# Introduction

BlockX Network is a Layer 1  Blockchain that offers multi-chain operability, an off-chain oracle infrastructure, and enables sovereign digital identity for the next-gen of Web3.

The BlockX ecosystem is built to utilize the Delegated Proof-of-Stake (DPoS) consensus algorithm which helps it to process and verify transactions instantly while helping dApps scale seamlessly.

Additionally, BlockX can be deployed by organizations in the traditional financial sector looking to transition to the blockchain. The list of these sectors includes - *banks, exchanges, trade finance, CBDC, stock, bond, loans, funds,* and *real estate*.

### Use Cases

BlockX makes it possible for dApp developers to deploy their smart contracts to the BlockX network as it is [EVM](https://ethereum.org/en/developers/docs/evm/)-compatible. This provides them with the benefits of a fast-finality on a Delegated-Proof-of-Stake ([DPoS](https://learn.bybit.com/blockchain/delegated-proof-of-stake-dpos/)) chain.

BlockX is set to become an ecosystem that incentivizes developers to build scalable and cost-efficient dApps using EVMs like ***Ethereum***, ***Matic***, ***Solana**, **Binance Smart Chain***, and more.&#x20;

It is an interoperable blockchain with an EVM set at the very core so that Smart Contracts can be deployed, as well as some of the existing dApps.

Bridges and Oracles will be used to connect the BlockX EVM to the outside community - this process and its surrounding entities make up our network called the Oxygen Network.&#x20;

All of the dApps created by the developers of the BlockX community will be connected with the Oxygen Network, which will encompass the BlockX Ecosystem.

### Features

BlockX works to produce one of the most compatible systems in Web3 today. Therefore, the following features are essential to be built in order to maximize usability across the many sub-sectors of blockchain:

* An infrastructure built with Metaverse adoption and scalability in mind
* Tokenization of traditional assets like stocks, bonds, using the Tokenizer digital banking product&#x20;
* Self-sovereign digital identity solutions&#x20;
* High rewards for Validators & Node Operators from transaction fees
* Off-chain data integration for mapping and data management with Oracles
* Horizontally scalable using [IBC](https://cosmos.network/ibc)
* Multi-chain token issuance and settlements

#### The above is possible because we:

* Adopt the [modules ](https://docs.cosmos.network/main/building-modules/intro.html)from [Cosmos SDK](https://docs.cosmos.network/).
* Incorporate JSON-RPC to be interoperable with other chains and products
* Utilize Tendermint Core's Application Blockchain Interface ([ABCI](https://docs.tendermint.com/master/spec/abci/))&#x20;
* Use [`geth`](https://github.com/ethereum/go-ethereum) for code maintenance&#x20;


# BlockX

BlockX is an [Ethereum Virtual Machine (EVM)](https://ethereum.org/en/developers/docs/evm/) chain that is also compatible with the Cosmos Ecosystem using Cosmos SDK. EVMs allow smart contracts to run, tokens to be transferred, and data to be stored. Some of the famous examples with EVMs used are *Ethereum, Binance Smart Chain*, and *Matic*. The genesis block was produced last January 16, 2024 12PM UTC time.

Using EVMs, blockchain projects can deploy new dApps like *decentralized exchanges, lending protocols, bridges* and many more.

The BlockX network has a very fast block time of 1 second, low gas fees, and network security that comes with the use of Tendermint’s protocol. BlockX will act as a hub between multiple chains that we will be launching in the BlockX Ecosystem.&#x20;

Other supporting systems can be bridges, IBCs, oracle systems, as well as other chains that have more specific use cases like data management and transaction storage. All of these will be connected via the Atlantis to allow users to experience a wide range of services across the BlockX Ecosystem.

*Inflation distribution of BCX:*

* 80% of tokens go to Validators
* 10% of tokens go to Smart Contract Developers
* 10% of tokens go to Community Pool

#### BlockX Testnet

In order for the users and developers to be able to freely test our chain, another chain is running in parallel with the BlockX chain and this is called BlockX Testnet or Atlantis.

###


# Tokens

The native EVM we've built using Cosmos SDK supports and powers BCX tokens, which enables efficient interoperability within the BlockX blockchain.&#x20;

### **BCX**

The BCX tokens power the BlockX ecosystem by enabling governance & voting operationg curated through the community pool, gas payments, and staking, on the Ethereum Virtual Machine.

BCX protects the Distributed Proof-of-Stake (DPoS) blockchain, and makes it possible Validators verify nodes and transactions, in addition to being the core of the ecosystem itself.&#x20;

BlockX tokens have high compatibility with ERC20 and other Ethereum standards for tokens supported by EVMs as well as Cosmos ecosystem.


# Transactions

### Using the Ethereum Chain

EOAs, or externally-owned accounts, initiate the underlying operations to create Ethereum transactions, not the smart contracts called internally. The whole network is broadcasted transformations of the EVM states by the Ethereum transaction.

Several types of Ethereum transactions:

* *Regular transactions*. Transactions coming from one account to another
* *Contract Deployment Transactions*. Transactions with contract code sent in the data field, and without a `to` address
* *Execution of a Contract*: transactions that interact with a deployed smart contract, where the `to` address is the smart contract address

The following transactions are supported by BlockX:

* [Dynamic Fee Transactions](https://eips.ethereum.org/EIPS/eip-1559)
* [Access List Transactions](https://eips.ethereum.org/EIPS/eip-2930)&#x20;
* [Legacy Transactions ](https://eips.ethereum.org/EIPS/eip-2718)

### Using Other chains

{% hint style="info" %}
Coming Soon
{% endhint %}


# Inflation

BCX inflation started at 10% per year. The new tokens will be distributed to Validators, Developers, and to the Community Pool.

* Validators will receive 80% of the new tokens
* Developers Pool will receive 10% of the new tokens
* Community Pool will receive 10% of the new tokens

Validators will be receiving the most rewards for maintaining the network, although Developers will also be incentivized for creating dApps on the Oracle Network, with BlockX rewarding them from the allocated BCX inflation distribution.&#x20;

The Community Pool will be allocated BCX tokens for the continued development and improvement of the chain through community proposals.


# Keys


# Keyring

The keyring holds the private/public key pairs used to interact with the node. For instance, a validator key needs to be set up before running the node, so that blocks can be correctly signed. The private key can be stored in different locations, called "backends", such as a file or the operating system's own key storage.

{% hint style="info" %}
You can run the command below when you have a running blockxd node to be able to create a key. Feel free to change the \<mykey> to whatever name you want and make sure to save the mnemonic that will be shown.\
blockxd keys add \<mykey> --keyring-backend file --algo eth\_secp256k1
{% endhint %}


# Multisig

A **multisig account** is an BlockX account with a special key that can require more than one signature to sign transactions. This can be useful for increasing the security of the account or for requiring the consent of multiple parties to make transactions. Multisig accounts can be created by specifying:

* threshold number of signatures required
* the public keys involved in signing

To sign with a multisig account, the transaction must be signed individually by the different keys specified for the account. Then, the signatures will be combined into a multisignature which can be used to sign the transaction. If fewer than the threshold number of signatures needed are present, the resultant multisignature is considered invalid.

The commands for setting up the BlockX private/public key pairs will be released soon.&#x20;

{% hint style="info" %}
The Multisig commands for setting up BlockX transaction signatures will be released soon.&#x20;
{% endhint %}


# Gas Fees

All gas fees will be paid in BCX, the governance token of the BlockX ecosystem. They will then be sent as rewards to the Validators for operating notes and keeping the blockchain running.

[Gas](https://eips.ethereum.org/EIPS/eip-1559) stands for the compute power required to run programs associated with a blockchain. Without gas, EVMs would have no way of knowing when to stop transaction loops from running forever and overloading a network, therefore the importance of participants’ operations is often rated by how much they are paying in fees.&#x20;

Smart contracts help set the parameters of a transaction which are agreed by the parties involved. No matter if you are using a multi-chain or single-chain network, gas works to ensure that excessive computational effort is not being used in conducting and finalizing transactions on-chain.

A small amount of gas is to be burned per each EVM transaction.

BlockX tracks and manages its ecosystem's gas the exact same way Ethereum does to ensure proper execution. Oxygen Network operations on the chain's store are represented as reads/writes.

Gas fees are calculated using the sum of all gas in a from the sum of all gas consumed in a message execution. So, the fee is equivalent to the gas multiplied by the gas price.

### `Gas`

`GasMeter` and `BlockGasMeter` are the primary interfaces for managing gas using the Cosmos SDK:&#x20;

* `GasMeter` tracks the gas consumed per executions during executions that lead to state transitions, and gets reset on every transaction execution.
* `BlockGasMeter` tracks the gas consumed per block, as well as prevents it from going over the limit pre-defined in the Tedermint consensus parameters.

Additional Cosmos SDK gas fee resources can be found in the Cosmos Gas [documentation](https://docs.cosmos.network/main/basics/gas-fees.html).


# Wallet and Accounts

BlockX Network allows you to connect to 2 ecosystems. An EVM ecosystem and a Cosmos ecosystem. EVM ecosystem allows you to use Metamask, Trust Wallet and others that you use to connect to DAPPs such as DEX, Bridge, NFT Marketplace or basically DAPPs that used Solidity Smart Contract to interact with. \
On the other hand, Cosmos ecosystems lets you be a validator of the network, stake your native token BCX and earn from it, vote for or against a proposal or even submit a proposal for the improvement of the chain. \
With these 2 ecosystems, you also have 2 types of addresses. The EVM-based address starts with 0x and the Cosmos-based address starts with the word blockx. Keep this in mind if you want to transfer and receive tokens. In the next pages, there are guides in how to connect using Metamask and Keplr wallets.


# Adding BlockX to Metamask

The [MetaMask ](https://metamask.io/)browser extension or mobile web allows us to access Ethereum-compatible applications. It can be used to connect to BlockX through the official testnet or through a BlockX node.&#x20;

Metamask also allows importing of different blockchains, making it a great solution for BlockX and similar ecosystems.&#x20;

*Below is an intuitive guide for adding the BlockX chain to Metamask:*

1. Open your MetaMask web extension (browsers - chrome, brave, Firefox, Opera)   or mobile web (iOS/Android), then click on the circle in the upper right corner to open settings.

![](/files/236xLU04LakueyA9qkIe)

&#x20; 2\. Click **Settings** at the bottom of the dropdown menu

![](/files/OVNVtDzkEQeYJ3sjZ9je)

&#x20; 3\. Select **Networks**

![](/files/MtlHi7DyTfDPUzmHWcjs)

&#x20; 4\. Enter the following details below:

**BlockX Mainnet**

Network Name: BlockX&#x20;

RPC URL: <https://web3.blockxnet.com>

Chain ID: 19191

Symbol: BCX

Explorer:  <https://explorer.blockxnet.com>

**BlockX Testnet (Atlantis)**

Network Name: BlockX Atlantis Testnet

RPC URL: <https://atlantis-web3.blockxnet.com>

Chain ID: 19077

Symbol: BCX

Explorer:  <https://testnet-explorer.blockxnet.com/>

&#x20; 5\. **Hit Save**

From here, you will have the same wallet as your Ethereum or other EVMs. No need for a separate app for you to access your funds.

### Automatic adding of BlockX to Metamask

Go to <https://ping.blockxnet.com> then select the chain to add

<figure><img src="/files/uHXAZhVbYPxJ69ZBYHH5" alt="" width="563"><figcaption></figcaption></figure>

To add BlockX, select BlockX then click on the Green Button to add BlockX to Metamask

<figure><img src="/files/46Z6ZggcB0grZO4ODNw5" alt="" width="563"><figcaption></figcaption></figure>

It will open up your Metamask to confirm the adding of BlockX Network, scroll to the bottom then click Approve. If it prompted you to switch the network to BlockX, you can also do so. \
![](/files/vHfdApu1r1QGY45hwLwg)

Make sure that the Chain ID and the Network URL is the same as above. It might also show a logo different than that of BCX later on but as long as you're connecting with the right RPC or Network URL and correct Chain ID of 100 you're in the right network. We'll work in adding the proper logo later on.

### Manual Import

Select **My Accounts** and click **Import Account**. You will then see the following:

![](/files/qfLq2Fr6PjXS5oeCb2MG)

Using your terminal, you can export your primary key using this command. Make sure that you replace `key` with your own key, and change the `keyring-backend flag to "file"`.

```
blockxd keys unsafe-export-eth-key mykey
```


# Adding BlockX to Keplr

Keplr is the wallet mostly being used in the Cosmos Ecosystem and it supports other Cosmos-based chains as well. It also allows you to have both a Cosmos-based address and an EVM address meaning it can act as your gateway from EVM to Cosmos-based services and vice versa. You're going to need Keplr wallet If you don't have Keplr wallet yet, you can download it from [here](https://www.keplr.app/download).

Currently there are 3 ways to easily add BlockX to your Keplr.&#x20;

1\) Open your browser where your Keplr wallet was installed then go to <https://chains.keplr.app/>

Search for BlockX then click Add to Keplr

<figure><img src="/files/KwiDtcV20FqpzEMIV6ai" alt=""><figcaption></figcaption></figure>

2\) Another way to add BlockX network to your Keplr web extension wallet, go to <https://ping.pub/wallet/keplr> on the Add BlockX

<figure><img src="/files/PXBEmc45ghZ3BkyFXdaE" alt="" width="563"><figcaption></figcaption></figure>

If the chain doesn't say BlockX, click on the dropdown on the left then choose BlockX from the list.&#x20;

<figure><img src="/files/5VzGOOiYOHjxgi7pYyK9" alt="" width="563"><figcaption></figcaption></figure>

Once added, it will open your Keplr window to ask for your approval. Just click Approve.

<figure><img src="/files/DevHYZ1qFtAkIol89xwA" alt="" width="353"><figcaption></figcaption></figure>

After you click on the Approve button, you will then see the BlockX network at the bottom of your wallet<br>

<figure><img src="/files/2mKPaCAmdwAjQ33JKod3" alt="" width="355"><figcaption></figcaption></figure>

{% hint style="info" %}
*Note: If BCX doesn't show up in your available balance, open your Keplr wallet then click the menu icon in your Keplr wallet. Click Manage Chain Visibility then make sure that BlockX is checked.*\
![](/files/WViGGiEBl6IB6KGqUchD)![](/files/z8xn6NfwOUT5k0fMNBaR)
{% endhint %}

3\) The previous steps are for Keplr Web browser extension wallet. You can use it on your mobile though by downloading Keplr from either Google Play Store or Apple App Store.

Open you Keplr Mobile Wallet then click on the Menu icon in the upper left corner

<figure><img src="/files/8IX1qfSE6I5STIUqha0Z" alt="" width="375"><figcaption></figcaption></figure>

At the bottom of the Menu, click Add More Chains

<figure><img src="/files/zr8Gm8qJakv4MiDoFzkY" alt="" width="175"><figcaption></figcaption></figure>

Search for Blockx then click Add to Keplr button

<figure><img src="/files/EujjwCDgoyJhcsZelBt8" alt="" width="344"><figcaption></figcaption></figure>

Click on the Menu icon again that you clicked earlier on the upper left corner of your Keplr wallet then click on Manage Chain  Visibility

<figure><img src="/files/HY5RcXknv7TTpnBI9Hmq" alt="" width="178"><figcaption></figcaption></figure>

You should be able to see BlockX on the list of chains, make sure that it is checked then feel free to check/uncheck other chains then hit Save button.

<figure><img src="/files/0RaCCgmpaXoCyVBHndqF" alt="" width="375"><figcaption></figcaption></figure>

You should now be able to see BlockX at the bottom section of your Mobile Keplr wallet

<figure><img src="/files/hzfb447RuTNXhJT02ZVY" alt="" width="323"><figcaption></figcaption></figure>

To see your receiving addresses, click on the Deposit button then this below will pop-up. You have 2 addresses, one for the Cosmos ecosystem and the other is for EVM systems like Metamask. You can copy them by clicking on the Copy symbol. Deposits to either addresses will reflect to your account.

<figure><img src="/files/3qjCLLNBXQXS4HG9YoPq" alt="" width="375"><figcaption></figcaption></figure>


# Transfers Between Wallets

### Transfer using Metamask

Transferring BCX to other wallets estimated cost automatically set by Metamask is roughly around 0.000032 BCX with Medium priority.

![](/files/wvOYhrJkiZ448Wjp6kJM)

Setting Metamask to High priority sending will increase the cost to 0.000042 BCX. Though you can also manually change the gas price by clicking the Advanced Options if needed.

![](/files/KZHEq7PF4tKpTLiApx0U)

### Transfer between Metamask and Keplr

Keplr Wallet allows you to have 2 types of address, one that starts with blockx and the other starts with 0x. In order to transfer from Metamask to Keplr, you'll have to use the 0x address. Click on the Copy Address at the upper section of your Keplr wallet then copy the right destination address. BCX tokens transferred to either of the address will reflect on your account accumulatively.

<figure><img src="/files/8oF68u2TskgFnhSqryym" alt="" width="530"><figcaption></figcaption></figure>

This basically means that if you want to transfer tokens from your Metamask or other EVM wallets like Trust Wallet going to your Keplr Wallet, just paste the EVM Address in your Keplr account and paste it as a recipient in your EVM wallet such as Metamask.


# Backup

### Mnemonics <a href="#mnemonics" id="mnemonics"></a>

When you create a new key, you'll receive a mnemonic phrase that can be used to restore that key. Backup the mnemonic phrase:

```bash
blockxd keys add mykey
{
  "name": "mykey",
  "type": "local",
  "address": "blockx1n253dl2tgyhxjm592p580c38r4dn8023ctv28d",
  "pubkey": '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"ArJhve4v5HkLm+F7ViASU/rAGx7YrwU4+XKV2MNJt+Cq"}',
  "mnemonic": ""
}

**Important** write this mnemonic phrase in a safe place.
It is the only way to recover your account if you ever forget your password.

# <24 word mnemonic phrase>
```

To restore the key:

```bash
$ blockxd keys add mykey-restored --recover
> Enter your bip39 mnemonic
banner genuine height east ghost oak toward reflect asset marble else explain foster car nest make van divide twice culture announce shuffle net peanut
{
  "name": "mykey-restored",
  "type": "local",
  "address": "blockx1n253dl2tgyhxjm592p580c38r4dn8023ctv28d",
  "pubkey": '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"ArJhve4v5HkLm+F7ViASU/rAGx7YrwU4+XKV2MNJt+Cq"}'
}
```

### Export Key <a href="#export-key" id="export-key"></a>

#### Tendermint-Formatted Private Keys <a href="#tendermint-formatted-private-keys" id="tendermint-formatted-private-keys"></a>

To backup this type of key without the mnemonic phrase, do the following:

```bash
blockxd keys export mykey
Enter passphrase to decrypt your key:
Enter passphrase to encrypt the exported key:
-----BEGIN TENDERMINT PRIVATE KEY-----
kdf: bcrypt
salt: 14559BB13D881A86E0F4D3872B8B2C82
type: secp256k1

# <Tendermint private key>
-----END TENDERMINT PRIVATE KEY-----

$ echo "\
-----BEGIN TENDERMINT PRIVATE KEY-----
kdf: bcrypt
salt: 14559BB13D881A86E0F4D3872B8B2C82
type: secp256k1

# <Tendermint private key>
-----END TENDERMINT PRIVATE KEY-----" > mykey.export
```

#### Ethereum-Formatted Private Keys (MetaMask-compatible) <a href="#ethereum-formatted-private-keys" id="ethereum-formatted-private-keys"></a>

To backup this type of key without the mnemonic phrase, do the following:

```bash
blockxd keys unsafe-export-eth-key mykey > mykey.export
**WARNING** this is an unsafe way to export your unencrypted private key, are you sure? [y/N]: y
Enter keyring passphrase:
```

### Import Key <a href="#import-key" id="import-key"></a>

#### Tendermint-Formatted Private Keys <a href="#tendermint-formatted-private-keys-2" id="tendermint-formatted-private-keys-2"></a>

```bash
$ blockxd keys import mykey-imported ./mykey.export
Enter passphrase to decrypt your key:
```

#### Ethereum-Formatted Private Keys <a href="#ethereum-formatted-private-keys-2" id="ethereum-formatted-private-keys-2"></a>

```bash
$ blockxd keys unsafe-import-eth-key mykey-imported ./mykey.export
Enter passphrase to encrypt your key:
```

#### Verification <a href="#verification" id="verification"></a>

Verify that your key has been restored using the following command:

```bash
$ blockxd keys list
[
  {
    "name": "mykey-imported",
    "type": "local",
    "address": "blockx1n253dl2tgyhxjm592p580c38r4dn8023ctv28d",
    "pubkey": '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"ArJhve4v5HkLm+F7ViASU/rAGx7YrwU4+XKV2MNJt+Cq"}'
  },
  {
    "name": "mykey-restored",
    "type": "local",
    "address": "blockx1n253dl2tgyhxjm592p580c38r4dn8023ctv28d",
    "pubkey": '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"ArJhve4v5HkLm+F7ViASU/rAGx7YrwU4+XKV2MNJt+Cq"}'
  },
  {
    "name": "mykey",
    "type": "local",
    "address": "blockx1n253dl2tgyhxjm592p580c38r4dn8023ctv28d",
    "pubkey": '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"ArJhve4v5HkLm+F7ViASU/rAGx7YrwU4+XKV2MNJt+Cq"}'
  }
]
```


# Deploying Smart Contracts

Learn how to deploy smart contracts using some of the most popular blockchain development tool suites - Remix and Hardhat


# Remix

Remix IDE allows developers to deploy their smart contracts using MetaMask, which is universally convenient. This platform doesn't require a setup, and comes with a series of plugins that offer simple GUIs.  &#x20;

Remix is supported by *Firefox, Chrome, Brave, and other Chromium-based browsers*. The platform is also available as a [Desktop IDE](https://github.com/ethereum/remix-desktop/releases) and a [VScode extension](https://github.com/ethereum/remix-vscode#ethereum-remix-project-extension-for-visual-studio-code). &#x20;

This guide assumes that the reader has at least some familiarity with the Solidity programming language for smart contracts, and general dApp development on the Ethereum network.&#x20;

The following steps will guide you to effective smart contract deployment on Remix.

**1.** Go to <https://remix.ethereum.org/>. Make sure that you have the **Atlantis Network** added to your Metamask and a few BCX tokens are in your wallet to be used as Gas for creating a smart contract.&#x20;

If you need some BCX tokens for the testnet, go to <https://faucet.blockxnet.com>, then enter your Metamask address.

<figure><img src="/files/dhuyZZW3jz39BMfZ2TA8" alt=""><figcaption><p>remix.ethereum.org</p></figcaption></figure>

Below is the default interface of Remix:

<figure><img src="/files/ItuUITjtp4ZJXCP5n2Vk" alt=""><figcaption></figcaption></figure>

Let’s try to create a new file. We’ll create a new token within the Atlantis Network using just a few lines of Solidity code commonly available across the internet:

```solidity
pragma solidity ^0.8.2;
 
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
 
contract MyToken is ERC20, ERC20Burnable, Ownable {
   
    constructor() ERC20("My Token", "Myt") {
        _mint(msg.sender, 1000000 * 10 ** 18);
    }
 
    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
}
```

**2.** Create a new file:

<figure><img src="/files/lXRj8otWxH4do8SIPa3Y" alt=""><figcaption></figcaption></figure>

Then enter a filename. For this example, we've named it **MyToken.sol.**

<figure><img src="/files/yd0x3xXtY82O7FBZJy2Q" alt=""><figcaption></figcaption></figure>

**3.** Paste the Solidity code shown below to the newly created file. Then **Save.**

```solidity
pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyToken is ERC20, ERC20Burnable, Ownable {
    
    constructor() ERC20("MyToken", "Myt") {
        _mint(msg.sender, 1000000 * 10 ** 18);
    }
    
    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
}
```

<figure><img src="/files/6diq1m1MUHA4WzgaXekE" alt=""><figcaption></figcaption></figure>

**4.** Upon saving, you will see more files being added to your workspace. They are our new dependencies since we imported the OpenZeppelin libraries.

<figure><img src="/files/ja20PWgutN4uy7pfzZme" alt=""><figcaption></figcaption></figure>

**5.** Look for the **Compile** icon on the left navigation panel of Remix - the 3rd icon. Then click on the Compile button.

<figure><img src="/files/lvhdq7VUaHrFXHx332bi" alt=""><figcaption></figcaption></figure>

**6.** Once you have successfully compiled the file, Remix will show you the Compile icon with a checkmark added to it. There’ll be no checkmark if an error had occurred during compilation and you’ll see error message(s) as well.&#x20;

You will now be able to copy the **ABI** of the contract which is commonly used in Web3 when it comes to tampering with the contract.

<figure><img src="/files/yEgBAqJcQ3dfBa7LoUD5" alt=""><figcaption></figcaption></figure>

**7.** To Deploy, click the **Deploy** button on the left which is the 4th icon in Remix. For the Environment, select **Injected Provider** - Metamask to use your Metamask wallet in deploying the contract. Make sure that the Atlantis Network is selected and the chosen wallet has BCX in it for gas fee coverage.&#x20;

One of the ways to verify if you’ve got the right wallet is checking if the address is correct, as well as the balance right beside it (displayed in **ether**).

<figure><img src="/files/f7PlYRSRLX3Py8mMBv3r" alt=""><figcaption></figcaption></figure>

**8.** Once you click **Deploy**, it will open up a MetaMask window where you’ll see the gas fee needed for deploying the contract. Click **Confirm** for the contract to be deployed.

<figure><img src="/files/sPXDKof2PwOOgNpOyVDK" alt=""><figcaption></figcaption></figure>

**9.** To find out the outcome of the deployment, check the lower section of Remix, which should show you something like this:

<figure><img src="/files/c7cgTxphTpRFcJFfudXQ" alt=""><figcaption></figcaption></figure>

On the **left side**, there is the **Deployed Contracts** section, which, if you click on the arrow on the left side of the MyToken contract, should open more options for interacting with the contract.&#x20;

The **Copy** icon allows you to copy the contract address of the deployed contract to add it to your Metamask since it is a token.&#x20;

On the **right side**, you’ll see more info if you click on the right arrow. It should show you transaction info.&#x20;

<figure><img src="/files/GjntXiGVRQe0IDqAr6GK" alt=""><figcaption></figcaption></figure>

**10.** Once you have copied the Contract Address, you can then add it to your Metamask. Once the Metamask window opens, you’ll notice that there is a small amount of BCX tokens deducted from your balance. Click on the **Assets** tab, then click **Import tokens**.

<figure><img src="/files/SLZlGXHeBHxQ6RUODhxd" alt=""><figcaption></figcaption></figure>

**11.** Paste the **contract address** that you copied from Remix. If the contract address that you copied is correct, MetaMask will automatically show your token symbol.&#x20;

Click **Add Custom Token.** It will show you a confirmation page before being able to add the token. It will also show you your token balance.

<figure><img src="/files/4GaAbCc0E9Jhn6sa7knQ" alt=""><figcaption></figcaption></figure>

**12.** A confirmation page will appear before you can add the token. Click **Import Tokens.**

<figure><img src="/files/jxUR3eUTda0Y80bXFmTk" alt=""><figcaption></figcaption></figure>

**13.** You should then be able to see your token on MetaMask where you can send tokens to other Atlantis Network users, just like you send tokens on **Ethereum** or **Binance Smart Chain**.

**14.** If you want to see further info on your contract, you can go to [**https://explorer.blockxnet.com**](https://explorer.blockxnet.com) and enter either the contract address or the transaction hash. Both are available in the Remix lower section after you deploy the contract.

<figure><img src="/files/7SG5RnpgCQOJXoWR7plA" alt=""><figcaption></figcaption></figure>

Click on the token name that you deployed to see more info about the token.

<figure><img src="/files/FYVx8MOwtojYTwwXd62F" alt=""><figcaption></figcaption></figure>

**15.** If you clicked on the token name of your token, it should have taken you to the token page where you can see the **Token Holders**, **Total Supply**, **Number of Holders** and **Number of Transfers.**

<figure><img src="/files/33lMjrGOm5AEHn7uq6ex" alt=""><figcaption></figcaption></figure>

**Congratulations**, you have successfully deployed a smart contract on the Atlantis Testnet using Remix, and are now able to see transaction details on a block explorer!


# Hardhat

[Hardhat](https://hardhat.org) is another essential tool that should be found in every dApp developer's arsenal. Hardhat allows seamless deployment of smart contracts, running of tests, and debugging outside of live environments.&#x20;

One of the biggest advantages of Hardhat is its flexibility - there is a series of plugins available for different types of developers, and Hardhat's extensible ecosystem allows for efficient tooling.&#x20;

This guide assumes that the reader has at least some familiarity with the Solidity programming language for smart contracts, and general dApp development on the Ethereum network.&#x20;

*The following is a short guide for deploying a smart contract using Hardhat. The best solution is to use a development environment like VSCode for an optimal deployment experience.*

**1.** First of all, make sure you have HardHat set up on your local machine. Check out this guide if you encounter problems: <https://hardhat.org/hardhat-runner/docs/guides/project-setup>

**2.** There are 3 files that you will have to edit. First, create a Solidity file under the contracts folder. You can right click on the folder and create a new file. For this example, we named it ***HHToken.sol***

<figure><img src="/files/QyhLAZbkWMRaFk8nTYSo" alt=""><figcaption></figcaption></figure>

**3.** Paste this piece of simple contract code in your ***HHToken.sol*** equivalent file:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";\

contract HHToken is ERC20, ERC20Burnable, Ownable {
    
    constructor() ERC20("HHToken", "HHT") {
        _mint(msg.sender, 1000 * 10 ** 18);
    }
    
    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
}
```

**4.** Once you’re done, go to the scripts folder, then look for ***deploy.js***. As part of the setting up Hardhat, there are already some lines in the that file. You will just have to edit some variables like the ones below:&#x20;

```javascript
const hre = require("hardhat");

async function main() {

    const Token = await hre.ethers.getContractFactory("HHToken");
    const token = await Token.deploy();
    await token.deployed();

    console.log("Token deployed to:", token.address);
}

main()
  .then(() => process.exit(0));
  .catch((error) => {
    console.error(error);
    process.exit(1);
});
```

{% hint style="info" %}
Make sure that for *getContractFactory* you enter the contract name of your token.
{% endhint %}

**5.** Once you have entered your contract name, go to the main folder and look for the file named ***hardhat.config.js***. Enter the BlockX Network details:

* **RPC**: <https://web3.blockxnet.com&#x20>;
* **Chain ID**: 100&#x20;

```javascript
module.exports = {
  defaultNetwork: "Mainnet",
  networks: {
    blockx: {
      url: "https://web3.blockxnet.com",
      chainId: 100,
      gasPrice: 2000000000,
      accounts: [privKey]
    },
```

It would be advisable to try deploying using Atlantis network first as it is the Testnet.&#x20;

\
RPC URL: <https://atlantis-web3.blockxnet.com>

Chain ID: 50

For the accounts, we stored our private key to a variable and named it *privKey*. You can also put your private key there. This private key should belong to the account of the one who deploys the contract, so make sure it has some BCX tokens.&#x20;

**6.** Open the **Terminal i**n your VSCode so you can enter a deployment command like the following:&#x20;

```bash
npx hardhat run --network blockx scripts/deploy.js 
```

&#x20;We named the network `blockx` in the ***hardhat.config.js*** file, which is why we used `blockx` after the `–-network` flag.&#x20;

**7.** You should now see an output like this:

<figure><img src="/files/FZYyOXLjAw3zYB1cDreY" alt=""><figcaption></figcaption></figure>

That’s it, you’ve successfully deployed your token using Hardhat on the BlockX Network! You can use [**https://explorer.blockxnet.com**](https://explorer.blockxnet.com) if you want to see more information on your newly deployed contract.


# BlockX White Paper

The cross-chain protocol for Metaverse, DeFi, & NFTs

## Abstract

This white paper introduces and overview of the BlockX Network, a multi-chain payments layer-1 blockchain for Metaverse, DeFi, and NFTs.   It outlines all the information concerning the business model of the project, marketing plans, products, services, and further details about the BlockX ecosystem.

## Introduction

BlockX is an Ethereum alternative blockchain built for a new generation of dApps for the Metaverse, DeFi and NFTs. BlockX is built on the delegated proof-of-stake (DPoS) consensus, and enables instant transactions for transfers and applications.   The key features of the BlockX chain include:

* *Multi-chain Issuance and Settlements*
* *Digital Identity On-chain  (SSI and Centralized)*&#x20;
* *Offchain Data Link Oracles*

## Cross-Chain

BlockX allows for issuance and settlement of assets on multiple chains. This enables:

* Building of dApps that may require assets from multiple chains&#x20;
* Any project built on another chain can be readily and easily ported to BlockX for execution and settlements

#### **A Network of Networks**

We aim to become the network of networks, and the primary hub of the blockchain world where multiple chains can operate.

## Digital Identity -  Social Logins for Web 3.0

BlockX on-chain ID is a portable identification system that can used in multiple dApps throughout the ecosystem.

IDs can be:

* *Centralized*
* *Self Sovereign Identity-based (SSI)*&#x20;

A user can verify their KYC/AML and accreditation status at once, then start using multiple dApps securely on the blockchain.

## Off-Chain Data

Quite a number of dApps today require off-chain data to operate. BlockX integrates high-performance oracles natively, for a real-time data link between APIs. Some of this data can be related to:

* Identity of Assets and Individuals
* Compliance
* Financial Markets data
* Maps&#x20;

## Key Solutions & Industries

Some of the key industries BlockX is focusing on are:

* Metaverse
* DeFi&#x20;
* NFTs&#x20;
* Asset Tokenization

Additionally, this blockchain infrastructure can be used in the following sectors to transition them to the blockchain era via BlockX:

* Banks
* Exchanges
* Traditional Finance
* CBDC
* Stocks
* Bonds
* Loans
* Funds
* Real Estate
* Games
* NFT Marketplaces

## Metaverse & NFTs

Traditional banks and other centralized institutions cannot keep up with the development of the Metaverse & Web 3.0. Currently, the average person spends 10 hours per day looking at a screen.&#x20;

This behavior automatically onboards the user to the Metaverse. We need to realize this at scale, and build specifically for this upcoming reality, focusing on:

* Identity of individuals&#x20;
* Security of digital assets
* Transactions on the Metaverse

***BlockX opens doors to a viable Metaverse with an ecosystem  of digital assets, including NFTs and crypto tokens.***

## DeFi & Tokenization

BlockX aims to completely transform the global investment industry and eradicate a series of key pain points. This will democratize investments and spur an increase in direct market participation and expansion.

Such expansion of capital markets will help finance the future ventures and endeavors of entrepreneurs, accelerating the overall progress of human civilization.

## What is Tokenization?

Asset tokenization is the process of converting ownership rights of a tangible or intangible asset into a digital token on a blockchain.&#x20;

This can be compared to the traditional securitization process, but with a modern twist. Asset-backed tokens (ABTs) are created via a form of Initial Coin Offering (ICO), commonly known as a Security Token Offering (STO) to distinguish them from other tokens.

An STO is used to create a digital representation of an asset, implying that a security token could represent company shares, ownership of a property, or participation in an investment fund. ABTs can be traded on a secondary market, like the Tokenizer DEX.

You can tokenize real estate, stocks, bonds, domains, venture capital, metals & commodities, intellectual property, FX & derivatives, identity, luxury goods, funds, art, private equity, corporate debt, and others.

Tokenization can create a more effective and fair financial world by significantly minimizing the friction involved in the fundraising, investing, and trading of securities.&#x20;

It will make the financial industry more accessible, cheaper, faster, and efficient, unlocking trillions of dollars in currently illiquid assets, and significantly increasing trading volume.

***Tokenization can create a more effective and fair financial world by significantly minimizing the friction involved in the fundraising, investing, and trading of securities.***

## Tokenomics

#### **BlockX Token (BCX)**

BCX is the native currency that fuels all the activities in the BlockX ecosystem. Initially, 600 million BCX tokens will be created on multiple chains. These tokens will then be swappable for BCX Mainnet tokens after the BlockX Mainnet is launched.

#### **BCX Token Supply Allocation**

<figure><img src="/files/UFVclCAxhb5PA7jCpQeL" alt=""><figcaption></figcaption></figure>

## BCX Token Use & Info

**Gas Fees:** All gas fees on the BlockX chain will paid using only the BCX token

**Staking rewards:** BlockX token can be staked for up to 20% APY

**Application fees:** Different partners and affiliated tokens can make BCX their main mode of payment

**Validators & node operators:** Validators & node operators are recommended to have a minimum number of BCX tokens to join respective programs

**Contract address on BSC:** <https://bscscan.com/> token/0x8d11b81a3d4bea2dc1e240241141e32 7b6922d6b

**Inflation:** 20% per annum

## Use of funds

#### **Development**

*30%* of funds will be used to build the BlockX platform, including recruitment, training, and maintenance of the overall infrastructure.

#### **Business Development**

*50%* will be used for marketing and business development to construct the marketplace and educate the Tokenizer ecosystem partners, including but not limited to:

* Investors of various types, from individuals to financial institutions
* Projects and assets to get BlockX on other platforms
* Ecosystem partners such as brokers, custodians, exchanges, and other tokenization platforms and chains, traditional banking and investment institutions, financial product distributors and advisors, and local licensing authorities
* Branding, marketing, and advertising companies to build the Tokenizer brand globally

#### **Reserve**

20% will be kept in reserve to cope with any emergencies or unexpected situations that might come up.

<figure><img src="/files/lAdhjRh19xlW10uske3X" alt=""><figcaption></figcaption></figure>

## Validators

Validators are nodes responsible for keeping the blockchain running. They create new blocks and confirm all the transactions within the chain.

#### **Earnings**

The BlockX ecosystem uses DPoS consensus. Considering that the ecosystem has a global inflation rate of 20%, Validator operators earn an additional 20% BCX per annum, on top of the gas fees paid by the smart contracts users.

#### **Key Points**

It is recommended that Validators have as many tokens as possible in their node to ensure there’s potential for earnings and cost coverage. Validators are to set a service fee that they will charge delegators.

#### **Becoming a Validator**

Once approved, validator operators can use a Command Line Interface (CLI) when running a node, and in the future, a Graphical User Interface (GUI) on a web browser that connects to nodes. Service fees can also be configured using these tools.

## Delegators

Delegators are users who delegate their BCX to validators for a fee to earn or stake additional BCX

#### **Earnings**

Delegators earn additional BCX based on the inflation rate of 20%, minus a small fee that Validators charge for using their nodes.

#### **Requirements**

Delegators must choose a validator their tokens will be delegated to using validator IDs. Delegators must also set a duration for which their BCX will be locked.&#x20;

This will be a minimum of 1 week and a maximum of 10 years. validators can have their own set of fees for these durations. The minimum amount that can be delegated is 1000 BCX.

#### **Staking**

One may use either a standard Command Line Interface, or in the future, a Graphical User Interface on the web that connects to digital wallets.&#x20;

There, BCX can be delegated to a validator of a user’s choice, and the required data can be filled up. potential earnings can also be found on one of these interfaces.

## Summary

Metaverse, DeFi, and NFTs will define the next wave of development in blockchain, and technology as a whole.

BlockX is well-positioned to play a leading role in the development of this critical blockchain infrastructure that forms the bedrock of many future technologies.

<figure><img src="/files/OWuccW2iwiVnUAh0t9Ya" alt=""><figcaption></figcaption></figure>

### Disclaimer:

*The information set forth above may not be exhaustive and does not imply any contractual relationship elements. Its sole purpose is to provide relevant and reasonable information to potential token holders to determine whether to undertake a thorough analysis of the project with the intent of purchasing BCX tokens.*

*Nothing in this white paper shall be deemed to constitute a prospectus of any sort or a solicitation for investment, nor does it in any way pertain to a solicitation of an offer to buy any securities in any jurisdiction.*

*This document is not composed per and is not subject to laws or regulations of any jurisdiction designed to protect investors.*

*BCX is a utility token. This product is not a digital currency, security, commodity, or any other financial instrument. It has not been registered under the Securities Act, the securities laws of any state of the United States, or the securities laws of any other country, including the securities laws of any jurisdiction in which a potential Tokenizer Token holder is a resident.*

*The BCX token confers no other rights in any form, including but not limited to any ownership, distribution (including but not limited to profit), redemption, liquidation, proprietary (types of intellectual property), or other financial or legal rights, other than those specifically described in the white paper.*

*All statements contained in this white paper, statements made in press releases or in any place accessible by the public and oral statements that may be made by BlockX or their respective directors, executive employees or team's representatives acting on behalf of BlockX (as the case may be), that are neither statements of historical fact nor do they constitute "forward-looking statements"*


# The BCX Token

BCX is the native token of BlockX used for governance, staking, and gas fee payments that has an initial supply of 698 million.

BCX will be used for all the features within BlockX that include:

* Voting
* Gas fees for creating smart contracts
* Gas fees for transferring assets from and to the EVM
* Gas fees for transacting with the smart contracts created inside the EVM
* Inflation rewards to Validators and Delegators
* Acting as an incentive for developers who will be creating dApps on the Atlantis Network.

![](/files/i5rrcIDgSfTFvAj3Jzrg)


# Governance

### On and off-chain Governance Structure

#### Communication Methods <a href="#communication-methods" id="communication-methods"></a>

Governance practices and decisions are communicated through different types of documents and design artifacts:

* On-chain governance proposals&#x20;
* Architecture Decision records
* Technical standards / specifications

#### Decision-making and Discussion Venues <a href="#decision-making-and-discussion-venues" id="decision-making-and-discussion-venues"></a>

Venues involve community members to different degrees and individuals often perform multiple roles in the Cosmos ecosystem. Because technical direction setting and development is almost always happening in the open, involvement from members in the extended community occurs organically.

The Community Pool of BlockX will work based on users’ proposals that will be gathered from BlockX communities on Discord, Telegram, and others.&#x20;

### Community Pool Structure

Soon we'll be sharing more information on community proposals and our voting systems, but the primary aim of BlockX remains a fully operational and properly configured network that allows Validators & Delegators to start participating.&#x20;

However, here are some community proposal aspects to note:

* 10% of tokens that come from block rewards will be sent consistently to the Community Pool
* A Community-spend proposal must be submitted then approved by the community in order for funds to be transferred to an address.

For now, the best way to get involved and start looking forward to the Community Pool launch is to join BlockX’s [Discord](https://discord.gg/b4GZURPMYw), [Telegram](https://t.me/blockxnetwork), [Twitter](https://twitter.com/BlockXnet), and other communities listed on our [website](http://blockxnet.com).&#x20;


# Proposals

### Deposit Period <a href="#deposit-period" id="deposit-period"></a>

The deposit period lasts either 2 days or until the proposal deposit totals 10,000,000 abcx, whichever happens first.

#### Deposits <a href="#deposits" id="deposits"></a>

Deposit amounts are at risk of being burned. Prior to a governance proposal entering the voting period (ie. for the proposal to be voted upon), there must be at least a minimum number of abcx deposited (10,000,000 abcx). Anyone may contribute to this deposit. Deposits of passed and failed proposals are returned to the contributors.

In the past, different people have considered contributions amounts differently. There is some consensus that this should be a personal choice. There is also some consensus that this can be an opportunity for supporters to signal their support by adding to the deposit amount, so a proposer may choose to leave contribution room (ie. a deposit below 10,000,000 abcx) so that others may participate. It is important to remember that any contributed BCX are at risk of being burned.

#### Burned deposits <a href="#burned-deposits" id="burned-deposits"></a>

Deposits are burned when proposals:

1. **Expire** - deposits will be burned if the deposit period ends before reaching the minimum deposit (10,000,000 abcx)
2. **Fail to reach quorum** - deposits will be burned for proposals that do not reach quorum ie. 33.4% of all staked BCX must vote
3. **Are vetoed** - deposits for proposals with 33.4% of voting power backing the `NoWithVeto` option are also burned

### Voting Period <a href="#voting-period" id="voting-period"></a>

The voting period is currently a fixed 14-day period but can be changed thru governance. During the voting period, participants may select a vote of either `Yes`, `No`, `Abstain`, or `NoWithVeto`. Voters may change their vote at any time before the voting period ends.

### What do the voting options mean? <a href="#what-do-the-voting-options-mean" id="what-do-the-voting-options-mean"></a>

1. **`Abstain`**: indicates that the voter is impartial to the outcome of the proposal.
2. **`Yes`**: indicates approval of the proposal in its current form.
3. **`No`**: indicates disapproval of the proposal in its current form.
4. **`NoWithVeto`**: indicates stronger opposition to the proposal than simply voting `No`. If the number of `NoWithVeto` votes is greater than a third of total votes excluding `Abstain` votes, the proposal is rejected and the deposits are burned.

As accepted by the community in Proposal 6, voters are expected to vote `NoWithVeto` if a proposal leads to undesirable outcomes for the community. It states “if a proposal seems to be spam or is deemed to have caused a negative externality to Cosmos community, voters should vote `NoWithVeto`.”

Voting `NoWithVeto` provides a mechanism for a minority group representing a *third* of the participating voting power to reject a proposal that would otherwise pass. This makes explicit an aspect of the consensus protocol: it works as long as only up to [a third of nodes fail](https://docs.tendermint.com/v0.35/introduction/what-is-tendermint.html).&#x20;

In other words, greater than a third of validators are always in a position to cause a proposal to fail outside the formalized governance process and the network's norms, such as by censoring transactions. The purpose of internalizing this aspect of the consensus protocol into the governance process is to discourage validators from relying on collusion and censorship tactics to influence voting outcomes.

### What determines whether or not a governance proposal passes? <a href="#what-determines-whether-or-not-a-governance-proposal-passes" id="what-determines-whether-or-not-a-governance-proposal-passes"></a>

There are four criteria:

1. A minimum deposit of 10,000,000 abcx is required for the proposal to enter the voting period
   * anyone may contribute to this deposit
   * the deposit must be reached within 2 days (this is the deposit period)
2. A minimum of 33.4% of the network's voting power (quorum) is required to participate to make the proposal valid
3. A simple majority (greater than 50%) of the participating voting power must back the `Yes` vote during the 2-day voting period
4. Less than 33.4% of participating voting power votes `NoWithVeto`

Currently, the criteria for submitting and passing/failing all proposal types is the same.

#### How is voting tallied? <a href="#how-is-voting-tallied" id="how-is-voting-tallied"></a>

Voting power is determined by stake weight at the end of the 2-day voting period and is proportional to the number of total BCX participating in the vote. Only bonded BCX count towards the voting power for a governance proposal. Liquid BCX will not count toward a vote or quorum.

Inactive validators can cast a vote, but their voting power (including the backing of their delegators) will not count toward the vote if they are not in the active set when the voting period ends. That means that if I delegate to a validator that is either jailed, tombstoned, or ranked lower than 150 in stake-backing at the time that the voting period ends, my stake-weight will not count in the vote.

Though a simple majority `Yes` vote (ie. 50% of participating voting power) is required for a governance proposal vote to pass, a `NoWithVeto` vote of 33.4% of participating voting power or greater can override this outcome and cause the proposal to fail. This enables a minority group representing greater than 1/3 of voting power to fail a proposal that would otherwise pass.

#### How is quorum determined? <a href="#how-is-quorum-determined" id="how-is-quorum-determined"></a>

Voting power, whether backing a vote of `Yes`, `Abstain`, `No`, or `NoWithVeto`, counts toward quorum. Quorum is required for the outcome of a governance proposal vote to be considered valid and for deposit contributors to recover their deposit amounts. If the proposal vote does not reach quorum (ie. less than 33.4% of the network's voting power is participating) within 5 days, any deposit amounts will be burned and the proposal outcome will not be considered to be valid.


# Proposal Tips

### General Advice: Community Outreach <a href="#general-advice-community-outreach" id="general-advice-community-outreach"></a>

Engagement is likely to be critical to the success of a proposal. The degree to which you engage with BlockX community should be relative to the potential impact that your proposal may have on the stakeholders. This guide does not cover all ways of engaging: you could bring your idea to a podcast or a hackathon, host an AMA on Reddit or host a Q\&A (questions & answers). We encourage you to experiment and use your strengths to introduce proposal ideas and gather feedback.

There are many different ways to engage. One strategy involves a few stages of engagement before and after submitting a proposal on chain. **Why do it in stages?** It's a more conservative approach to save resources. The idea is to check in with key stakeholders at each stage before investing more resources into developing your proposal.

In the first stage of this strategy, you should engage people (ideally experts) informally about your idea. You'll want to start with the minimal, critical components (name, value to cosmos hub, timeline, any funding needs) and check:

* Does it make sense?
* Are there critical flaws?
* Does it need to be reconsidered?

You should be able engaging with key stakeholders (eg. a large validator operator) with a few short sentences to measure their support. Here's an example:

> "We are considering a proposal for funding to work on (project). We think it will help BlockX to (outcome). Timeline is (x), and we're asking for (y) amount. Do you think that this is a proposal that (large validator) may support?"

**Why a large validator?** They tend to be the de facto decision-makers on BlockX, since their delegators also delegate their voting power. If you can establish a base layer of off-chain support, you can be more confident that it's worth proceeding to the next stage.

**Note:** many will likely hesitate to commit support, and that's okay. It will be important to reassure these stakeholders that this isn't a binding a commitment. You're just canvassing the community to get a feel for whether it's worthwhile to proceed. It's also an opportunity to connect with new people and to answer their questions about what it is you're working on. It will be important for them to clearly understand why you think what you're proposing will be valuable to BlockX, and if possible, why it will be valuable to them as long-term stakeholders

### Stage 1: Your Idea <a href="#stage-1-your-idea" id="stage-1-your-idea"></a>

#### Not yet confident about your idea? <a href="#not-yet-confident-about-your-idea" id="not-yet-confident-about-your-idea"></a>

Great! Governance proposals potentially impact many stakeholders. Introduce your idea with known members of the community before investing resources into drafting a proposal. Don't let negative feedback dissuade you from exploring your idea if you think that it's still important.

If you know people who are very involved with BlockX, send them a private message with a concise overview of what you think will result from your idea or proposed changes. Wait for them to ask questions before providing details. Do the same in semi-private channels where people tend to be respectful (and hopefully supportive).

#### Confident with your idea? <a href="#confident-with-your-idea" id="confident-with-your-idea"></a>

Great! However, remember that governance proposals potentially impact many stakeholders, which can happen in unexpected ways. Introduce your idea with members of the community before investing resources into drafting a proposal. At this point you should seek out and carefully consider critical feedback in order to protect yourself from [confirmation bias](https://en.wikipedia.org/wiki/Confirmation_bias). This is the ideal time to see a critical flaw, because submitting a flawed proposal will waste resources.

#### Are you ready to draft a governance proposal? <a href="#are-you-ready-to-draft-a-governance-proposal" id="are-you-ready-to-draft-a-governance-proposal"></a>

There will likely be differences of opinion about the value of what you're proposing to do and the strategy by which you're planning to do it. If you've considered feedback from broad perspectives and think that what you're doing is valuable and that your strategy should work, and you believe that others feel this way as well, it's likely worth drafting a proposal. However, remember that the largest BCX stakers have the biggest vote, so a vocal minority isn't necessarily representative or predictive of the outcome of an on-chain vote.

A conservative approach is to have some confidence that you roughly have initial support from a majority of the voting power before proceeding to drafting your proposal. However, there are likely other approaches, and if your idea is important enough, you may want to pursue it regardless of whether or not you are confident that the voting power will support it.

### Stage 2: Your Draft Proposal <a href="#stage-2-your-draft-proposal" id="stage-2-your-draft-proposal"></a>

The next major section outlines and describes some potential elements of drafting a proposal. Ensure that you have considered your proposal and anticipated questions that the community will likely ask. Once your proposal is on-chain, you will not be able to change it.

#### Proposal Elements <a href="#proposal-elements" id="proposal-elements"></a>

It will be important to balance two things: being detailed and being concise. You'll want to be concise so that people can assess your proposal quickly. You'll want to be detailed so that voters will have a clear, meaningful understanding of what the changes are and how they are likely to be impacted.

Every proposal should contain a summary with key details:

* who is submitting the proposal
* the amount of the proposal or parameter(s) being changed;
* and deliverables and timeline
* a reason for the proposal and potential impacts
* a short summary of the history (what compelled this proposal), solution that's being presented, and future expectations

Assume that many people will stop reading at this point. However, it is important to provide in-depth information, so a few more pointers for Parameter-Change, Community Spend, and ERC-20 Module proposals are below.

**Parameter-Change Proposal**

1. Problem/Value - generally the problem or value that's motivating the parameter change(s)
2. Solution - generally how changing the parameter(s) will address the problem or improve the network
   * the beneficiaries of the change(s) (ie. who will these changes impact and how?)
     * voters should understand the importance of the change(s) in a simple way
3. Risks & Benefits - clearly describe how making this/these change(s) may expose stakeholders to new benefits and/or risks
4. Supplementary materials - optional materials eg. models, graphs, tables, research, signed petition, etc

**Community Spend Proposal**

1. Applicant(s) - the profile of the person(s)/entity making the proposal
   * who you are and your involvement in Cosmos and/or other blockchain networks
   * an overview of team members involved and their relevant experience
   * brief mission statement for your organization/business (if applicable) eg. website
   * past work you've done eg. include your GitHub
   * some sort of proof of who you are eg. Keybase
2. Problem - generally what you're solving and/or opportunity you're addressing
   * provide relevant information about both past and present issues created by this problem
   * give suggestions as to the state of the future if this work is not completed
3. Solution - generally how you're proposing to deliver the solution
   * your plan to fix the problem or deliver value
   * the beneficiaries of this plan (ie. who will your plan impact and how?)
     * follow the "as a user" template ie. write a short user story about the problem you are trying to solve and how users will interact with what you're proposing to deliver (eg. benefits and functionality from a user’s perspective)
     * voters should understand the value of what you're providing in a simple way
   * your reasons for selecting this plan
   * your motivation for delivering this solution/value
4. Funding - amount and denomination proposed eg. 5000 BCX
   * the entity controlling the account receiving the funding
   * consider an itemized breakdown of funding per major deliverable
   * consider outlining how the funds will be spent
5. Deliverables and timeline - the specifics of what you're delivering and how, and what to expect
   * what are the specific deliverables? (be detailed)
   * when will each of these be delivered?
   * will there be a date at which the project will be considered failed if the deliverables have not been met?
   * how will each of these be delivered?
   * what will happen if you do not deliver on time?
     * what is the deadline for the project to be considered failed?
     * do you have a plan to return the funds?
   * how will you be accountable to BlockX stakeholders?
     * how will you communicate updates and how often?
     * how can the community observe your progress?
     * how can the community provide feedback?
   * how should the quality of deliverables be assessed? eg. metrics
6. Relationships and disclosures
   * how will you and/or your organization benefit?
   * do you see this work continuing in the future and is there a plan?
   * what are the risks involved with this work?
   * do you have conflicts of interest to declare?

**ERC-20 Proposal**

1. Applicant(s) - the profile of the person(s)/entity making the proposal
   * who you are and your involvement in Cosmos and/or other blockchain networks
   * an overview of team members involved and their relevant experience
   * brief mission statement for your organization/business (if applicable) eg. website
   * past work you've done eg. include your Github
   * some sort of proof of who you are eg. Keybase
2. Background information - promote understanding of the ERC-20 Module
   * a brief explanation of what the ERC-20 Module does
   * a mention of the [ERC-20 Module documentation ](https://manindra-1.gitbook.io/blockx/protocol-developers/modules/erc20)
3. Solution - generally how ERC-20 Module changes will be made
   * a brief explanation of what the proposal will do if it passes
   * a brief explanation of the precautions taken, how it was tested, and who was consulted prior to making the proposal
   * a breakdown of the proposal's payload, and third-party review
   * a brief explanation of the risks involved (depending on the direction of IBC Coin, ERC-20)
   * ensure the following are both adhered to and documented:
     * the contracts are deployed open-source
     * the contracts do not extend the `IERC20.sol` interface through a malicious implementation
     * the contracts use the main libraries for ERC-20s ([OpenZeppelin](https://docs.openzeppelin.com/contracts/4.x/erc20), [dapp.tools](https://dapp.tools/))
     * the transfer logic is not modified (i.e. transfer logic is not directly manipulated)
     * no malicious `Approve` events can directly manipulate users' balance through a delayed granted allowance

#### Begin with a well-considered draft proposal <a href="#begin-with-a-well-considered-draft-proposal" id="begin-with-a-well-considered-draft-proposal"></a>

The ideal format for a proposal is as a Markdown file (ie. `.md`) in a Github repo or [HackMd](https://hackmd.io/) markdown files.

#### Engage the community with your draft proposal <a href="#engage-the-community-with-your-draft-proposal" id="engage-the-community-with-your-draft-proposal"></a>

1. Post a discussion in the BlockX forum. Ideally this should contain a link to this repository, either directly to your proposal if it has been merged, or else to a pull-request containing your proposal if it has not been merged yet.
2. Directly engage key members of the community for feedback. These could be large contributors, those likely to be most impacted by the proposal, and entities with high stake-backing (eg. high-ranked validators; large stakers).
3. Target members of the community in a semi-public way before bringing the draft to a full public audience. The burden of public scrutiny in a semi-anonymized environment (eg. Twitter) can be stressful and overwhelming without establishing support. Solicit opinions in places with people who have established reputations first.

#### Submit your proposal to the testnet <a href="#submit-your-proposal-to-the-testnet" id="submit-your-proposal-to-the-testnet"></a>

You may want to submit your proposal to the testnet chain before the mainnet for a number of reasons, such as wanting to see what the proposal description will look like, to share what the proposal will look like in advance with stakeholders, and to signal that your proposal is about to go live on the mainnet.

Perhaps most importantly, for parameter change proposals, you can test the parameter changes in advance (if you have enough support from the voting power on the testnet).

Submitting your proposal to the testnet increases the likelihood of engagement and the possibility that you will be alerted to a flaw before deploying your proposal to mainnet.

### Stage 3: Your On-Chain Proposal <a href="#stage-3-your-on-chain-proposal" id="stage-3-your-on-chain-proposal"></a>

A majority of the voting community should probably be aware of the proposal and have considered it before the proposal goes live on-chain. If you're taking a conservative approach, you should have reasonable confidence that your proposal will pass before risking deposit contributions. Make revisions to your draft proposal after each stage of engagement.

#### The Deposit Period <a href="#the-deposit-period" id="the-deposit-period"></a>

The deposit period currently lasts 14 days. If you submitted your transaction with the minimum deposit (64 BCX), your proposal will immediately enter the voting period. If you didn't submit the minimum deposit amount (currently 64 BCX), then this may be an opportunity for others to show their support by contributing (and risking) their BCX as a bond for your proposal.&#x20;

You can request contributions openly and also contact stakeholders directly (particularly stakeholders who are enthusiastic about your proposal). Remember that each contributor is risking their funds, and you can read more about the conditions for burning deposits.

This is a stage where proposals may begin to get broader attention. Most popular explorers currently display proposals that are in the deposit period, but due to proposal spamming, this may change.

A large cross-section of the blockchain/cryptocurrency community exists on Twitter. Having your proposal in the deposit period is a good time to engage the BlockX community to prepare validators to vote and BCX holders that are staking.

#### The Voting Period <a href="#the-voting-period" id="the-voting-period"></a>

At this point you'll want to track which validator has voted and which has not. You'll want to re-engage directly with top stake-holders, ie. the highest-ranking validator operators, to ensure that:

1. they are aware of your proposal;
2. they can ask you any questions about your proposal; and
3. they are prepared to vote.

Remember that any voter may change their vote at any time before the voting period ends. That historically doesn't happen often, but there may be an opportunity to convince a voter to change their vote. The biggest risk is that stakeholders won't vote at all (for a number of reasons). Validator operators tend to need multiple reminders to vote.&#x20;

How you choose to contact validator operators, how often, and what you say is up to you--remember that no validator is obligated to vote, and that operators are likely occupied by competing demands for their attention. Take care not to stress any potential relationship with validator operators.


# Submit a Proposal

If you have a final draft of your proposal ready to submit, you may want to push your proposal live on the testnet first. These are the three primary steps to getting your proposal live on-chain.

1. (**Optional**) Hosting supplementary materials for your proposal with IPFS (InterPlanetary File System)
2. Formatting the JSON file for the governance proposal transaction that will be on-chain
3. Sending the transaction that submits your governance proposal on-chain

### Hosting supplementary materials <a href="#hosting-supplementary-materials" id="hosting-supplementary-materials"></a>

In general we try to minimize the amount of data pushed to the blockchain. Hence, detailed documentation about a proposal is usually hosted on a separate censorship resistant data-hosting platform, like IPFS.

Once you have drafted your proposal, ideally as a Markdown file, you can upload it to the IPFS network:

1. either by running an IPFS node and the IPFS software, or
2. using a service such as <https://pinata.cloud&#x20>;

Ensure that you "pin" the file so that it continues to be available on the network. You should get a URL like this: `https://ipfs.io/ipfs/QmbkQNtCAdR1CNbFE8ujub2jcpwUcmSRpSCg8gVWrTHSWD` The value `QmbkQNtCAdR1CNbFE8ujub2jcpwUcmSRpSCg8gVWrTHSWD` is called the `CID` of your file - it is effectively the file's hash.

If you uploaded a markdown file, you can use the IPFS markdown viewer to render the document for better viewing. Links for the markdown viewer look like `https://ipfs.io/ipfs/QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/example#/ipfs/<CID>`, where `<CID>` is your CID. For instance the link above would be: [https://ipfs.io/ipfs/QmTk...HSWD ](https://ipfs.io/ipfs/QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/example#/ipfs/QmbkQNtCAdR1CNbFE8ujub2jcpwUcmSRpSCg8gVWrTHSWD)

Share the URL with others and verify that your file is publicly accessible.

The reason we use IPFS is that it is a decentralized means of storage, making it resistant to censorship or single points of failure. This increases the likelihood that the file will remain available in the future.

### Formatting the JSON file for the governance proposal <a href="#formatting-the-json-file-for-the-governance-proposal" id="formatting-the-json-file-for-the-governance-proposal"></a>

Many proposals allow for long form text to be included, usually under the key `description`. These provide the opportunity to include [markdown ](https://www.markdownguide.org/)if formatted correctly as well as line breaks with.&#x20;

Beware, however, that if you are using the CLI to create a proposal, and setting `description` using a flag, the text will be escaped which may have undesired effects. If you're using markdown or line breaks it's recommended to put the proposal text into a json file and include that file as part of the CLI proposal, as opposed to individual fields in flags.

#### Text Proposals <a href="#text-proposals" id="text-proposals"></a>

`TextProposal`s are used by delegators to agree to a certain strategy, plan, commitment, future upgrade, or any other statement in the form of text. Aside from having a record of the proposal outcome on the Blockx chain, a text proposal has no direct effect on BlockX.

#### Community Pool Spend Proposals <a href="#community-pool-spend-proposals" id="community-pool-spend-proposals"></a>

For community pool spend proposals, there are five components:

1. **Title** - the distinguishing name of the proposal, typically the way the that explorers list proposals
2. **Description** - the body of the proposal that further describes what is being proposed and details surrounding the proposal
3. **Recipient** - the BlockX (bech32-based) address that will receive funding from the Community Pool
4. **Amount** - the amount of funding that the recipient will receive&#x20;
5. **Deposit** - the amount that will be contributed to the deposit from the account submitting the proposal

**Made-Up Example**

In this simple example (below), a network explorer will list the governance proposal as a `CommunityPoolSpendProposal`. When an observer selects the proposal, they'll see the description. Not all explorers will show the recipient and amount, so ensure that you verify that the description aligns with the what the governance proposal is programmed to enact. If the description says that a certain address will receive a certain number of BCX, it should also be programmed to do that, but it's possible that that's not the case (accidentally or otherwise).

The `amount` is `1000000000000000000abcx`. This is equal to 1 BCX, so `recipient` address blockx`1mx9nqk5agvlsvt2yc8259nwztmxq7zjq50mxkp` will receive 1 BCX if this proposal is passed.

The `deposit` of `64000000000000000000abcx` results in 64 BCX being used from the proposal submitter's account. There is a minimum deposit required for a proposal to enter the voting period, and anyone may contribute to this deposit within a 5-day period. If the minimum deposit isn't reached before this time, the deposit amounts will be burned. Deposit amounts will also be burned if quorum isn't met in the vote or if the proposal is vetoed.

```bash
{
  "title": "Community Pool Spend",
  "description": "This is the summary of the key information about this proposal. Include the URL to a PDF version of your full proposal.",
  "recipient": "blockx1mx9nqk5agvlsvt2yc8259nwztmxq7zjq50mxkp",
  "amount": [
    {
      "denom": "abcx",
      "amount": "1000000000000000000"
    }
  ],
  "deposit": [
    {
      "denom": "abcx",
      "amount": "64000000000000000000"
    }
  ]
}
```

#### Params-Change Proposals <a href="#params-change-proposals" id="params-change-proposals"></a>

{% hint style="info" %}
Changes to the `gov` module are different from the other kinds of parameter changes because `gov` has subkeys. Only the `key` part of the JSON file is different for `gov` parameter-change proposals.
{% endhint %}

For parameter-change proposals, there are seven components:

1. **Title** - the distinguishing name of the proposal, typically the way the that explorers list proposal
2. **Description** - the body of the proposal that further describes what is being proposed and details surrounding the proposal
3. **Subspace** - the BlockX module with the parameter that is being changed
4. **Key** - the parameter that will be changed
5. **Value** - the value of the parameter that will be changed by the governance mechanism
6. **Denom** - type of asset used as the deposit
7. **Amount** - the amount that will be contributed to the deposit from the account submitting the proposal

### &#x20;<a href="#sending-the-transaction-that-submits-your-governance-proposal" id="sending-the-transaction-that-submits-your-governance-proposal"></a>

#### CLI <a href="#cli" id="cli"></a>

This is the command format for using `blockxd` (the command-line interface) to submit your proposal on-chain:

```bash
blockxd tx gov submit-proposal \
  --title=<title> \
  --description=<description> \
  --type="Text" \
  --deposit="1000000bcx" \
  --from=<mykey> \
  --chain-id=<chain_id>
  --node <address>
```

{% hint style="info" %}
Use the `blockxd tx gov --help` flag to get more info about the governance commands
{% endhint %}

1. `blockxd` is the command-line interface client that is used to send transactions and query BlockX
2. `tx gov submit-proposal param-change` indicates that the transaction is submitting a parameter-change proposal
3. `--from mykey` is the account key that pays the transaction fee and deposit amount
4. `--gas 500000` is the maximum amount of gas permitted to be used to process the transaction
   * the more content there is in the description of your proposal, the more gas your transaction will consume
   * if this number isn't high enough and there isn't enough gas to process your transaction, the transaction will fail
   * the transaction will only use the amount of gas needed to process the transaction
5. `--gas-prices` is the flat-rate per unit of gas value for a validator to process your transaction
6. `--chain-id blockx_12346-1` is BlockX Mainnet. For current and past chain-id's, please look at the Chain ID documentation.
7. `--node` is using a full node to send the transaction to the BlockX Mainnet

#### Verifying your transaction <a href="#verifying-your-transaction" id="verifying-your-transaction"></a>

After posting your transaction, your command line interface (`blockxd`) will provide you with the transaction's hash, which you can either query using `blockxd` or by searching the transaction hash using Mintscan or any block explorer.

#### Depositing funds after a proposal has been submitted <a href="#depositing-funds-after-a-proposal-has-been-submitted" id="depositing-funds-after-a-proposal-has-been-submitted"></a>

Sometimes a proposal is submitted without having the minimum token amount deposited yet. In these cases you would want to be able to deposit more tokens to get the proposal into the voting stage. In order to deposit tokens, you'll need to know what your proposal ID is after you've submitted your proposal. You can query all proposals by the following command:

```bash
blockxd q gov proposals
```

If there are a lot of proposals on the chain already, you can also filter by your own address. For the proposal above, that would be:

```bash
blockxd q gov proposals --depositor blockx1hxv7mpztvln45eghez6evw2ypcw4vjmsmr8cdx
```

Once you have the proposal ID, this is the command to deposit extra tokens:

```bash
blockxd tx gov deposit <proposal-id> <deposit> --from <name>
```

In our case above, the `<proposal-id>` would be 59 as queried earlier. The `<deposit>` is written as `500000abcx`, just like the example above.

#### Submit your proposal to the testnet <a href="#submit-your-proposal-to-the-testnet" id="submit-your-proposal-to-the-testnet"></a>

You may want to submit your proposal to the testnet chain before the mainnet for a number of reasons:

1. To see what the proposal description will look like
2. To signal that your proposal is about to go live on the mainnet
3. To share what the proposal will look like in advance with stakeholders
4. To test the functionality of the governance features

Submitting your proposal to the testnet increases the likelihood that you will discover a flaw before deploying your proposal on mainnet. A few things to keep in mind:

* you'll need testnet tokens for your proposal (ask around for a [faucet](https://docs.evmos.org/developers/testnet/faucet.html))
* the parameters for testnet proposals are different (eg. voting period timing, deposit amount, deposit denomination)
* the deposit denomination is in `'atbcx'` instead of `'abcx'`


# Community Pool

BCX token holders can cast a vote to approve spending from the Community Pool to fund development and projects in the BlockX ecosystem.

### Why create a proposal to use Community Pool funds? <a href="#why-create-a-proposal-to-use-community-pool-funds" id="why-create-a-proposal-to-use-community-pool-funds"></a>

Why create a community-spend proposal?

* **As a strategy: you can do both.** You can submit your proposal to the BlockX Grants Program, but also consider submitting your proposal publicly on-chain. If the BlockX community votes in favor, you can withdraw your application.
* **As a strategy: funding is fast.** Besides the time it takes to push your proposal on-chain, the only other limiting factor is a fixed 5-day voting period. As soon as the proposal passes, your account will be credited the full amount of your proposal request.
* **To build rapport.** Engaging publicly with the community is the opportunity to develop relationships with stakeholders and to educate them about the importance of your work. Unforeseen partnerships could arise, and overall the community may value your work more if they are involved as stakeholders.
* **To be more independent.** The BlockX Grants Program may not always be able to fund work. Having a more consistently funded source and having a report with its stakeholders means you can use your rapport to have confidence in your ability to secure funding without having to be dependent upon the foundation alone.

### FAQ <a href="#faq" id="faq"></a>

#### How is the Community Pool funded? <a href="#how-is-the-community-pool-funded" id="how-is-the-community-pool-funded"></a>

10% of all tokens generated (via block rewards) are continually transferred to and accrue within the Community Pool.

How can funding for the Community Pool change?

Though the rate of funding is currently fixed at 10% of tokens minted per epoch. The current value of funding may be modified with a governance proposal and enacted immediately after the proposal passes.

#### How can funds from the Community Pool be spent? <a href="#how-can-funds-from-the-community-pool-be-spent" id="how-can-funds-from-the-community-pool-be-spent"></a>

Funds from the BlockX Community Pool may be spent via successful governance proposal.

#### How are funds disbursed after a community-spend proposal is passed? <a href="#how-are-funds-disbursed-after-a-community-spend-proposal-is-passed" id="how-are-funds-disbursed-after-a-community-spend-proposal-is-passed"></a>

If a community-spend proposal passes successfully, the number of BCX encoded in the proposal will be transferred from the community pool to the address encoded in the proposal, and this will happen immediately after the voting period ends.


# Chain Parameters

If a parameter-change proposal is successful, the change takes effect immediately upon completion of the voting period.

{% hint style="info" %}
Work on parameter setting is in progress
{% endhint %}

### List of Parameters <a href="#list-of-parameters" id="list-of-parameters"></a>

For a comprehensive list of available module parameters see the table below:

|    Module    |  Codebase  |                                     Parameters                                    |
| :----------: | :--------: | :-------------------------------------------------------------------------------: |
|     auth     | cosmos-sdk |     [reference](https://docs.cosmos.network/main/modules/auth/06_params.html)     |
|     bank     | cosmos-sdk |     [reference](https://docs.cosmos.network/main/modules/bank/05_params.html)     |
|    crisis    | cosmos-sdk |    [reference](https://docs.cosmos.network/main/modules/crisis/04_params.html)    |
| distribution | cosmos-sdk | [reference](https://docs.cosmos.network/main/modules/distribution/06_events.html) |
|  governance  | cosmos-sdk |      [reference](https://docs.cosmos.network/main/modules/gov/06_params.html)     |
|   slashing   | cosmos-sdk |   [reference](https://docs.cosmos.network/main/modules/slashing/08_params.html)   |
|    staking   | cosmos-sdk |    [reference](https://docs.cosmos.network/main/modules/staking/08_params.html)   |
|   transfer   |   ibc-go   |     [reference](https://github.com/cosmos/ibc-go/blob/main/docs/ibc/params.md)    |
|      evm     |  ethermint |     [reference](https://github.com/cosmos/ibc-go/blob/main/docs/ibc/params.md)    |
|   feemarket  |  ethermint |                                     reference                                     |
|    claims    |   blockx   |                                     reference                                     |
|     erc20    |   blockx   |                                     reference                                     |
|   feesplit   |   blockx   |                                     reference                                     |
|  incentives  |   blockx   |                                     reference                                     |
|   inflation  |   blockx   |                                     reference                                     |


# Technical Concepts


# Architecture

### Cosmos SDK <a href="#cosmos-sdk" id="cosmos-sdk"></a>

BlockX enables the full composability and modularity of the [Cosmos SDK](https://docs.cosmos.network/).

### Tendermint Core & the Application Blockchain Interface (ABCI) <a href="#tendermint-core-the-application-blockchain-interface-abci" id="tendermint-core-the-application-blockchain-interface-abci"></a>

Tendermint consists of two chief technical components: a blockchain consensus engine and a generic application interface. The consensus engine, called [Tendermint Core](https://docs.tendermint.com/), ensures that the same transactions are recorded on every machine in the same order. The application interface, called the [Application Blockchain Interface (ABCI)](https://docs.tendermint.com/master/spec/abci/), enables the transactions to be processed in any programming language.

Tendermint has evolved to be a general purpose blockchain consensus engine that can host arbitrary application states. Since Tendermint can replicate arbitrary applications, it can be used as a plug-and-play replacement for the consensus engines of other blockchains. BlockX is such an example of an ABCI application replacing Ethereum's PoW via Tendermint's consensus engine.

Another example of a cryptocurrency application built on Tendermint is the Cosmos network. Tendermint is able to decompose the blockchain design by offering a very simple API (ie. the ABCI) between the application process and consensus process.

### EVM module <a href="#evm-module" id="evm-module"></a>

BlockX enables EVM compatibility by implementing various components that together support all the EVM state transitions while ensuring the same developer experience as Ethereum:

* Ethereum transaction format as a Cosmos SDK `Tx` and `Msg` interface
* Ethereum's `secp256k1` curve for the Cosmos Keyring
* `StateDB` interface for state updates and queries
* JSON-RPC client for interacting with the EVM


# Accounts

{% hint style="warning" %}
The following functions and commands are subject to further testing and potential changed.
{% endhint %}

### BlockX Accounts <a href="#evmos-accounts" id="evmos-accounts"></a>

BlockX defines its own custom `Account` type that uses Ethereum's ECDSA secp256k1 curve for keys. This satisfies the [EIP84 ](https://github.com/ethereum/EIPs/issues/84)for full [BIP44 ](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)paths. The root HD path for BlockXs-based accounts is `m/44'/60'/0'/0`.

```go
// EthAccount implements the authtypes.AccountI interface and embeds an
// authtypes.BaseAccount type. It is compatible with the auth AccountKeeper.
type EthAccount struct {
	*types.BaseAccount `protobuf:"bytes,1,opt,name=base_account,json=baseAccount,proto3,embedded=base_account" json:"base_account,omitempty" yaml:"base_account"`
	CodeHash           string `protobuf:"bytes,2,opt,name=code_hash,json=codeHash,proto3" json:"code_hash,omitempty" yaml:"code_hash"`
}
```

### Addresses and Public Keys <a href="#addresses-and-public-keys" id="addresses-and-public-keys"></a>

[BIP-0173 ](https://github.com/satoshilabs/slips/blob/master/slip-0173.md)defines a new format for segregated witness output addresses that contains a human-readable part that identifies the Bech32 usage. BlockX uses the following HRP (human readable prefix) as the base HRP:

| Network | Testnet | Mainnet |
| :-----: | :-----: | :-----: |
|         |         |         |

There are 3 main types of HRP for the `Addresses`/`PubKeys` available by default on BlockX:

* Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`eth_secp256k1`** curve.
* Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`eth_secp256k1`** curve.
* Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are derived using the **`ed25519`** curve.

{% hint style="info" %}
Data items are coming soon
{% endhint %}

| -                  | Address bech32 Prefix | Pubkey bech32 Prefix | Curve | Address byte length | Pubkey byte length |
| ------------------ | --------------------- | -------------------- | ----- | ------------------- | ------------------ |
| Accounts           |                       |                      |       |                     |                    |
| Validator Operator |                       |                      |       |                     |                    |
| Consensus Nodes    |                       |                      |       |                     |                    |

### Address formats for clients <a href="#address-formats-for-clients" id="address-formats-for-clients"></a>

`EthAccount` can be represented in both [Bech32](https://en.bitcoin.it/wiki/Bech32) and hex (`0x...`) formats for Ethereum's Web3 tooling compatibility.

The Bech32 format is the default format for Cosmos-SDK queries and transactions through CLI and REST clients. The hex format on the other hand, is the Ethereum `common.Address` representation of a Cosmos `sdk.AccAddress`.

* **Address (Bech32)**: `[]`
* **Address (**[**EIP55**](https://eips.ethereum.org/EIPS/eip-55) **Hex)**: `[]`
* **Compressed Public Key**: `[]`

#### Address conversion <a href="#address-conversion" id="address-conversion"></a>

The `[]` can be used to convert an address between hex and bech32 formats. For example:

:::: tabs ::: tab Bech32

```bash
blockxd debug addr blockx1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
  Address: [20 87 74 109 255 45 223 158 7 130 139 67 69 211 4 9 25 175 86 82]
  Address (hex): 14574A6DFF2DDF9E07828B4345D3040919AF5652
  Bech32 Acc: blockx1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
  Bech32 Val: blockxvaloper1z3t55m0l9h0eupuz3dp5t5cypyv674jjn4d6nn
```

::: ::: tab Hex

```bash
blockxd debug addr 14574A6DFF2DDF9E07828B4345D3040919AF5652
  Address: [20 87 74 109 255 45 223 158 7 130 139 67 69 211 4 9 25 175 86 82]
  Address (hex): 14574A6DFF2DDF9E07828B4345D3040919AF5652
  Bech32 Acc: blockx1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
  Bech32 Val: blockxvaloper1z3t55m0l9h0eupuz3dp5t5cypyv674jjn4d6nn
```

::: ::::

#### Key output <a href="#key-output" id="key-output"></a>

{% hint style="info" %}
The Cosmos SDK Keyring output (i.e blockxd`keys`) only supports addresses and public keys in Bech32 format.
{% endhint %}

We can use the `keys show` command of `blockxd` with the flag `--bech <type> (acc|val|cons)` to obtain the addresses and keys as mentioned above,

:::: tabs ::: tab Account

```bash
blockxd keys show mykey --bech acc
- name: mykey
  type: local
  address: blockx1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
  pubkey: '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"AsV5oddeB+hkByIJo/4lZiVUgXTzNfBPKC73cZ4K1YD2"}'
  mnemonic: ""
```

::: ::: tab Validator

```bash
blockxd keys show mykey --bech val
- name: mykey
  type: local
  address: blockxvaloper1z3t55m0l9h0eupuz3dp5t5cypyv674jjn4d6nn
  pubkey: '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"AsV5oddeB+hkByIJo/4lZiVUgXTzNfBPKC73cZ4K1YD2"}'
  mnemonic: ""
```

::: ::: tab Consensus

```bash
blockxd keys show mykey --bech cons
- name: mykey
  type: local
  address: blockxvalcons1rllqa5d97n6zyjhy6cnscc7zu30zjn3f7wyj2n
  pubkey: '{"@type":"/ethermint.crypto.v1.ethsecp256k1.PubKey","key":"A/fVLgIqiLykFQxum96JkSOoTemrXD0tFaFQ1B0cpB2c"}'
  mnemonic: ""
```

::: ::::

### Querying an Account <a href="#querying-an-account" id="querying-an-account"></a>

You can query an account address using the CLI, gRPC or

#### Command Line Interface <a href="#command-line-interface" id="command-line-interface"></a>

```bash
# NOTE: the --output (-o) flag will define the output format in JSON or YAML (text)
blockxd q auth account $(blockxd keys show mykey -a) -o text
|
  '@type': /ethermint.types.v1.EthAccount
  base_account:
    account_number: "0"
    address: blockx1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
    pub_key:
      '@type': /ethermint.crypto.v1.ethsecp256k1.PubKey
      key: AsV5oddeB+hkByIJo/4lZiVUgXTzNfBPKC73cZ4K1YD2
    sequence: "1"
  code_hash: 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
```

#### Cosmos gRPC and REST <a href="#cosmos-grpc-and-rest" id="cosmos-grpc-and-rest"></a>

```bash
# GET /cosmos/auth/v1beta1/accounts/{address}
curl -X GET "http://localhost:10337/cosmos/auth/v1beta1/accounts/blockx14au322k9munkmx5wrchz9q30juf5wjgz2cfqku" -H "accept: application/json"
```

#### JSON-RPC <a href="#json-rpc" id="json-rpc"></a>

To retrieve the Ethereum hex address using Web3, use the JSON-RPC `eth_accounts` or `personal_listAccounts` endpoints:

```bash
# query against a local node
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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


# Chain ID

### Official Chain IDs <a href="#official-chain-ids" id="official-chain-ids"></a>

{% hint style="info" %}
The latest Chain ID (i.e highest Version Number) is the latest version of the software and mainnet.
{% endhint %}

::: ::: tab Testnets

| Name     | Chain ID      | Identifier | EIP155 Number | Version Number |
| -------- | ------------- | ---------- | ------------- | -------------- |
| BlockX   | blockx\_100-1 | blockx     | 100           | 1              |
| Atlantis | `blockx_50-1` | `blockx`   | `50`          | 1              |

### The Chain Identifier <a href="#the-chain-identifier" id="the-chain-identifier"></a>

Every chain must have a unique identifier or `chain-id`. Tendermint requires each application to define its own `chain-id` in the [genesis.json fields](https://docs.tendermint.com/master/spec/core/genesis.html#genesis-fields). However, in order to comply with both EIP155 and Cosmos standard for chain upgrades, BlockX-compatible chains must implement a special structure for their chain identifiers.

### Structure <a href="#structure" id="structure"></a>

The BlockX Chain ID contains 3 main components

* **Identifier**: Unstructured string that defines the name of the application.
* **EIP155 Number**: Immutable [EIP155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) `CHAIN_ID` that defines the replay attack protection number.
* **Version Number**: Is the version number (always positive) that the chain is currently running. This number **MUST** be incremented every time the chain is upgraded or forked in order to avoid network or consensus errors.

#### Format <a href="#format" id="format"></a>

The format for specifying and BlockX-compatible chain-id in genesis is the following:

```
{identifier}_{EIP155}-{version}
```


# Encoding

### Encoding Formats <a href="#encoding-formats" id="encoding-formats"></a>

#### Protocol Buffers <a href="#protocol-buffers" id="protocol-buffers"></a>

The Cosmos [Stargate ](https://stargate.cosmos.network/)release introduces [protobuf ](https://developers.google.com/protocol-buffers)as the main encoding format for both client and state serialization. All the EVM module types that are used for state and clients (transaction messages, genesis, query services, etc) will be implemented as protocol buffer messages.

#### Amino <a href="#amino" id="amino"></a>

The Cosmos SDK also supports the legacy Amino encoding format for backwards compatibility with previous versions, specially for client encoding and signing with Ledger devices. BlockX does not support Amino in the EVM module, but it is supported for all other Cosmos SDK modules that enable it.

#### RLP <a href="#rlp" id="rlp"></a>

Recursive Length Prefix ([RLP](https://eth.wiki/en/fundamentals/rlp)), is an encoding/decoding algorithm that serializes a message and allows for quick reconstruction of encoded data. BlockX uses RLP to encode/decode Ethereum messages for JSON-RPC handling to conform messages to the proper Ethereum format. This allows messages to be encoded and decoded in the exact format as Ethereum's.

The `x/evm` transactions (`MsgEthereumTx`) encoding is performed by casting the message to a go-ethereum's `Transaction` and then marshaling the transaction data using RLP:

```go
// TxEncoder overwrites sdk.TxEncoder to support MsgEthereumTx
func (g txConfig) TxEncoder() sdk.TxEncoder {
  return func(tx sdk.Tx) ([]byte, error) {
    msg, ok := tx.(*evmtypes.MsgEthereumTx)
    if ok {
      return msg.AsTransaction().MarshalBinary()
   }
    return g.TxConfig.TxEncoder()(tx)
  }
}

// TxDecoder overwrites sdk.TxDecoder to support MsgEthereumTx
func (g txConfig) TxDecoder() sdk.TxDecoder {
  return func(txBytes []byte) (sdk.Tx, error) {
    tx := &ethtypes.Transaction{}

    err := tx.UnmarshalBinary(txBytes)
    if err == nil {
      msg := &evmtypes.MsgEthereumTx{}
      msg.FromEthereumTx(tx)
      return msg, nil
    }

    return g.TxConfig.TxDecoder()(txBytes)
  }
}
```


# Pending State

### BlockX vs Ethereum <a href="#evmos-vs-ethereum" id="evmos-vs-ethereum"></a>

In Ethereum, pending blocks are generated as they are queued for production by miners. These pending blocks include pending transactions that are picked out by miners, based on the highest reward paid in gas.&#x20;

This mechanism exists as block finality is not possible on the Ethereum network. Blocks are committed with probabilistic finality, which means that transactions and blocks become less likely to become reverted as more time (and blocks) passes.

BlockX is designed quite differently on this front as there is no concept of a "pending state". BlockX uses [Tendermint Core](https://docs.tendermint.com/) BFT consensus which provides instant finality for transaction. For this reason, Ethermint does not require a pending state mechanism, as all (if not most) of the transactions will be committed to the next block (avg. block time on Cosmos chains is \~8s). However, this causes a few hiccups in terms of the Ethereum Web3-compatible queries that can be made to pending state.

Another significant difference with Ethereum, is that blocks are produced by validators or block producers, who include transactions from their local mempool into blocks in a first-in-first-out (FIFO) fashion. Transactions on BlockX cannot be ordered or cherry picked out from the Tendermint node [mempool](https://docs.tendermint.com/master/tendermint-core/mempool/).

### Pending State Queries <a href="#pending-state-queries" id="pending-state-queries"></a>

BlockX will make queries which will account for any unconfirmed transactions present in a node's transaction mempool. A pending state query made will be subjective and the query will be made on the target node's mempool. Thus, the pending state will not be the same for the same query to two different nodes.

#### JSON-RPC Calls on Pending Transactions <a href="#json-rpc-calls-on-pending-transactions" id="json-rpc-calls-on-pending-transactions"></a>

* `eth_getBalance`
* `eth_getTransactionCount`
* `eth_getBlockTransactionCountByNumber`
* `eth_getBlockByNumber`
* `eth_getTransactionByHash`
* `eth_getTransactionByBlockNumberAndIndex`
* `eth_sendTransaction`


# dApp Developers

### List of Resources <a href="#list-of-resources" id="list-of-resources"></a>

Please find the following resources for in-depth information:

* **Quick Connect**: List of publicly available endpoints.
* **BlockX Clients**: Description of available clients.
* **Testnet Faucet**: Explaination of faucet use to obtain testnet tokens.
* **Localnet**: Instructions on how to configure a local instance of the BlockX blockchain.
  * **Single Node**: Run a single local node.
  * **Multi Node**: Run a local testnet with multiple nodes.
  * **Testnet**: Use the testnet command of the BlockX daemon.
* **Guides**:
  * **Wallet Integration**: Connect Metamask wallet to a UI.
  * **ERC-20 Registration**: Register interoperable ERC-20s through governance.
  * **Cosmos Coin Registration**: Register native Cosmos Coins through governance.
  * **Smart Contract Registration**: Register smart contracts in the dApp store to earn income.
  * **Incentives Registration**: Register smart contract incentives through governance.
  * **Trace Transactions**: Learn how to trace transactions on BlockX.
  * **Query Balances**: Learn how to query balances on BlockX.

#### Remote Procedure Calls (RPCs) <a href="#remote-procedure-calls-rpcs" id="remote-procedure-calls-rpcs"></a>

As BlockX lives at the crossroads of Cosmos and Ethereum, there are RPC connections available for all corresponding interfaces:

* **JSON-RPC Server**: General information about the JSON-RPC server provided by BlockX.
* **Running The Server**: Instructions on how to set up the server when running a node.
* **Namespaces**: Description of the available JSON-RPC namespaces.
* **JSON-RPC Methods**: List of supported JSON-RPC endpoints and methods.
* **Events**: Information about the available events and instructions to subscribe to them.
* **Cosmos gRPC & REST**: Documentation of the available gRPC implementation on BlockX.
* **Tendermint RPC**: Documentation for the RPC protocols supported by Tendermint.

#### Tutorials for Ethereum Developers <a href="#tutorials-for-ethereum-devs" id="tutorials-for-ethereum-devs"></a>

To welcome Ethereum developers, there is a selection of tutorials available showcasing some widely used developer tools:

* **Remix**: Instructions to deploy a smart contract on BlockX with [Remix IDE](http://remix.ethereum.org/).
* **Hardhat**: Instructions to deploy a smart contract on BlockX with the [Hardhat ](https://hardhat.org/)suite of development tools.
* **Truffle**: Instructions to deploy a smart contract on BlockX using the [Truffle](https://www.trufflesuite.com/truffle) framework.


# Establishing Connections

### Public Available Endpoints <a href="#public-available-endpoints" id="public-available-endpoints"></a>

Below is a list of publicly available endpoints that you can use to connect to the Atlantis Network:

RPC: <https://atlantis-rpc.blockxnet.com>

API: <https://atlantis-api.blockxnet.com>

Web3: <https://atlantis-web3.blockxnet.com><br>


# BlockX Clients

BlockX supports different clients in order to support Cosmos and Ethereum transactions and queries:

| -                                | Description                                                                          | Default Port |
| -------------------------------- | ------------------------------------------------------------------------------------ | ------------ |
| **Cosmos gRPC**                  | Query or send BlockX transactions using gRPC                                         | `9090`       |
| **Cosmos REST (gRPC-Gateway)**   | Query or send BlockX  transactions using an HTTP RESTful API                         | `9091`       |
| **Ethereum JSON-RPC**            | Query Ethereum-formatted transactions and blocks or send Ethereum txs using JSON-RPC | `8545`       |
| **Ethereum Websocket**           | Subscribe to Ethereum logs and events emitted in smart contracts.                    | `8586`       |
| **Tendermint RPC**               | Subscribe to Ethereum logs and events emitted in smart contracts.                    | `26657`      |
| **Tendermint Websocket**         | Query transactions, blocks, consensus state, broadcast transactions, etc.            | `26657`      |
| **Command Line Interface (CLI)** | Query or send BlockX  transactions using your Terminal or Console.                   | N/A          |

### Cosmos gRPC <a href="#cosmos-grpc" id="cosmos-grpc"></a>

BlockX exposes gRPC endpoints for all the integrated Cosmos SDK modules. This makes it easier for wallets and block explorers to interact with the Proof-of-Stake logic and native Cosmos transactions and queries.

#### Cosmos gRPC-Gateway (HTTP REST) <a href="#cosmos-grpc-gateway-http-rest" id="cosmos-grpc-gateway-http-rest"></a>

[gRPC-Gateway](https://grpc-ecosystem.github.io/grpc-gateway/) reads a gRPC service definition and generates a reverse-proxy server which translates RESTful JSON API into gRPC. With gRPC-Gateway, users can use REST to interact the Cosmos gRPC service.

### Ethereum JSON-RPC <a href="#ethereum-json-rpc" id="ethereum-json-rpc"></a>

BlockX supports most of the standard [JSON-RPC APIs](https://docs.evmos.org/developers/json-rpc/server.html) to connect with existing Ethereum-compatible web3 tooling.

### Ethereum Websocket <a href="#ethereum-websocket" id="ethereum-websocket"></a>

Then, start a websocket subscription with [`ws`](https://github.com/hashrocket/ws)

```bash
# connect to tendermint websocet at port 8546 as defined above
ws ws://localhost:8546/

# subscribe to new Ethereum-formatted block Headers
> {"id": 1, "method": "eth_subscribe", "params": ["newHeads", {}]}
< {"jsonrpc":"2.0","result":"0x44e010cb2c3161e9c02207ff172166ef","id":1}
```

### Tendermint Websocket <a href="#tendermint-websocket" id="tendermint-websocket"></a>

Tendermint Core provides a Websocket connection to subscribe or unsubscribe to Tendermint ABCI events.

{% hint style="info" %}
For more info about the how to subscribe to events, please refer to the official [Tendermint documentation](https://docs.tendermint.com/v0.34/tendermint-core/subscription.html).
{% endhint %}

```bash
{
    "jsonrpc": "2.0",
    "method": "subscribe",
    "id": "0",
    "params": {
        "query": "tm.event='<event_value>' AND eventType.eventAttribute='<attribute_value>'"
    }
}
```

#### List of Tendermint Events <a href="#list-of-tendermint-events" id="list-of-tendermint-events"></a>

The main events you can subscribe to are:

* `NewBlock`: Contains `events` triggered during `BeginBlock` and `EndBlock`.
* `Tx`: Contains `events` triggered during `DeliverTx` (i.e. transaction processing).
* `ValidatorSetUpdates`: Contains validator set updates for the block.

{% hint style="info" %}
The list of events types and values for each Cosmos SDK module can be found in the **`Modules`** Specification section. Check the `Events` page to obtain the event list of each supported module on BlockX .
{% endhint %}

List of all Tendermint event keys:

| -                                                    | Event Type       | Categories  |
| ---------------------------------------------------- | ---------------- | ----------- |
| Subscribe to a specific event                        | `"tm.event"`     | `block`     |
| Subscribe to a specific transaction                  | `"tx.hash"`      | `block`     |
| Subscribe to transactions at a specific block height | `"tx.height"`    | `block`     |
| Index `BeginBlock` and `Endblock` events             | `"block.height"` | `block`     |
| Subscribe to ABCI `BeginBlock` events                | `"begin_block"`  | `block`     |
| Subscribe to ABCI `EndBlock` events                  | `"end_block"`    | `consensus` |

Below is a list of values that you can use to subscribe for the `tm.event` type:

| -                      | Event Value             | Categories  |
| ---------------------- | ----------------------- | ----------- |
| New block              | `"NewBlock"`            | `block`     |
| New block header       | `"NewBlockHeader"`      | `block`     |
| New Byzantine Evidence | `"NewEvidence"`         | `block`     |
| New transaction        | `"Tx"`                  | `block`     |
| Validator set updated  | `"ValidatorSetUpdates"` | `block`     |
| Block sync status      | `"BlockSyncStatus"`     | `consensus` |
| lock                   | `"Lock"`                | `consensus` |
| New consensus round    | `"NewRound"`            | `consensus` |
| Polka                  | `"Polka"`               | `consensus` |
| Relock                 | `"Relock"`              | `consensus` |
| State sync status      | `"StateSyncStatus"`     | `consensus` |
| Timeout propose        | `"TimeoutPropose"`      | `consensus` |
| Timeout wait           | `"TimeoutWait"`         | `consensus` |
| Unlock                 | `"Unlock"`              | `consensus` |
| Block is valid         | `"ValidBlock"`          | `consensus` |
| Consensus vote         | `"Vote"`                | `consensus` |

#### Example

```bash
ws ws://localhost:26657/websocket
> { "jsonrpc": "2.0", "method": "subscribe", "params": ["tm.event='ValidatorSetUpdates'"], "id": 1 }
```

Example response:

```bash
{
    "jsonrpc": "2.0",
    "id": 0,
    "result": {
        "query": "tm.event='ValidatorSetUpdates'",
        "data": {
            "type": "tendermint/event/ValidatorSetUpdates",
            "value": {
              "validator_updates": [
                {
                  "address": "09EAD022FD25DE3A02E64B0FE9610B1417183EE4",
                  "pub_key": {
                    "type": "tendermint/PubKeyEd25519",
                    "value": "ww0z4WaZ0Xg+YI10w43wTWbBmM3dpVza4mmSQYsd0ck="
                  },
                  "voting_power": "10",
                  "proposer_priority": "0"
                }
              ]
            }
        }
    }
}
```

### CLI <a href="#cli" id="cli"></a>

Users can use the `blockxd` binary to interact directly with an BlockX node though the CLI.

{% hint style="info" %}
To use the CLI, you will need to provide a Tendermint RPC address for the `--node` flag. Look for a publicly available addresses for testnet and mainnet in the Establishing Connections page.
{% endhint %}

* **Transactions**: `blockxd tx`

  The list of available commands, as of `v3.0.0`, are:

```bash
Available Commands:
  authz               Authorization transactions subcommands
  bank                Bank transaction subcommands
  broadcast           Broadcast transactions generated offline
  crisis              Crisis transactions subcommands
  decode              Decode a binary encoded transaction string
  distribution        Distribution transactions subcommands
  encode              Encode transactions generated offline
  erc20               erc20 subcommands
  evidence            Evidence transaction subcommands
  evm                 evm transactions subcommands
  feegrant            Feegrant transactions subcommands
  gov                 Governance transactions subcommands
  ibc                 IBC transaction subcommands
  ibc-transfer        IBC fungible token transfer transaction subcommands
  multisign           Generate multisig signatures for transactions generated offline
  multisign-batch     Assemble multisig transactions in batch from batch signatures
  sign                Sign a transaction generated offline
  sign-batch          Sign transaction batch files
  slashing            Slashing transaction subcommands
  staking             Staking transaction subcommands
  validate-signatures validate transactions signatures
  vesting             Vesting transaction subcommands
```

**Queries**: `blockxd query`

The list of available commands, as of `v3.0.0`, are:

```bash
Available Commands:
  account                  Query for account by address
  auth                     Querying commands for the auth module
  authz                    Querying commands for the authz module
  bank                     Querying commands for the bank module
  block                    Get verified data for a the block at given height
  claims                   Querying commands for the claims module
  distribution             Querying commands for the distribution module
  epochs                   Querying commands for the epochs module
  erc20                    Querying commands for the erc20 module
  evidence                 Query for evidence by hash or for all (paginated) submitted evidence
  evm                      Querying commands for the evm module
  feegrant                 Querying commands for the feegrant module
  feemarket                Querying commands for the fee market module
  gov                      Querying commands for the governance module
  ibc                      Querying commands for the IBC module
  ibc-transfer             IBC fungible token transfer query subcommands
  incentives               Querying commands for the incentives module
  inflation                Querying commands for the inflation module
  params                   Querying commands for the params module
  recovery                 Querying commands for the recovery module
  slashing                 Querying commands for the slashing module
  staking                  Querying commands for the staking module
  tendermint-validator-set Get the full tendermint validator set at given height
  tx                       Query for a transaction by hash, "<addr>/<seq>" combination or comma-separated signatures in a committed block
  txs                      Query for paginated transactions that match a set of events
  upgrade                  Querying commands for the upgrade module
  vesting                  Querying commands for the vesting module
```

{% hint style="info" %}
When querying Ethereum transactions versus Cosmos transactions, the transaction hashes are different. When querying Ethereum transactions, users need to use event query. Here's an example with the CLI:
{% endhint %}

```bash
curl -X GET "http://localhost:26657/tx_search?query=ethereum_tx.ethereumTxHash%3D0x8d43464891fac6c113e809e14dff1a3e608eae124d629799e42ca0e36562d9d7&prove=false&page=1&per_page=30&order_by=asc" -H "accept: application/json"  
```


# Guides


# Wallet Integration

### Implementation Checklist <a href="#implementation-checklist" id="implementation-checklist"></a>

The integration implementation checklist for dApp developers consists of three categories:

1. Frontend features
2. Transactions and wallet interactions
3. Client-side provider

#### Frontend <a href="#frontend" id="frontend"></a>

Make sure to create a wallet-connection button for Metamask and/or Keplr on the frontend of the application. For instance, consider the "Connect to a wallet" button on the interface of [Diffusion Finance](https://app.diffusion.fi/).

#### Transactions <a href="#transactions" id="transactions"></a>

Developers enabling transactions on their dApp have to determine wallet type of the user, create the transaction, request signatures from the corresponding wallet, and finally broadcast the transaction to the network.

**Determining Wallet Type**

Developers should determine whether users are using Keplr or MetaMask. Whether MetaMask or Keplr is installed on the user device can be determined by checking the corresponding `window.ethereum` or `window.keplr` value.

* **For MetaMask**: `await window.ethereum.enable(chainId);`
* **For Keplr**: `await window.keplr.enable(chainId);`

If either `window.ethereum` or `window.keplr` returns `undefined` after `document.load`, then MetaMask (or, correspondingly, Keplr) is not installed. There are several ways to wait for the load event to check the status: for instance, developers can register functions to `window.onload`, or they can track the document's ready state through the document event listener.

After the user's wallet type has been determined, developers can proceed with creating, signing, and sending transactions.

**Create the Transaction**

{% hint style="info" %}
The example below uses the BlockX Testnet `chainID`. For more info, check the BlockX Chain IDs reference document here.
{% endhint %}

Developers can create `MsgSend` transactions.

```javascript
import { createMessageSend } from @tharsis/transactions

const chain = {
    chainId: 50,
    cosmosChainId: 'blockx_50-1',
}

const sender = {
    accountAddress: 'blockx1mx9nqk5agvlsvt2yc8259nwztmxq7zjq50mxkp',
    sequence: 1,
    accountNumber: 9,
    pubkey: 'AgTw+4v0daIrxsNSW4FcQ+IoingPseFwHO1DnssyoOqZ',
}

const fee = {
    amount: '20',
    denom: 'abcx',
    gas: '200000',
}

const memo = ''

const params = {
    destinationAddress: 'blockx1pmk2r32ssqwps42y3c9d4clqlca403yd9wymgr',
    amount: '1',
    denom: 'abcx',
}

const msg = createMessageSend(chain, sender, fee, memo, params)

// msg.signDirect is the transaction in Keplr format
// msg.legacyAmino is the transaction with legacy amino
// msg.eipToSign is the EIP712 data to sign with metamaskjs
```

**Sign and Broadcast the Transaction**

{% hint style="info" %}
The example below uses an BlockX Testnet RPC node.
{% endhint %}

After creating the transaction, developers need to send the payload to the appropriate wallet to be signed ([`msg.signDirect` ](https://docs.keplr.app/api/#sign-direct-protobuf)is the transaction in Keplr format, and `msg.eipToSign` is the [`EIP712`](https://eips.ethereum.org/EIPS/eip-712) data to sign with MetaMask).

#### Connections <a href="#connections" id="connections"></a>

For Ethereum RPC, BlockX gRPC, and/or REST queries, dApp developers should implement providers client-side, and store RPC details in the environment variable as secrets.


# Smart Contract Incentive Registration

An incentive for a smart contract can be registered through governance to encourage more interaction with that contract. Users who interact with a registered contract (eg. through submission of transactions) will have rewards distributed to them. These rewards are essentially cash-back for the gas spent on the initial transactions.

To register smart contract incentives, consider the following stages:

1. Drafting the Contract Incentives Proposal
2. Submitting the Contract Incentives Proposal
3. The On-Chain Contract Incentives Proposal

This document also discusses incentives analysis through telemetry.

Check out the incentives module specification for more information on incentives.

### Drafting the Contract Incentives Proposal <a href="#drafting-the-contract-incentives-proposal" id="drafting-the-contract-incentives-proposal"></a>

The following topics must be addressed when drafting a Contract Incentives Proposal:

1. Provide the profile of the person(s)/entity making the proposal.

   Who are you? What is your involvement in Cosmos and/or other blockchain networks? If you are working with a team, who are the team members involved and what is their relevant experience? What is the mission statement of your organization or business? Do you have a website? Showcase some work you've done, and some proof of who you are.
2. Promote understanding of the `x/incentives` Module.

   Make sure to mention the `x/incentives` Module Documentation along with a brief explanation of what the `x/incentives` Module does.&#x20;
3. Describe what changes are being made, and why they are required.

   Give a breakdown of the proposal's payload, and explain in layman's terms what the proposal will do if it passes. For the smart contract in question, provide general information on its purpose, along with an argument for why it requires incentives. Mention risks involved in the proposal, depending on the traction of the smart contract involved and the timetable for the proposed incentives. Finally, detail precautions taken during proposal formulation, if applicable (including consultations made prior to proposal creation, and any third-party reviews).

### Submitting the Contract Incentives Proposal <a href="#submitting-the-contract-incentives-proposal" id="submitting-the-contract-incentives-proposal"></a>

After the drafting process, the Contract Incentives Proposal can be submitted.

#### Formatting the Proposal's Text <a href="#formatting-the-proposal-s-text" id="formatting-the-proposal-s-text"></a>

The ideal format for a proposal is as a Markdown file (ie. `.md`) in a Github repo or [HackMd](https://hackmd.io/). Markdown is a simple and accessible format for writing plain text files that is easy to learn. See the [Github Markdown Guide](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) for details on writing markdown files.

#### Submit the Proposal to Testnet <a href="#submit-the-proposal-to-testnet" id="submit-the-proposal-to-testnet"></a>

To submit the proposal to testnet through the command line with `blockxd`, use the following command with `register-incentive`:

```bash
blockxd tx gov submit-proposal \
  register-incentive \
  $CONTRACTADDRESS \
  $ALLOCATION \
  $NUMWEEKS \
  --title=<title> \
  --description=<description> \
  --deposit="1000000ablockx" \
  --from=<mykey> \
  --chain-id=<testnet_chain_id> \
  --node <address>
```

with the following arguments:

* `$CONTRACTADDRESS`: Ethereum hex-formatted (`0x...`) address of the contract that users will interact with in your dApp. If you are using several external/internal contracts, **make sure the contract is the correct one**.
* `$ALLOCATION`: Denominations and percentage of the total rewards (25% of block distribution) to be allocated to users that interact and spend gas using the `$CONTRACTADDRESS` (eg. `"0.005000000000000000abcx"` will distribute 0.5% of out of the 25% tokens minted on each daily epoch rewards).
* `$NUMWEEKS`: Number of weeks (counted by epochs) that you want the `$CONTRACTADDRESS` to be incentivized for.
  * 6 months (`26` epochs): recommended for long-term incentives on apps that have a lot of traction
  * 3 months (`13` epochs): recommended for long-term incentives on apps that have some traction
  * 1 months (`4` epochs): recommended for short-term incentives on apps that don't have much traction

See below for an example using [Diffusion Finance's](https://diffusion.fi/) router contract:

```bash
blockxd tx gov submit-proposal register-incentive 0xFCd2Ce20ef8ed3D43Ab4f8C2dA13bbF1C6d9512F 0.050000000000000000abcx 13 --description=$DESCRIPTION --title=$PROPOSALTITLE
```

However, note that if the CLI is used to create a proposal, and `description` is set using a flag, the text will be [escaped](https://en.wikipedia.org/wiki/Escape_sequences_in_C) which may have undesired effects. If the proposal creator is using markdown or line breaks it's recommended to put the proposal text into a json file and include that file as part of the CLI proposal, as opposed to individual fields in flags.&#x20;

The CLI command for submitting the file is below:

```bash
blockxd tx gov submit-proposal register-incentive --proposal=<path_to_json>
```

You may want to submit your proposal to the testnet chain before the mainnet for a number of reasons, such as wanting to see what the proposal description will look like, to share what the proposal will look like in advance with stakeholders, and to signal that your proposal is about to go live on the mainnet.

Submitting your proposal to the testnet increases the likelihood of engagement and the possibility that you will be alerted to a flaw before deploying your proposal to mainnet.

### The On-Chain Contract Incentives Proposal <a href="#the-on-chain-contract-incentives-proposal" id="the-on-chain-contract-incentives-proposal"></a>

A majority of the voting community should probably be aware of the proposal and have considered it before the proposal goes live on-chain. If you're taking a conservative approach, you should have reasonable confidence that your proposal will pass before risking deposit contributions by submitting the proposal. Make revisions to your draft proposal after each stage of engagement.

#### The Deposit Period <a href="#the-deposit-period" id="the-deposit-period"></a>

The deposit period currently lasts 14 days. If you submitted your transaction with the minimum deposit (64 BCX), your proposal will immediately enter the voting period. If you didn't submit the minimum deposit amount (currently 64 BCX), then this may be an opportunity for others to show their support by contributing (and risking) their BCX as a bond for your proposal.&#x20;

You can request contributions openly and also contact stakeholders directly (particularly stakeholders who are enthusiastic about your proposal).

This is a stage where proposals may begin to get broader attention. Most popular explorers currently display proposals that are in the deposit period, but due to proposal spamming, this may change.

A large cross-section of the blockchain/cryptocurrency community exists on Twitter. Having your proposal in the deposit period is a good time to engage the BlockX community to prepare validators to vote and BCX-holders that are staking.

#### The Voting Period <a href="#the-voting-period" id="the-voting-period"></a>

At this point you'll want to track which validator has voted and which has not. You'll want to re-engage directly with top stake-holders, ie. the highest-ranking validator operators, to ensure that:

1. they are aware of your proposal;
2. they can ask you any questions about your proposal; and
3. they are prepared to vote.

Remember that any voter may change their vote at any time before the voting period ends. That historically doesn't happen often, but there may be an opportunity to convince a voter to change their vote. The biggest risk is that stakeholders won't vote at all (for a number of reasons). Validator operators tend to need multiple reminders to vote.&#x20;

How you choose to contact validator operators, how often, and what you say is up to you--remember that no validator is obligated to vote, and that operators are likely occupied by competing demands for their attention. Take care not to stress any potential relationship with validator operators.

### Incentives Analysis through Telemetry <a href="#incentives-analysis-through-telemetry" id="incentives-analysis-through-telemetry"></a>

#### Telemetry Basics & Setup <a href="#telemetry-basics-setup" id="telemetry-basics-setup"></a>

The telemetry package of the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) allows operators and developers to gain insight into the performance and behavior of their applications.

To enable telemetrics, set `telemetry.enabled = true` in the `app.toml` config file of the node. The Cosmos SDK currently supports enabling in-memory and [Prometheus ](https://prometheus.io/)telemetry sinks. The in-memory sink is always attached (when telemetry is enabled) with a ten second interval and one minute retention.&#x20;

This means that metrics will be aggregated over ten seconds, and metrics will be kept alive for one minute. To query active metrics, set `api.enabled = true` in the `app.toml`. This exposes a single API endpoint: `http://localhost:1317/metrics?format={text|prometheus}`, the default being `text`.

#### Incentive Metrics <a href="#incentive-metrics" id="incentive-metrics"></a>

BlockX supports the following metrics related to the `x/incentives` module, which can be collected for incentive analysis:

| Metric                                         | Description                                                                         | Unit        | Type    |
| ---------------------------------------------- | ----------------------------------------------------------------------------------- | ----------- | ------- |
| `tx_msg_ethereum_tx_incentives_total`          | Total number of txs with an incentivized contract processed via the EVM             | tx          | counter |
| `tx_msg_ethereum_tx_incentives_gas_used_total` | Total amount of gas used by txs with an incentivized contract processed via the EVM | token       | counter |
| `incentives_distribute_participant_total`      | Total number of participants who received rewards                                   | participant | counter |
| `incentives_distribute_reward_total`           | Total amount of rewards that are distributed to all incentives' participants        | token       | counter |

To calculate specific values, such as paid out incentives to a given smart contract user, custom metrics will have to be made following the above section.


# Tracing Transactions

This guide will cover the following topics:

* basic EVM tracing with JS
* filtered EVM tracing with JS
* JSON-RPC `debug_trace*` endpoints

### Basic EVM Tracing with JS <a href="#basic-evm-tracing-with-js" id="basic-evm-tracing-with-js"></a>

Tracing a transaction means requesting an BlockX node to re-execute the desired transaction with varying degrees of data collection.

Re-executing a transaction has a few prerequisites to be met. All historical state accessed by the transaction must be available, including:

* Balance, nonce, bytecode, and storage of both the recipient as well as all internally invoked contracts
* Block metadata referenced during execution of the outer as well as all internally created transactions
* Intermediate state generated by all preceding transactions contained in the same block as well as the one being traced

This means there are limits on the transactions that can be traced and imported based on the synchronization and pruning configuration of a node.

* **Archive nodes**: retain all historical data back to genesis, can trace arbitrary transactions at any point in the history of the chain.
* **Fully synced nodes**: transactions within a recent range (depending on how much history is stored) are accessible.
* **Light synced nodes**: these nodes retrieve data on demand, so in theory they can trace transactions for which all required historical state is readily available in the network (however, data availability cannot be reasonably assumed).

#### Basic Traces <a href="#basic-traces" id="basic-traces"></a>

The simplest type of transaction trace that [Geth](https://geth.ethereum.org/) can generate are raw EVM opcode traces. For every VM instruction the transaction executes, a structured log entry is emitted, contained all contextual metadata deemed useful. This includes:

* program counter
* opcode name & cost
* remaining gas
* execution depth
* occurred errors

as well as (optionally) the execution stack, execution memory, and contract storage.

The entire output of a raw EVM opcode trace is a JSON object having a few metadata fields: consumed gas, failure status, return value, and a list of opcode entries:

```json5
{
  "gas":         25523,
  "failed":      false,
  "returnValue": "",
  "structLogs":  []
}
```

An example log for a single opcode entry has the following format:

```json5
{
  "pc":      48,
  "op":      "DIV",
  "gasCost": 5,
  "gas":     64532,
  "depth":   1,
  "error":   null,
  "stack": [
    "00000000000000000000000000000000000000000000000000000000ffffffff",
    "0000000100000000000000000000000000000000000000000000000000000000",
    "2df07fbaabbe40e3244445af30759352e348ec8bebd4dd75467a9f29ec55d98d"
  ],
  "memory": [
    "0000000000000000000000000000000000000000000000000000000000000000",
    "0000000000000000000000000000000000000000000000000000000000000000",
    "0000000000000000000000000000000000000000000000000000000000000060"
  ],
  "storage": {
  }
}

```

#### Limits of Basic Traces <a href="#limits-of-basic-traces" id="limits-of-basic-traces"></a>

Although raw opcode traces generated above are useful, having an individual log entry for every single opcode is too low level for most use cases, and will require developers to create additional tools to post-process the traces. Additionally, a single opcode trace can easily be hundreds of megabytes, making them very resource intensive to extract from the node and process extenally.

To avoid these issues, [Geth ](https://geth.ethereum.org/)supports running custom JavaScript traces *within* the BlockX (or any EVM-compatible) node, which have full access to the EVM stack, memory, and contract storage. This means developers only have to gather data that they actually need, and do any processing at the source.

### Filtered EVM Tracing with JS <a href="#filtered-evm-tracing-with-js" id="filtered-evm-tracing-with-js"></a>

Basic traces can include the complete status of the EVM at every point in the transaction's execution, which is huge space-wise. Usually, developers are only interested in a small subset of this information, which can be obtained by specifying a JavaScript filter.

#### Running a Simple Trace <a href="#running-a-simple-trace" id="running-a-simple-trace"></a>

{% hint style="warning" %}
`debug.traceTransaction` must be invoked from within the [Geth](https://geth.ethereum.org/) console, although it can be invoked from outside the node using JSON-RPC (eg. using Curl), as seen in the following section. If developers want to use `debug.traceTransaction` as it is used here, maintainence of a node is required.
{% endhint %}

1. Create a file, `filterTrace_1.js`, with this content:

```javascript
tracer = function(tx) {
  return debug.traceTransaction(tx, {tracer:
      '{' +
        'retVal: [],' +
        'step: function(log,db) {this.retVal.push(log.getPC() + ":" + log.op.toString())},' +
        'fault: function(log,db) {this.retVal.push("FAULT: " + JSON.stringify(log))},' +
        'result: function(ctx,db) {return this.retVal}' +
      '}'
  }) // return debug.traceTransaction ...
}   // tracer = function ...
```

&#x20; 2\. Run the [JavaScript console](https://geth.ethereum.org/docs/interface/javascript-console).

&#x20; 3\. Get a hash of a recent transaction.

&#x20; 4\. Run this command to run the script:

```javascript
loadScript("filterTrace_1.js")
```

&#x20; 5\. Run the tracer from the script:

```javascript
tracer("<hash of transaction>")
```

The bottom of the output looks similar to:

```javascript
"3366:POP", "3367:JUMP", "1355:JUMPDEST", "1356:PUSH1", "1358:MLOAD", "1359:DUP1", "1360:DUP3", "1361:ISZERO", "1362:ISZERO",
"1363:ISZERO", "1364:ISZERO", "1365:DUP2", "1366:MSTORE", "1367:PUSH1", "1369:ADD", "1370:SWAP2", "1371:POP", "1372:POP", "1373:PUSH1",
"1375:MLOAD", "1376:DUP1", "1377:SWAP2", "1378:SUB", "1379:SWAP1", "1380:RETURN", ...
```

&#x20; 6\. Run this command to get a more readable output with each string on its own line:

```javascript
console.log(JSON.stringify(tracer("<hash of transaction>"), null, 2))
```

The JSON.stringify function's documentation is [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). If we just return the output, we get  for newlines, which is why we need to use `console.log`.

#### How Does it Work? <a href="#how-does-it-work" id="how-does-it-work"></a>

We call the same `debug.traceTransaction` function used for basic traces, but with a new parameter, `tracer`. This parameter is a string, which is the JavaScript object we use. In the case of the trace above, it is:

```javascript
{
   retVal: [],
   step: function(log,db) {this.retVal.push(log.getPC() + ":" + log.op.toString())},
   fault: function(log,db) {this.retVal.push("FAULT: " + JSON.stringify(log))},
   result: function(ctx,db) {return this.retVal}
}
```

This object has to have three member functions:

* `step`, called for each opcode
* `fault`, called if there is a problem in the execution
* `result`, called to produce the results that are returned by `debug.traceTransaction` after the execution is done

It can have additional members. In this case, we use `retVal` to store the list of strings that we'll return in `result`.

The `step` function here adds to `retVal`: the program counter, and the name of the opcode there. Then, in `result`, we return this list to be sent to the caller.

#### Actual Filtering <a href="#actual-filtering" id="actual-filtering"></a>

For actual filtered tracing, we need an `if` statement to only log revelant information. For example, if we are interested in the transaction's interaction with storage, we might use:

```javascript
tracer = function(tx) {
      return debug.traceTransaction(tx, {tracer:
      '{' +
         'retVal: [],' +
         'step: function(log,db) {' +
         '   if(log.op.toNumber() == 0x54) ' +
         '     this.retVal.push(log.getPC() + ": SLOAD");' +
         '   if(log.op.toNumber() == 0x55) ' +
         '     this.retVal.push(log.getPC() + ": SSTORE");' +
         '},' +
         'fault: function(log,db) {this.retVal.push("FAULT: " + JSON.stringify(log))},' +
         'result: function(ctx,db) {return this.retVal}' +
      '}'
      }) // return debug.traceTransaction ...
}   // tracer = function ...
```

The `step` function here looks at the opcode number of the op, and only pushes an entry if the opcode is `SLOAD` or `SSTORE`. We could have used `log.op.toString` instead, but it is faster to compare numbers rather than strings.

The output looks similar to this:

```javascript
[
  "5921: SLOAD",
  .
  .
  .
  "2413: SSTORE",
  "2420: SLOAD",
  "2475: SSTORE",
  "6094: SSTORE"
]
```

#### Stack Information <a href="#stack-information" id="stack-information"></a>

The trace above tells us the program counter and whether the program read from storage or wrote to it. To know more, you can use the `log.stack.peek` function to peek into the stack. `log.stack.peek(0)` is the stack top, `log.stack.peek(1)` is the entry beow it, etc.&#x20;

The values returned by `log.stack.peek` are Go `big.int` objects. By default they are converted to JavaScript floating point numbers, so you need toString(16) to get them as hexadecimals, which is how we normally represent 256-bit values such as storage cells and their content.

```javascript
tracer = function(tx) {
      return debug.traceTransaction(tx, {tracer:
      '{' +
         'retVal: [],' +
         'step: function(log,db) {' +
         '   if(log.op.toNumber() == 0x54) ' +
         '     this.retVal.push(log.getPC() + ": SLOAD " + ' +
         '        log.stack.peek(0).toString(16));' +
         '   if(log.op.toNumber() == 0x55) ' +
         '     this.retVal.push(log.getPC() + ": SSTORE " +' +
         '        log.stack.peek(0).toString(16) + " <- " +' +
         '        log.stack.peek(1).toString(16));' +
         '},' +
         'fault: function(log,db) {this.retVal.push("FAULT: " + JSON.stringify(log))},' +
         'result: function(ctx,db) {return this.retVal}' +
      '}'
      }) // return debug.traceTransaction ...
}   // tracer = function ...
```

```javascript
[
  "5921: SLOAD 0",
  .
  .
  .
  "2413: SSTORE 3f0af0a7a3ed17f5ba6a93e0a2a05e766ed67bf82195d2dd15feead3749a575d <- fb8629ad13d9a12456",
  "2420: SLOAD cc39b177dd3a7f50d4c09527584048378a692aed24d31d2eabeddb7f3c041870",
  "2475: SSTORE cc39b177dd3a7f50d4c09527584048378a692aed24d31d2eabeddb7f3c041870 <- 358c3de691bd19",
  "6094: SSTORE 0 <- 1"
]
```

There are several other facets of filtered EVM tracing, including:

* determining operation results
* dealing with calls between contracts
* accessing memory
* using the `db` parameter to know the state of the chain at the time of execution

### JSON-RPC `debug_trace*` Endpoints <a href="#json-rpc-debug-trace-endpoints" id="json-rpc-debug-trace-endpoints"></a>

BlockX supports the following `debug_trace*` JSON-RPC Methods, which follow Geth's debug API guidelines.

#### `debug_traceTransaction` <a href="#debug-tracetransaction" id="debug-tracetransaction"></a>

The `traceTransaction` debugging method will attempt to run the transaction in the exact same manner as it was executed on the network. It will replay any transaction that may have been executed prior to this one, before it will finally attempt to execute the transaction that corresponds to the given hash.

**Parameters**:

* trace configuration

```bash
# Request
curl -X POST --data '{"jsonrpc":"2.0","method":"debug_traceTransaction","params":[<transaction hash>, {"tracer": "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}"}],"id":1}' -H "Content-Type: application/json" https://eth.bd.blockxnet.com:8545

# Result
{"jsonrpc":"2.0","id":1,"result":[{"result":["68410", "51470"]}]}
```

#### `debug_traceBlockByHash` <a href="#debug-traceblockbyhash" id="debug-traceblockbyhash"></a>

The `traceBlockByNumber` endpoint accepts a block hash, and will replay the block that is already present in the database.

**Parameters**:

* trace configuration

```bash
# Request
curl -X POST --data '{"jsonrpc":"2.0","method":"debug_traceBlockByNumber","params":[<block hash>, {"tracer": "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}"}],"id":1}' -H "Content-Type: application/json" https://eth.bd.blockxnet.com:8545

# Result
{"jsonrpc":"2.0","id":1,"result":[{"result":["68410", "51470"]}]}
```


# Query Balances

This guide will cover the following query methods:

* `blockxd` & Tendermint RPC
* JSON-RPC
* gRPC

### `blockxd` & Tendermint RPC <a href="#evmosd-tendermint-rpc" id="evmosd-tendermint-rpc"></a>

Upon installation and configuration of the BlockX Daemon, developers can query account balances using `blockxd` with the following CLI command:

```bash
$ blockxd query bank balances $BLOCKXADDRESS --count-total=$COUNTTOTAL --height=$HEIGHT --output=$OUTPUT --node=$NODE
balances:
- amount: "1000000000000000000"
  denom: abcx
- amount: "100000"
  denom: ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518
pagination:
  next_key: null
  total: "0"
```

where:

* `$BLOCKXADDRESS` is the BlockX address with balances of interest (eg. `blockx1...`).
* (optional) `$COUNTTOTAL` counts the total number of records in all balances to query for.
* (optional) `$HEIGHT` is the specific height to query state at (can error if node is pruning state).
* (optional) `$OUTPUT` is the output format (eg. `text`).
* (optional if running local node) `$NODE` is the Tendermint RPC node information is requested from&#x20;

Details of non-native currencies (ie. not `ablockx`) can be queried with the following CLI command:

```bash
$ blockxd query erc20 token-pair $DENOM --node=$NODE --height=$HEIGHT --output=$OUTPUT
token_pair:
  contract_owner: OWNER_MODULE
  denom: ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518
  enabled: true
  erc20_address: 0xFA3C22C069B9556A4B2f7EcE1Ee3B467909f4864
```

where `$DENOM` is the denomination of the coin (eg. `ibc/ED07A3391A1...`).

### JSON-RPC <a href="#json-rpc" id="json-rpc"></a>

Developers can query account balances of `ablockx` using the `eth_getBalance` JSON-RPC method in conjunction with [`curl`](https://curl.se/):

```bash
# Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":[`$ETHADDRESS`, `$BLOCK`],"id":1}' -H "Content-Type: application/json" $NODE

# Result
{"jsonrpc":"2.0","id":1,"result":"0x36354d5575577c8000"}
```

where:

* `$ETHADDRESS` is the Etherum hex-address the balance is to be queried from. Note that BlockX addresses
* `$BLOCK` is the block number or block hash (eg. `"0x0"`). The reasoning for this parameter is due to [EIP-1898](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md).
* (optional if running local node) `$NODE` is the JSON-RPC node information is requested from&#x20;

Developers can also query account balances of `x/erc20`-module registered coins using the `eth_call` JSON-RPC method in conjunction with [`curl`](https://curl.se/):

```bash
# Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_call","params":[{"from":`SENDERCONTRACTADDRESS`, "to":`ERCCONTRACTADDRESS`, "data":`$DATA`}, `$BLOCK`],"id":1}'  -H "Content-Type: application/json" $NODE

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

where:

* `$SENDERCONTRACTADDRESS` is the Ethereum hex-address this smart contract call is sent from.
* `$ERCCONTRACTADDRESS` is the Ethereum hex-address of the ERC-20 contract corresponding to the coin denomination being queried.
* `$DATA` is the hash of the [`balanceof` ](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#ERC20)method signature and encoded parameters. `balanceOf` is a required method in every ERC-20 contract, and the encoded parameter is the address which is having its balance queried. For additional information, see the [Ethereum Contract ABI](https://docs.soliditylang.org/en/v0.8.13/abi-spec.html).
* `$BLOCK` is the block number or block hash (eg. `"0x0"`). The reasoning for this parameter is due to [EIP-1898](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md).
* (optional if running local node) `$NODE` is the JSON-RPC node information is requested from&#x20;

### gRPC <a href="#grpc" id="grpc"></a>

Developers can use [`grpcurl`](https://github.com/fullstorydev/grpcurl) with the `AllBalances` endpoint to query account balance by address for all denominations:

```bash
# Request
grpcurl $OUTPUT -d '{"address":`$BLOCKXADDRESS`}' $NODE cosmos.bank.v1beta1.Query/AllBalances

# Result
{
  "balances": [
    {
      "denom": "stake",
      "amount": "1000000000"
    }
  ],
  "pagination": {
    "total": "1"
  }
}
```

where:

* `$BCXADDRESS` is the BlockX address with balances of interest (eg. `"blockx1..."`).
* `$NODE` is the Cosmos gRPC node information is requested&#x20;
* (optional) `$OUTPUT` is the output format (eg. `plaintext`).

State can also be queried using gRPC within a Go program. The idea is to create a gRPC connection, then use the [Protobuf](https://developers.google.com/protocol-buffers)-generated client code to query the gRPC server.

```go
import (
    "context"
    "fmt"

  "google.golang.org/grpc"

    sdk "github.com/cosmos/cosmos-sdk/types"
  "github.com/cosmos/cosmos-sdk/types/tx"
)

func queryState() error {
    myAddress, err := GetBlockXAddressFromBech32("blockx1...") // blockx address with balances of interest.
    if err != nil {
        return err
    }

    // Create a connection to the gRPC server.
    grpcConn := grpc.Dial(
        "https://grpc.bd.blockxnet.com:9090", // your gRPC server address.
        grpc.WithInsecure(), // the SDK doesn't support any transport security mechanism.
    )
    defer grpcConn.Close()

    // This creates a gRPC client to query the x/bank service.
    bankClient := banktypes.NewQueryClient(grpcConn)
    bankRes, err := bankClient.AllBalances(
        context.Background(),
        &banktypes.QueryAllBalancesRequest{Address: myAddress},
    )
    if err != nil {
        return err
    }

    fmt.Println(bankRes.GetBalances()) // prints the account balances.

    return nil
}
```


# Localnet


# Single-node

### Automated Localnet (script) <a href="#automated-localnet-script" id="automated-localnet-script"></a>

You can customize the local testnet script by changing values for convenience for example:

```bash
# customize the name of your key, the chain-id, moniker of the node, keyring backend, and log level
KEY="mykey"
CHAINID="blockx_9000-4"
MONIKER="localtestnet"
KEYRING="test"
LOGLEVEL="info"


# Allocate genesis accounts (cosmos formatted addresses)
blockxd add-genesis-account $KEY 100000000000000000000000000ablockx --keyring-backend $KEYRING

# Sign genesis transaction
blockxd gentx $KEY 1000000000000000000000ablockx --keyring-backend $KEYRING --chain-id $CHAINID
```

The default configuration will generate a single validator localnet with the chain-id `blockxd-1` and one predefined account (`mykey`) with some allocated funds at the genesis.

You can start the local chain using:

```bash
init.sh
```

### Manual Localnet <a href="#manual-localnet" id="manual-localnet"></a>

This guide helps you create a single validator node that runs a network locally for testing and other development related uses.

#### Initialize the chain <a href="#initialize-the-chain" id="initialize-the-chain"></a>

Before actually running the node, we need to initialize the chain, and most importantly its genesis file. This is done with the `init` subcommand:

```bash
$MONIKER=testing
$KEY=mykey
$CHAINID="blockx_9000-4"

# The argument $MONIKER is the custom username of your node, it should be human-readable.
blockxd init $MONIKER --chain-id=$CHAINID
```

{% hint style="info" %}
You can edit this `moniker` later by updating the `config.toml` file.
{% endhint %}

The command above creates all the configuration files needed for your node and validator to run, as well as a default genesis file, which defines the initial state of the network. All these configuration files are in `~/.blockxd` by default, but you can overwrite the location of this folder by passing the `--home` flag.

### Genesis Procedure <a href="#genesis-procedure" id="genesis-procedure"></a>

#### Adding Genesis Accounts <a href="#adding-genesis-accounts" id="adding-genesis-accounts"></a>

Before starting the chain, you need to populate the state with at least one account using the keyring:

```bash
blockxd keys add my_validator
```

Once you have created a local account, go ahead and grant it some `ablockx` tokens in your chain's genesis file. Doing so will also make sure your chain is aware of this account's existence:

```bash
blockxd add-genesis-account my_validator 10000000000ablockx
```

Now that your account has some tokens, you need to add a validator to your chain.

For this guide, you will add your local node (created via the `init` command above) as a validator of your chain. Validators can be declared before a chain is first started via a special transaction included in the genesis file called a `gentx`:

```bash
# Create a gentx
# NOTE: this command lets you set the number of coins. 
# Make sure this account has some coins with the genesis.app_state.staking.params.bond_denom denom
blockxd add-genesis-account my_validator 1000000000stake,10000000000ablockx
```

A `gentx` does three things:

1. Registers the `validator` account you created as a validator operator account (i.e. the account that controls the validator).
2. Self-delegates the provided `amount` of staking tokens.
3. Link the operator account with a Tendermint node pubkey that will be used for signing blocks. If no `--pubkey` flag is provided, it defaults to the local node pubkey created via the `blockxd init` command above.

For more information on `gentx`, use the following command:

```bash
blockxd gentx --help
```

#### Collecting `gentx` <a href="#collecting-gentx" id="collecting-gentx"></a>

By default, the genesis file do not contain any `gentxs`. A `gentx` is a transaction that bonds staking token present in the genesis file under `accounts` to a validator, essentially creating a validator at genesis. The chain will start as soon as more than 2/3rds of the validators (weighted by voting power) that are the recipient of a valid `gentx` come online after `genesis_time`.

A `gentx` can be added manually to the genesis file, or via the following command:

```bash
# Add the gentx to the genesis file
blockxd collect-gentxs
```

This command will add all the `gentxs` stored in `~/.blockxd/config/gentx` to the genesis file.

#### Run Testnet <a href="#run-testnet" id="run-testnet"></a>

Finally, check the correctness of the `genesis.json` file:

```bash
blockxd validate-genesis
```

Now that everything is set up, you can finally start your node:

```bash
blockxd start
```

{% hint style="info" %}
To check all the available customizable options when running the node, use the `--help` flag.
{% endhint %}

You should see blocks come in.

The previous command allow you to run a single node. This is enough for the next section on interacting with this node, but you may wish to run multiple nodes at the same time, and see how consensus happens between them.

You can then stop the node using `Ctrl+C`.


# Multi-node

### Automated Localnet with Ignite CLI <a href="#automated-localnet-with-ignite-cli" id="automated-localnet-with-ignite-cli"></a>

Once you have installed `ignite`, just run the localnet by using

```bash
ignite chain serve 
```

Detailed instructions can be found in the [Ignite CLI documentation](https://docs.ignite.com/kb/serve.html).

### Automated Localnet with Docker <a href="#automated-localnet-with-docker" id="automated-localnet-with-docker"></a>

#### Build & Start <a href="#build-start" id="build-start"></a>

To build start a 4 node testnet run:

```bash
make localnet-start
```

This command creates a 4-node network using the `blockxdnode` Docker image. The ports for each node are found in this table:

| Node ID       | P2P Port | Tendermint RPC Port | REST/ Ethereum JSON-RPC Port | WebSocket Port |
| ------------- | -------- | ------------------- | ---------------------------- | -------------- |
| `blockxnode0` | `26656`  | `26657`             | `8545`                       | `8546`         |
| `blockxnode1` | `26659`  | `26660`             | `8547`                       | `8548`         |
| `blockxnode2` | `26661`  | `26662`             | `8549`                       | `8550`         |
| `node3`       | `26663`  | `26664`             | `8551`                       | `8552`         |

To update the binary, just rebuild it and restart the nodes:

```bash
make localnet-start
```

The command above command will run containers in the background using Docker compose. You will see the network being created:

```
...
Creating network "blockx_localnet" with driver "bridge"
Creating blockxdnode0 ... done
Creating blockxdnode2 ... done
Creating blockxdnode1 ... done
Creating blockxdnode3 ... done
```

#### Stop Localnet <a href="#stop-localnet" id="stop-localnet"></a>

Once you are done, execute:

```bash
make localnet-stop
```

#### Configuration <a href="#configuration" id="configuration"></a>

The `make localnet-start` creates files for a 4-node testnet in `./build` by calling the `blockxd testnet` command. This outputs a handful of files in the `./build` directory:

```bash
tree -L 3 build/

build/
├── blockxd
├── blockxd
├── gentxs
│   ├── node0.json
│   ├── node1.json
│   ├── node2.json
│   └── node3.json
├── node0
│   ├── blockxd
│   │   ├── key_seed.json
│   │   └── keyring-test-cosmos
│   └── blockxd
│       ├── config
│       ├── data
│       └── blockxd.log
├── node1
│   ├── blockxd
│   │   ├── key_seed.json
│   │   └── keyring-test-cosmos
│   └── blockxd
│       ├── config
│       ├── data
│       └── blockxd.log
├── node2
│   ├── blockxd
│   │   ├── key_seed.json
│   │   └── keyring-test-cosmos
│   └── blockxd
│       ├── config
│       ├── data
│       └── blockxd.log
└── node3
    ├── blockxd
    │   ├── key_seed.json
    │   └── keyring-test-cosmos
    └── blockxd
        ├── config
        ├── data
        └── blockxd.log
```

Each `./build/nodeN` directory is mounted to the `/blockxd` directory in each container.

#### Logging <a href="#logging" id="logging"></a>

In order to see the logs of a particular node you can use the following command:

```bash
# node 0: daemon logs
docker exec blockxdnode0 tail blockxd.log

# node 0: REST & RPC logs
docker exec blockxdnode0 tail blockxd.log
```

The logs for the daemon will look like:

```
I[2020-07-29|17:33:52.452] starting ABCI with Tendermint                module=main
E[2020-07-29|17:33:53.394] Can't add peer's address to addrbook         module=p2p err="Cannot add non-routable address 272a247b837653cf068d39efd4c407ffbd9a0e6f@192.168.10.5:26656"
E[2020-07-29|17:33:53.394] Can't add peer's address to addrbook         module=p2p err="Cannot add non-routable address 3e05d3637b7ebf4fc0948bbef01b54d670aa810a@192.168.10.4:26656"
E[2020-07-29|17:33:53.394] Can't add peer's address to addrbook         module=p2p err="Cannot add non-routable address 689f8606ede0b26ad5b79ae244c14cc67ab4efe7@192.168.10.3:26656"
I[2020-07-29|17:33:58.828] Executed block                               module=state height=88 validTxs=0 invalidTxs=0
I[2020-07-29|17:33:58.830] Committed state                              module=state height=88 txs=0 appHash=90CC5FA53CF8B5EC49653A14DA20888AD81C92FCF646F04D501453FD89FCC791
I[2020-07-29|17:34:04.032] Executed block                               module=state height=89 validTxs=0 invalidTxs=0
I[2020-07-29|17:34:04.034] Committed state                              module=state height=89 txs=0 appHash=0B54C4DB1A0DACB1EEDCD662B221C048C826D309FD2A2F31FF26BAE8D2D7D8D7
I[2020-07-29|17:34:09.381] Executed block                               module=state height=90 validTxs=0 invalidTxs=0
I[2020-07-29|17:34:09.383] Committed state                              module=state height=90 txs=0 appHash=75FD1EE834F0669D5E717C812F36B21D5F20B3CCBB45E8B8D415CB9C4513DE51
I[2020-07-29|17:34:14.700] Executed block                               module=state height=91 validTxs=0 invalidTxs=0
```

{% hint style="info" %}
You can disregard the `Can't add peer's address to addrbook` warning. As long as the blocks are being produced and the app hashes are the same for each node, there should not be any issues.
{% endhint %}

Whereas the logs for the REST & RPC server would look like:

```
I[2020-07-30|09:39:17.488] Starting application REST service (chain-id: "7305661614933169792")... module=rest-server
I[2020-07-30|09:39:17.488] Starting RPC HTTP server on 127.0.0.1:8545   module=rest-server
...
```

**Follow Logs**

You can also watch logs as they are produced via Docker with the `--follow` (`-f`) flag, for example:

```bash
docker logs -f blockxdnode0
```

#### Interact with the Localnet <a href="#interact-with-the-localnet" id="interact-with-the-localnet"></a>

**Ethereum JSON-RPC & Websocket Ports**

To interact with the testnet via WebSockets or RPC/API, you will send your request to the corresponding ports:

| EVM JSON-RPC | Eth Websocket |
| ------------ | ------------- |
| `8545`       | `8546`        |

You can send a curl command such as:

```bash
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' -H "Content-Type: application/json" 192.162.10.1:8545
```

{% hint style="info" %}
The IP address will be the public IP of the docker container.
{% endhint %}

#### Keys & Accounts <a href="#keys-accounts" id="keys-accounts"></a>

To interact with `blockxd` and start querying state or creating txs, you use the `blockxd` directory of any given node as your `home`, for example:

```bash
blockxd keys list --home ./build/node0/blockxd
```

Now that accounts exists, you may create new accounts and send those accounts funds!

{% hint style="info" %}
Each node's seed is located at `./build/nodeN/blockxd/key_seed.json` and can be restored to the CLI using the `blockxd keys add --restore` command
{% endhint %}

#### Special Binaries <a href="#special-binaries" id="special-binaries"></a>

If you have multiple binaries with different names, you can specify which one to run with the BINARY environment variable. The path of the binary is relative to the attached volume. For example:

```bash
# Run with custom binary
BINARY=blockx make localnet-start
```


# Testnet


# Testnet Commands

In addition to the commands for running a node, the `blockxd` binary also includes a `testnet` command that allows you to start a simulated test network in-process or to initialize files for a simulated test network that runs in a separate process.

### Initialize Files <a href="#initialize-files" id="initialize-files"></a>

The `init-files` subcommand initializes the necessary files to run a test network in a separate process (i.e. using a Docker container). Running this command is not a prerequisite for the `start` subcommand.

This is similar to the `init` command when initializing a single node, but in this case we are initializing multiple nodes, generating the genesis transactions for each node, and then collecting those transactions.

In order to initialize the files for a test network, run the following command:

```bash
blockxd testnet init-files
```

You should see the following output in your terminal:

```
Successfully initialized 4 node directories
```

The default output directory is a relative `.testnets` directory. Let's take a look at the files created within the `.testnets` directory.

### Gentxs <a href="#gentxs" id="gentxs"></a>

The `gentxs` directory includes a genesis transaction for each validator node. Each file includes a JSON encoded genesis transaction used to register a validator node at the time of genesis. The genesis transactions are added to the `genesis.json` file within each node directory during the initialization process.

### Nodes <a href="#nodes" id="nodes"></a>

A node directory is created for each validator node. Within each node directory is a `blockxd` directory. The `blockxd` directory is the home directory for each node, which includes the configuration and data files for that node (i.e. the same files included in the default `~/.blockxd` directory when running a single node).

### Start Testnet <a href="#start-testnet" id="start-testnet"></a>

The `start` subcommand both initializes and starts an in-process test network. This is the fastest way to spin up a local test network for testing purposes.

You can start the local test network by running the following command:

```bash
blockxd testnet start
```

You should see something similar to the following:

```
acquiring test network lock
preparing test network with chain-id "blockx_1276974-1"


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++       THIS MNEMONIC IS FOR TESTING PURPOSES ONLY        ++
++                DO NOT USE IN PRODUCTION                 ++
++                                                         ++
++  sustain know debris minute gate hybrid stereo custom   ++
++  divorce cross spoon machine latin vibrant term oblige  ++
++   moment beauty laundry repeat grab game bronze truly   ++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


starting test network...
started test network
press the Enter Key to terminate
```

The first validator node is now running in-process, which means the test network will terminate once you either close the terminal window or you press the Enter key.&#x20;

In the output, the mnemonic phrase for the first validator node is provided for testing purposes. The validator node is using the same default addresses being used when initializing and starting a single node (no need to provide a `--node` flag).

Check the status of the first validator node:

```bash
blockxd status
```

Import the key from the provided mnemonic:

```bash
blockxd keys add test --recover
```

Check the balance of the account address:

```bash
blockxd q bank balances [address]
```

Use this test account to manually test against the test network.

### Testnet Options <a href="#testnet-options" id="testnet-options"></a>

You can customize the configuration of the test network with flags. In order to see all flag options, append the `--help` flag to each command.


# Ethereum JSON-RPC


# JSON-RPC Server

The JSON-PRC Server provides an API that allows you to connect to the BlockX blockchain and interact with the EVM. This gives you direct access to reading Ethereum-formatted transactions or sending them to the network which otherwise wouldn't be possible on a Cosmos chain, such as BlockX.

[JSON-RPC](http://www.jsonrpc.org/specification) is a stateless, light-weight remote procedure call (RPC) protocol. It 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](https://www.ietf.org/rfc/rfc4627.txt)) as data format.

JSON-RPC is provided on multiple transports. BlockX supports JSON-RPC over HTTP and WebSocket. Transports must be enabled through command-line flags or through the `app.toml` configuration file.

### Web3 Support <a href="#web3-support" id="web3-support"></a>

BlockX supports all standard web3 JSON-RPC APIs. You can find documentation for these APIs on the `JSON-RPC Methods` page.

Ethereum JSON-RPC APIs use a name-space system. RPC methods are grouped into several categories depending on their purpose.&#x20;

All method names are composed of the namespace, an underscore, and the actual method name within the namespace. For example, the eth\_call method resides in the eth namespace. Access to RPC methods can be enabled on a per-namespace basis.&#x20;

### HEX value encoding <a href="#hex-value-encoding" id="hex-value-encoding"></a>

At present there are two key datatypes that are passed over JSON:

* **quantities** and
* **unformatted byte arrays**.

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`)

### Default block parameter <a href="#default-block-parameter" id="default-block-parameter"></a>

The following methods have an extra default block parameter:

* `eth_getBalance`
* `eth_getCode`
* `eth_getTransactionCount`
* `eth_getStorageAt`
* `eth_call`

When requests are made that act on the state of BlockX, 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 <a href="#curl-examples-explained" id="curl-examples-explained"></a>

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`


# Running the Server

### Enable Server <a href="#enable-server" id="enable-server"></a>

To enable RPC server use the following flag (set to true by default).

```bash
blockxd start --json-rpc.enable
```

### Defining Namespaces <a href="#defining-namespaces" id="defining-namespaces"></a>

`Eth`,`Net` and `Web3` namespaces are enabled by default. In order to enable other namespaces use flag `--json-rpc.api`.

```bash
blockxd start --json-rpc.api eth,txpool,personal,net,debug,web3,miner
```

### Set a Gas Cap <a href="#set-a-gas-cap" id="set-a-gas-cap"></a>

`eth_call` and `eth_estimateGas` define a global gas cap over rpc for DoS protection. You can override the default gas cap value of 25,000,000 by passing a custom value when starting the node:

```bash
# set gas cap to 85M
blockxd start --json-rpc.gas-cap 85000000000

# set gas cap to infinite (=0)
blockxd start --json-rpc.gas-cap 0
```

### CORS <a href="#cors" id="cors"></a>

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.

The CORS setting can be updated from the `app.toml`:

```
###############################################################################
###                           API Configuration                             ###
###############################################################################

[api]

# ...

# EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk).
enabled-unsafe-cors = true # default false
```


# Namespaces

### Ethereum Namespaces <a href="#ethereum-namespaces" id="ethereum-namespaces"></a>

|            |                                                                                                                                                                                                                              |   | Enabled by Default |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | ------------------ |
| `eth`      | BlockX provides several extensions to the standard `eth` JSON-RPC namespace.                                                                                                                                                 | ✔ | ✔                  |
| `web3`     | The `web3` API provides utility functions for the web3 client.                                                                                                                                                               | ✔ | ✔                  |
| `net`      | The `net` API provides access to network information of the node                                                                                                                                                             | ✔ | ✔                  |
| `clique`   | The `clique` API provides access to the state of the clique consensus engine. You can use this API to manage signer votes and to check the health of a private network.                                                      | ❌ |                    |
| `debug`    | The `debug` API gives you access to several non-standard RPC methods, which will allow you to inspect, debug and set certain debugging flags during runtime.                                                                 | ✔ |                    |
| `les`      | The `les` API allows you to manage LES server settings, including client parameters and payment settings for prioritized clients. It also provides functions to query checkpoint information in both server and client mode. | ❌ |                    |
| `miner`    | The `miner` API allows you to remote control the node’s mining operation and set various mining specific settings.                                                                                                           | ✔ | ❌                  |
| `txpool`   | The `txpool` API gives you access to several non-standard RPC methods to inspect the contents of the transaction pool containing all the currently pending transactions as well as the ones queued for future processing.    | ✔ | ❌                  |
| `admin`    | The `admin` API gives you access to several non-standard RPC methods, which will allow you to have a fine grained control over your nodeinstance, including but not limited to network peer and RPC endpoint management.     | ❌ |                    |
| `personal` | The `personal` API manages private keys in the key store.                                                                                                                                                                    | ✔ | ❌                  |


# JSON-RPC Methods

### Endpoints

| Method                                    | Namespace | Implemented | Public | Notes              |
| ----------------------------------------- | --------- | ----------- | ------ | ------------------ |
| `web3_clientVersion`                      | Web3      | ✔           | ✔      |                    |
| `web3_sha3`                               | Web3      | ✔           | ✔      |                    |
| `net_version`                             | Net       | ✔           | ✔      |                    |
| `net_peerCount`                           | Net       | ✔           | ✔      |                    |
| `net_listening`                           | Net       | ✔           | ✔      |                    |
| `eth_protocolVersion`                     | Eth       | ✔           | ✔      |                    |
| `eth_syncing`                             | Eth       | ✔           | ✔      |                    |
| `eth_gasPrice`                            | Eth       | ✔           | ✔      |                    |
| `eth_accounts`                            | Eth       | ✔           | ✔      |                    |
| `eth_blockNumber`                         | Eth       | ✔           | ✔      |                    |
| `eth_getBalance`                          | Eth       | ✔           | ✔      |                    |
| `eth_getStorageAt`                        | Eth       | ✔           | ✔      |                    |
| `eth_getTransactionCount`                 | Eth       | ✔           | ✔      |                    |
| `eth_getBlockTransactionCountByNumber`    | Eth       | ✔           | ✔      |                    |
| `eth_getBlockTransactionCountByHash`      | Eth       | ✔           | ✔      |                    |
| `eth_getCode`                             | Eth       | ✔           | ✔      |                    |
| `eth_sign`                                | Eth       | ✔           | ✔      |                    |
| `eth_sendTransaction`                     | Eth       | ✔           | ✔      |                    |
| `eth_sendRawTransaction`                  | Eth       | ✔           | ✔      |                    |
| `eth_call`                                | Eth       | ✔           | ✔      |                    |
| `eth_estimateGas`                         | Eth       | ✔           | ✔      |                    |
| `eth_getBlockByNumber`                    | Eth       | ✔           | ✔      |                    |
| `eth_getBlockByHash`                      | Eth       | ✔           | ✔      |                    |
| `eth_getTransactionByHash`                | Eth       | ✔           | ✔      |                    |
| `eth_getTransactionByBlockHashAndIndex`   | Eth       | ✔           | ✔      |                    |
| `eth_getTransactionReceipt`               | Eth       | ✔           | ✔      |                    |
| `eth_newFilter`                           | Eth       | ✔           | ✔      |                    |
| `eth_newBlockFilter`                      | Eth       | ✔           | ✔      |                    |
| `eth_newPendingTransactionFilter`         | Eth       | ✔           | ✔      |                    |
| `eth_uninstallFilter`                     | Eth       | ✔           | ✔      |                    |
| `eth_getFilterChanges`                    | Eth       | ✔           | ✔      |                    |
| `eth_getFilterLogs`                       | Eth       | ✔           | ✔      |                    |
| `eth_getLogs`                             | Eth       | ✔           | ✔      |                    |
| `eth_getTransactionbyBlockNumberAndIndex` | Eth       |             | ✔      |                    |
| `eth_getWork`                             | Eth       | N/A         | ✔      | PoW-only           |
| `eth_submitWork`                          | Eth       | N/A         | ✔      | PoW-only           |
| `eth_submitHashrate`                      | Eth       |             |        |                    |
| `eth_getCompilers`                        | Eth       |             |        |                    |
| `eth_compileLLL`                          | Eth       |             |        |                    |
| `eth_compileSolidity`                     | Eth       |             |        |                    |
| `eth_compileSerpent`                      | Eth       |             |        |                    |
| `eth_signTransaction`                     | Eth       |             |        |                    |
| `eth_mining`                              | Eth       |             | ❌      |                    |
| `eth_coinbase`                            | Eth       | ✔           |        |                    |
| `eth_hashrate`                            | Eth       | N/A         | ❌      | PoW-only           |
| `eth_getUncleCountByBlockHash`            | Eth       | N/A         |        | PoW-only           |
| `eth_getUncleCountByBlockNumber`          | Eth       | N/A         |        | PoW-only           |
| `eth_getUncleByBlockHashAndIndex`         | Eth       | N/A         |        | PoW-only           |
| `eth_getUncleByBlockNumberAndIndex`       | Eth       | N/A         |        | PoW-only           |
| `eth_getProof`                            | Eth       | ✔           |        |                    |
| `eth_subscribe`                           | Websocket | ✔           |        |                    |
| `eth_unsubscribe`                         | Websocket | ✔           |        |                    |
| `personal_importRawKey`                   | Personal  | ✔           | ❌      |                    |
| `personal_listAccounts`                   | Personal  | ✔           | ❌      |                    |
| `personal_lockAccount`                    | Personal  | ✔           | ❌      |                    |
| `personal_newAccount`                     | Personal  | ✔           | ❌      |                    |
| `personal_unlockAccount`                  | Personal  | ✔           | ❌      |                    |
| `personal_sendTransaction`                | Personal  | ✔           | ❌      |                    |
| `personal_sign`                           | Personal  | ✔           | ❌      |                    |
| `personal_ecRecover`                      | Personal  | ✔           | ❌      |                    |
| `personal_initializeWallet`               | Personal  | ✔           | ❌      |                    |
| `personal_unpair`                         | Personal  | ✔           | ❌      |                    |
| `db_putString`                            | DB        |             |        |                    |
| `db_getString`                            | DB        |             |        | ❌                  |
| `db_putHex`                               | DB        |             |        |                    |
| `db_getHex`                               | DB        |             |        |                    |
| `shh_post`                                | SSH       |             |        |                    |
| `shh_version`                             | SSH       |             |        |                    |
| `shh_newIdentity`                         | SSH       |             |        |                    |
| `shh_hasIdentity`                         | SSH       |             |        |                    |
| `shh_newGroup`                            | SSH       |             |        |                    |
| `shh_addToGroup`                          | SSH       |             |        |                    |
| `shh_newFilter`                           | SSH       |             |        |                    |
| `shh_uninstallFilter`                     | SSH       |             |        |                    |
| `shh_getFilterChanges`                    | SSH       |             |        |                    |
| `shh_getMessages`                         | SSH       |             |        |                    |
| `admin_addPeer`                           | Admin     | ❌           |        |                    |
| `admin_datadir`                           | Admin     | ❌           |        |                    |
| `admin_nodeInfo`                          | Admin     | ❌           |        |                    |
| `admin_peers`                             | Admin     | ❌           |        |                    |
| `admin_startRPC`                          | Admin     | ❌           |        |                    |
| `admin_startWS`                           | Admin     | ❌           |        |                    |
| `admin_stopRPC`                           | Admin     | ❌           |        |                    |
| `admin_stopWS`                            | Admin     | ❌           |        |                    |
| `clique_getSnapshot`                      | Clique    |             |        |                    |
| `clique_getSnapshotAtHash`                | Clique    |             |        |                    |
| `clique_getSigners`                       | Clique    |             |        |                    |
| `clique_proposals`                        | Clique    |             |        |                    |
| `clique_propose`                          | Clique    |             |        |                    |
| `clique_discard`                          | Clique    |             |        |                    |
| `clique_status`                           | Clique    |             |        |                    |
| `debug_backtraceAt`                       | Debug     |             |        |                    |
| `debug_blockProfile`                      | Debug     | ✔           |        |                    |
| `debug_cpuProfile`                        | Debug     | ✔           |        |                    |
| `debug_dumpBlock`                         | Debug     |             |        |                    |
| `debug_gcStats`                           | Debug     | ✔           |        |                    |
| `debug_getBlockRlp`                       | Debug     |             |        |                    |
| `debug_goTrace`                           | Debug     | ✔           |        |                    |
| `debug_freeOSMemory`                      | Debug     | ✔           |        |                    |
| `debug_memStats`                          | Debug     | ✔           |        |                    |
| `debug_mutexProfile`                      | Debug     | ✔           |        |                    |
| `debug_seedHash`                          | Debug     |             |        |                    |
| `debug_setHead`                           | Debug     |             |        |                    |
| `debug_setBlockProfileRate`               | Debug     | ✔           |        |                    |
| `debug_setGCPercent`                      | Debug     | ✔           |        |                    |
| `debug_setMutexProfileFraction`           | Debug     | ✔           |        |                    |
| `debug_stacks`                            | Debug     | ✔           |        |                    |
| `debug_startCPUProfile`                   | Debug     | ✔           |        |                    |
| `debug_startGoTrace`                      | Debug     | ✔           |        |                    |
| `debug_stopCPUProfile`                    | Debug     | ✔           |        |                    |
| `debug_stopGoTrace`                       | Debug     | ✔           |        |                    |
| `debug_traceBlock`                        | Debug     | ✔           |        |                    |
| `debug_traceBlockByNumber`                | Debug     | ✔           |        |                    |
| `debug_traceBlockByHash`                  | Debug     | ✔           |        |                    |
| `debug_traceBlockFromFile`                | Debug     |             |        |                    |
| `debug_standardTraceBlockToFile`          | Debug     |             |        |                    |
| `debug_standardTraceBadBlockToFile`       | Debug     |             |        |                    |
| `debug_traceTransaction`                  | Debug     | ✔           |        |                    |
| `debug_verbosity`                         | Debug     |             |        |                    |
| `debug_vmodule`                           | Debug     |             |        |                    |
| `debug_writeBlockProfile`                 | Debug     | ✔           |        |                    |
| `debug_writeMemProfile`                   | Debug     | ✔           |        |                    |
| `debug_writeMutexProfile`                 | Debug     | ✔           |        |                    |
| `les_serverInfo`                          | Les       |             |        |                    |
| `les_clientInfo`                          | Les       |             |        |                    |
| `les_priorityClientInfo`                  | Les       |             |        |                    |
| `les_addBalance`                          | Les       |             |        |                    |
| `les_setClientParams`                     | Les       |             |        |                    |
| `les_setDefaultParams`                    | Les       |             |        |                    |
| `les_latestCheckpoint`                    | Les       |             |        |                    |
| `les_getCheckpoint`                       | Les       |             |        |                    |
| `les_getCheckpointContractAddress`        | Les       |             |        |                    |
| `miner_getHashrate`                       | Miner     | ✔           | ❌      | No-op              |
| `miner_setExtra`                          | Miner     | ✔           | ❌      | No-op              |
| `miner_setGasPrice`                       | Miner     | ✔           | ❌      | Needs node restart |
| `miner_start`                             | Miner     | ✔           | ❌      | No-op              |
| `miner_stop`                              | Miner     | ✔           | ❌      | No-op              |
| `miner_setGasLimit`                       | Miner     | ✔           | ❌      | No-op              |
| `miner_setEtherbase`                      | Miner     | ✔           | ❌      |                    |
| `txpool_content`                          | TxPool    | ✔           |        |                    |
| `txpool_inspect`                          | TxPool    | ✔           |        |                    |
| `txpool_status`                           | TxPool    | ✔           |        |                    |

{% hint style="info" %}
Block Number can be entered as a Hex string, `"earliest"`, `"latest"` or `"pending"`.
{% endhint %}

Below is a list of the RPC methods, the parameters and an example response from the namespaces.

### Web3 Methods <a href="#web3-methods" id="web3-methods"></a>

#### `web3_clientVersion` <a href="#web3-clientversion" id="web3-clientversion"></a>

Get the web3 client version.

**Parameters (0)**

**Result**

```bash
 {"jsonrpc":"2.0","id":1,"result":"BlockX/0.1.3+/linux/go1.18"}
```

**Client Examples**

:::: tabs ::: tab Shell HTTP

```bash
curl -X POST -H "Content-Type: application/json" http://localhost:8545 --data '{"jsonrpc": "2.0", "id": 42, "method": "web3_clientVersion", "params": []}'
```

::: ::: tab Shell WebSocket

```bash
wscat -c ws://localhost:8546 -x '{"jsonrpc": "2.0", "id": 1, "method": "web3_clientVersion", "params": []}'
```

::: ::: tab Javascript Console

```javascript
web3.clientVersion();
```

#### `web3_sha3` <a href="#web3-sha3" id="web3-sha3"></a>

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

**Parameters (1)**

1: input `hexutil.Bytes`

* Required: ✓ Yes

**Result**

```bash
{"jsonrpc":"2.0","id":1,"result":"0x1b84adea42d5b7d192fd8a61a85b25abe0757e9a65cab1da470258914053823f"}
```

**Client Examples**

:::: tabs ::: tab Shell HTTP

```bash
curl -X POST -H "Content-Type: application/json" http://localhost:8545 --data '{"jsonrpc": "2.0", "id": 42, "method": "web3_sha3", "params": [<input>]}'
```

::: ::: tab Shell WebSocket

```bash
wscat -c ws://localhost:8546 -x '{"jsonrpc": "2.0", "id": 1, "method": "web3_sha3", "params": [<input>]}'
```

::: ::: tab Javascript Console

```javascript
web3.sha3(input);
```

::: ::::

### Net Methods <a href="#net-methods" id="net-methods"></a>

#### `net_version` <a href="#net-version" id="net-version"></a>

Returns the current network id.

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

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

#### `net_peerCount` <a href="#net-peercount" id="net-peercount"></a>

Returns the number of peers currently connected to the client.

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

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

### Eth Methods <a href="#eth-methods" id="eth-methods"></a>

#### `eth_protocolVersion` <a href="#eth-protocolversion" id="eth-protocolversion"></a>

Returns the current ethereum protocol version.

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

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

#### `eth_syncing` <a href="#eth-syncing" id="eth-syncing"></a>

The sync status object may need to be different depending on the details of Tendermint's sync protocol. However, the 'synced' result is simply a boolean, and can easily be derived from Tendermint's internal sync state.

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

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

#### `eth_gasPrice` <a href="#eth-gasprice" id="eth-gasprice"></a>

Returns the current gas price in the default EVM denomination parameter.

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

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

#### `eth_accounts` <a href="#eth-accounts" id="eth-accounts"></a>

Returns array of all eth accounts.

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

// Result
{"jsonrpc":"2.0","id":1,"result":["0x3b7252d007059ffc82d16d022da3cbf9992d2f70","0xddd64b4712f7c8f1ace3c145c950339eddaf221d","0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0"]}
```

#### `eth_blockNumber` <a href="#eth-blocknumber" id="eth-blocknumber"></a>

Returns the current block height.

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

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

#### `eth_getBalance` <a href="#eth-getbalance" id="eth-getbalance"></a>

Returns the account balance for a given account address and Block Number.

**Parameters**

* Account Address
* Block Number or Block Hash ([EIP-1898](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md))

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0", "0x0"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_getStorageAt` <a href="#eth-getstorageat" id="eth-getstorageat"></a>

Returns the storage address for a given account address.

**Parameters**

* Account Address
* Integer of the position in the storage
* Block Number or Block Hash ([EIP-1898](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md))

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getStorageAt","params":["0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0", "0", `"latest"`],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_getTransactionCount` <a href="#eth-gettransactioncount" id="eth-gettransactioncount"></a>

Returns the total transaction for a given account address and Block Number.

**Parameters**

* Account Address
* Block Number or Block Hash ([EIP-1898](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md))

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0x7bf7b17da59880d9bcca24915679668db75f9397", "0x0"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_getBlockTransactionCountByNumber` <a href="#eth-getblocktransactioncountbynumber" id="eth-getblocktransactioncountbynumber"></a>

Returns the total transaction count for a given block number.

**Parameters**

* Block number

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByNumber","params":["0x1"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

// Result
{"jsonrpc":"2.0","id":1,"result":{"difficulty":null,"extraData":"0x0","gasLimit":"0xffffffff","gasUsed":"0x0","hash":"0x8101cc04aea3341a6d4b3ced715e3f38de1e72867d6c0db5f5247d1a42fbb085","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","nonce":null,"number":"0x17d","parentHash":"0x70445488069d2584fea7d18c829e179322e2b2185b25430850deced481ca2e77","sha3Uncles":null,"size":"0x1df","stateRoot":"0x269bb17fe7adb8dd5f15f57b717979f82078d6b7a675c1ba1b0da2d27e415fcc","timestamp":"0x5f5ba97c","totalDifficulty":null,"transactions":[],"transactionsRoot":"0x","uncles":[]}}
```

#### `eth_getBlockTransactionCountByHash` <a href="#eth-getblocktransactioncountbyhash" id="eth-getblocktransactioncountbyhash"></a>

Returns the total transaction count for a given block hash.

**Parameters**

* Block Hash

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0x8101cc04aea3341a6d4b3ced715e3f38de1e72867d6c0db5f5247d1a42fbb085"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_getCode` <a href="#eth-getcode" id="eth-getcode"></a>

Returns the code for a given account address and Block Number.

**Parameters**

* Account Address
* Block Number or Block Hash ([EIP-1898](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md))

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getCode","params":["0x7bf7b17da59880d9bcca24915679668db75f9397", "0x0"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_sign` <a href="#eth-sign" id="eth-sign"></a>

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

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

{% hint style="warning" %}
The address to sign with must be unlocked.
{% endhint %}

**Parameters**

* Account Address
* Message to sign

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sign","params":["0x3b7252d007059ffc82d16d022da3cbf9992d2f70", "0xdeadbeaf"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_sendTransaction` <a href="#eth-sendtransaction" id="eth-sendtransaction"></a>

Sends transaction from given account to a given account.

**Parameters**

* Object containing:

  `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 - 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 Ethereum Contract ABI

  `nonce`: QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from":"0x3b7252d007059ffc82d16d022da3cbf9992d2f70", "to":"0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0", "value":"0x16345785d8a0000", "gasLimit":"0x5208", "gasPrice":"0x55ae82600"}],"id":1}'  -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_sendRawTransaction` <a href="#eth-sendrawtransaction" id="eth-sendrawtransaction"></a>

Creates new message call transaction or a contract creation for signed transactions. You can get signed transaction data using the `personal_sign` method.

**Parameters**

* The signed transaction data

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0xf9ff74c86aefeb5f6019d77280bbb44fb695b4d45cfe97e6eed7acd62905f4a85034d5c68ed25a2e7a8eeb9baf1b8401e4f865d92ec48c1763bf649e354d900b1c"],"id":1}'  -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_call` <a href="#eth-call" id="eth-call"></a>

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

**Parameters**

* Object containing:

  `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 - gas provided for the transaction execution. eth\_call consumes zero gas, but this parameter may be needed by some executions.

  `gasPrice`: QUANTITY - gasPrice used for each paid gas

  `value`: QUANTITY - value sent with this transaction

  `data`: `DATA` - (optional) Hash of the method signature and encoded parameters. For details see Ethereum Contract ABI in the Solidity documentation
* Block number or Block Hash ([EIP-1898](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md))

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_call","params":[{"from":"0x3b7252d007059ffc82d16d022da3cbf9992d2f70", "to":"0xddd64b4712f7c8f1ace3c145c950339eddaf221d", "gas":"0x5208", "gasPrice":"0x55ae82600", "value":"0x16345785d8a0000", "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, "0x0"],"id":1}'  -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_estimateGas` <a href="#eth-estimategas" id="eth-estimategas"></a>

Returns an estimate value of the gas required to send the transaction.

**Parameters**

* Object containing:

  `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.

  `value`: `QUANTITY` - value sent with this transaction

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_estimateGas","params":[{"from":"0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0", "to":"0x3b7252d007059ffc82d16d022da3cbf9992d2f70", "value":"0x16345785d8a00000"}],"id":1}'  -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_getBlockByNumber` <a href="#eth-getblockbynumber" id="eth-getblockbynumber"></a>

Returns information about a block by block number.

**Parameters**

* Block Number
* If true it returns the full transaction objects, if false only the hashes of the transactions.

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1", false],"id":1}' -H "Content-Type: application/json" http://localhost:8545

// Result
{"jsonrpc":"2.0","id":1,"result":{"difficulty":null,"extraData":"0x0","gasLimit":"0xffffffff","gasUsed":null,"hash":"0xabac6416f737a0eb54f47495b60246d405d138a6a64946458cf6cbeae0d48465","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","nonce":null,"number":"0x1","parentHash":"0x","sha3Uncles":null,"size":"0x9b","stateRoot":"0x","timestamp":"0x5f5bd3e5","totalDifficulty":null,"transactions":[],"transactionsRoot":"0x","uncles":[]}}
```

#### `eth_getBlockByHash` <a href="#eth-getblockbyhash" id="eth-getblockbyhash"></a>

Returns the block info given the hash found in the command above and a bool.

**Parameters**

* Hash of a block.
* If true it returns the full transaction objects, if false only the hashes of the transactions.

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByHash","params":["0x1b9911f57c13e5160d567ea6cf5b545413f96b95e43ec6e02787043351fb2cc4", false],"id":1}' -H "Content-Type: application/json" http://localhost:8545

// Result
{"jsonrpc":"2.0","id":1,"result":{"difficulty":null,"extraData":"0x0","gasLimit":"0xffffffff","gasUsed":null,"hash":"0x1b9911f57c13e5160d567ea6cf5b545413f96b95e43ec6e02787043351fb2cc4","logsBloom":"0x00000000100000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000002000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","nonce":null,"number":"0xc","parentHash":"0x404e58f31a9ede1b614b98701d6b0fbf1450f186842dbcf6426dd16811a5ca0d","sha3Uncles":null,"size":"0x307","stateRoot":"0x599ccdb111fc62c6398dc39be957df8e97bf8ab72ce6c06ff10641a92b754627","timestamp":"0x5f5fdbbd","totalDifficulty":null,"transactions":["0xae64961cb206a9773a6e5efeb337773a6fd0a2085ce480a174135a029afea615"],"transactionsRoot":"0x4764dba431128836fa919b83d314ba9cc000e75f38e1c31a60484409acea777b","uncles":[]}}
```

#### `eth_getTransactionByHash` <a href="#eth-gettransactionbyhash" id="eth-gettransactionbyhash"></a>

Returns transaction details given the ethereum tx something.

**Parameters**

* hash of a transaction

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0xec5fa15e1368d6ac314f9f64118c5794f076f63c02e66f97ea5fe1de761a8973"],"id":1}' -H "Content-Type: application/json" http://localhost:8545
 
// Result
{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x7a7398cc11d9c4c8e6f53e0c73824297aceafdab62db9e4b867a0da694384864","blockNumber":"0x188","from":"0x3b7252d007059ffc82d16d022da3cbf9992d2f70","gas":"0x147ee","gasPrice":"0x3b9aca00","hash":"0xec5fa15e1368d6ac314f9f64118c5794f076f63c02e66f97ea5fe1de761a8973","input":"0x6dba746c","nonce":"0x18","to":"0xa655256f589060437e5ffe2246dec385d040f148","transactionIndex":"0x0","value":"0x0","v":"0xa96","r":"0x6db399d694a452fb4106419140a6e5dbbe6817743a0f6f695a651e6576e59a5e","s":"0x25dd6ab1f936d0280d2fed0caeb0ebe5b9a46de6d8cb08ad8fd2c88deb55fc31"}}
```

#### `eth_getTransactionByBlockHashAndIndex` <a href="#eth-gettransactionbyblockhashandindex" id="eth-gettransactionbyblockhashandindex"></a>

Returns transaction details given the block hash and the transaction index.

**Parameters**

* Hash of a block.
* Transaction index position.

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockHashAndIndex","params":["0x1b9911f57c13e5160d567ea6cf5b545413f96b95e43ec6e02787043351fb2cc4", "0x0"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

// Result
{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x1b9911f57c13e5160d567ea6cf5b545413f96b95e43ec6e02787043351fb2cc4","blockNumber":"0xc","from":"0xddd64b4712f7c8f1ace3c145c950339eddaf221d","gas":"0x4c4b40","gasPrice":"0x3b9aca00","hash":"0xae64961cb206a9773a6e5efeb337773a6fd0a2085ce480a174135a029afea615","input":"0x4f2be91f","nonce":"0x0","to":"0x439c697e0742a0ddb124a376efd62a72a94ac35a","transactionIndex":"0x0","value":"0x0","v":"0xa96","r":"0xced57d973e58b0f634f776d57daf41d3d3387ceb347a3a72ca0746e5ec2b709e","s":"0x384e89e209a5eb147a2bac3a4e399507400ac7b29cd155531f9d6203a89db3f2"}}
```

#### `eth_getTransactionReceipt` <a href="#eth-gettransactionreceipt" id="eth-gettransactionreceipt"></a>

Returns the receipt of a transaction by transaction hash.

{% hint style="info" %}
Tx Code from Tendermint and the Ethereum receipt status are switched:
{% endhint %}

| -       | Tendermint | Ethereum |
| ------- | ---------- | -------- |
| Success | 0          | 1        |
| Failure | 1          | 0        |

**Parameters**

* Hash of a transaction

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xae64961cb206a9773a6e5efeb337773a6fd0a2085ce480a174135a029afea614"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

// Result
{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x1b9911f57c13e5160d567ea6cf5b545413f96b95e43ec6e02787043351fb2cc4","blockNumber":"0xc","contractAddress":"0x0000000000000000000000000000000000000000","cumulativeGasUsed":null,"from":"0xddd64b4712f7c8f1ace3c145c950339eddaf221d","gasUsed":"0x5289","logs":[{"address":"0x439c697e0742a0ddb124a376efd62a72a94ac35a","topics":["0x64a55044d1f2eddebe1b90e8e2853e8e96931cefadbfa0b2ceb34bee36061941"],"data":"0x0000000000000000000000000000000000000000000000000000000000000002","blockNumber":"0xc","transactionHash":"0xae64961cb206a9773a6e5efeb337773a6fd0a2085ce480a174135a029afea615","transactionIndex":"0x0","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","logIndex":"0x0","removed":false},{"address":"0x439c697e0742a0ddb124a376efd62a72a94ac35a","topics":["0x938d2ee5be9cfb0f7270ee2eff90507e94b37625d9d2b3a61c97d30a4560b829"],"data":"0x0000000000000000000000000000000000000000000000000000000000000002","blockNumber":"0xc","transactionHash":"0xae64961cb206a9773a6e5efeb337773a6fd0a2085ce480a174135a029afea615","transactionIndex":"0x0","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","logIndex":"0x1","removed":false}],"logsBloom":"0x00000000100000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000002000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":"0x439c697e0742a0ddb124a376efd62a72a94ac35a","transactionHash":"0xae64961cb206a9773a6e5efeb337773a6fd0a2085ce480a174135a029afea615","transactionIndex":"0x0"}}
```

#### `eth_newFilter` <a href="#eth-newfilter" id="eth-newfilter"></a>

Create new filter using topics of some kind.

**Parameters**

* hash of a transaction

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newFilter","params":[{"topics":["0x0000000000000000000000000000000000000000000000000000000012341234"]}],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_newBlockFilter` <a href="#eth-newblockfilter" id="eth-newblockfilter"></a>

Creates a filter in the node, to notify when a new block arrives.

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

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

#### `eth_newPendingTransactionFilter` <a href="#eth-newpendingtransactionfilter" id="eth-newpendingtransactionfilter"></a>

Creates a filter in the node, to notify when new pending transactions arrive.

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

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

#### `eth_uninstallFilter` <a href="#eth-uninstallfilter" id="eth-uninstallfilter"></a>

Removes the filter with the given filter id. Returns true if the filter was successfully uninstalled, otherwise false.

**Parameters**

* The filter id

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_uninstallFilter","params":["0xb91b6608b61bf56288a661a1bd5eb34a"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_getFilterChanges` <a href="#eth-getfilterchanges" id="eth-getfilterchanges"></a>

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

**Parameters**

* The filter id

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x127e9eca4f7751fb4e5cb5291ad8b455"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

// Result
{"jsonrpc":"2.0","id":1,"result":["0xc6f08d183a81e149896fc5317c872f9092068e88e956ca1864e9bd4c81c09b44","0x3ca6dfb5be15549d721d1b3d10c1bec50ed6217c9ac7b61df361fac9692a27e5","0x776fffac134171acb1ebf2e59856625501ad5ccc5c4c8fe0359e0d4dff8919f2","0x84123103704dbd738c089276ab2b04b5936330b24f6e78453c4ba8bf4848aaf9","0xffddbe5bd8e8aa41e44002daa9ea89ade9e6980a0d83f51d104cf16498827eca","0x53430e49963e8ae32605d8f22dec2e757a691e6436d593854ca4d9383eeab86a","0x975948058c9351a91fbec332ca00dda39d1a919f5f16b996a4c7e30c38ba423b","0x619e37e32024c8efef7f7220e6caff4ee1d682ea78b2ac91e0a6b30850dc0677","0x31a5d985a40d08303ac68000ce008df512bcd1a911c497415c97f0624b4a271a","0x91dcf1fce4503a8dbb3e6fb61073f25cd31d69c766ecba639fefde4436e59d07","0x606d9e0143cfdb410a6812c590a8135b5c6b5c59eec26d760d5cd930aa47257d","0xd3c00b859b29b20ba654415eef648ef58251389c73a138580db87675b0d5465f","0x954391f0eb50888be90489898016ebb54f750f612f3adec2a00854955d5e52d8","0x698905f06aff921a9e9fcef39b8b0d107747c3e6204d2ea79cf4c12debf8d253","0x9fcafec5721938a06eb8e2951ede4b6ef8fae54a8c8f85f3166ec9782a0032b5","0xaec6d3364e47a5716ba69e4705f3c705d017f81298859589591183bfea87be7a","0x91bf2ee13319b6eaca96ed89c126437b66c4df1b13560c6a9bb18556ee3b7e1f","0x4f426dc1fc0ea8149052033065b237892d2d34927b2d558ab50c5a7fb98d6e79","0xdd809fb07e5aab638fef5311371b4e2b27c9c9a6183fde0cdd2b7724f6d2a89b","0x7e12fc92ab953e233a304959a2a8474d96195e71efd9388fdceb1326a577811a","0x30618ef6b490c3cc9979c47163459db37c1a1e0aa5793c56accd417f9d89973b","0x614609f06ee24bae7408e45895b1a25e6b19a8159aeea7a95c9d1339d9ba286f","0x115ddc6d533620040791d241f01f1c5ae3d9d1a8f64b15af5e9793e4d9096e22","0xb7458c9323beeca2cd54f32a6af5671f3cd5a7a251aed9d82bdd6ebe5f56305b","0x573dd48a5ba7bf4cc3d49597cd7419f75ecc9897258f1ebadebd670446d0d358","0xcb6670918439f9698413b53f3b5336d82ca4be152fdefaacf45e052fff6262fc","0xf3fe2a8945abafd269ab97bfdc80b3dbff2202ffdce59a227f952874b966b230","0x989980707007533cc0840a079f77f261a2e818abae1a1ffd3af02f3fff1d35fd","0x886b6ae365fec996be8a9a2c31cf4cda97ff8352908be2c83f17abd66ef1591e","0xfd90df68706ef95a62b317de93d6899a9bd6c80416e42d007f5c30fcdedfce24","0x7af8491fbb0373886d9032bb74e0ef52ed9e100f260b79bd15f46126b38cbede","0x91d1e2cd55533cf7dd5de86c9aa73295e811b1279be193d429bbd6ba83810e16","0x6b65b3128c2104005a04923288fe2aa33a2477a4962bef70532f94cab582f2a7"]}
```

#### `eth_getFilterLogs` <a href="#eth-getfilterlogs" id="eth-getfilterlogs"></a>

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

**Parameters**

* `QUANTITY` - The filter id

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterLogs","params":["0x127e9eca4f7751fb4e5cb5291ad8b455"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

// Result
{"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"filter 0x35b64c227ce30e84fc5c7bd347be380e doesn't have a LogsSubscription type: got 5"}} 
```

#### `eth_getLogs` <a href="#eth-getlogs" id="eth-getlogs"></a>

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

**Parameters**

* Object containing:

  `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`: (optional, future) With the addition of [EIP-234](https://eips.ethereum.org/EIPS/eip-234), `blockHash` will be 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 in the filter criteria, then neither `fromBlock` nor `toBlock` are allowed.

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"topics":["0x775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd738898","0x0000000000000000000000000000000000000000000000000000000000000011"], "fromBlock":`"latest"`}],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `eth_coinbase` <a href="#eth-coinbase" id="eth-coinbase"></a>

Returns the account the mining rewards will be send to.

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

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

#### `eth_getProof` <a href="#eth-getproof" id="eth-getproof"></a>

Returns the account- and storage-values of the specified account including the Merkle-proof.

**Parameters**

* Address of account or contract
* Integer of the position in the storage
* Block Number or Block Hash ([EIP-1898](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md))

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getProof","params":["0x1234567890123456789012345678901234567890",["0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001"],`"latest"`],"id":1}' -H "Content-type:application/json" http://localhost:8545

// Result
{"jsonrpc": "2.0", "id": 1, "result": {"address": "0x1234567890123456789012345678901234567890", "accountProof": ["0xf90211a090dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43a0babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bda0473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021a0bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0a04e44caecff45c9891f74f6a2156735886eedf6f1a733628ebc802ec79d844648a0a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7a0e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92da0f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721a07117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681a069eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472a0203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8ea09287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208a06fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94eca07b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475a051f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0a089d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb80", "0xf90211a0395d87a95873cd98c21cf1df9421af03f7247880a2554e20738eec2c7507a494a0bcf6546339a1e7e14eb8fb572a968d217d2a0d1f3bc4257b22ef5333e9e4433ca012ae12498af8b2752c99efce07f3feef8ec910493be749acd63822c3558e6671a0dbf51303afdc36fc0c2d68a9bb05dab4f4917e7531e4a37ab0a153472d1b86e2a0ae90b50f067d9a2244e3d975233c0a0558c39ee152969f6678790abf773a9621a01d65cd682cc1be7c5e38d8da5c942e0a73eeaef10f387340a40a106699d494c3a06163b53d956c55544390c13634ea9aa75309f4fd866f312586942daf0f60fb37a058a52c1e858b1382a8893eb9c1f111f266eb9e21e6137aff0dddea243a567000a037b4b100761e02de63ea5f1fcfcf43e81a372dafb4419d126342136d329b7a7ba032472415864b08f808ba4374092003c8d7c40a9f7f9fe9cc8291f62538e1cc14a074e238ff5ec96b810364515551344100138916594d6af966170ff326a092fab0a0d31ac4eef14a79845200a496662e92186ca8b55e29ed0f9f59dbc6b521b116fea090607784fe738458b63c1942bba7c0321ae77e18df4961b2bc66727ea996464ea078f757653c1b63f72aff3dcc3f2a2e4c8cb4a9d36d1117c742833c84e20de994a0f78407de07f4b4cb4f899dfb95eedeb4049aeb5fc1635d65cf2f2f4dfd25d1d7a0862037513ba9d45354dd3e36264aceb2b862ac79d2050f14c95657e43a51b85c80", "0xf90171a04ad705ea7bf04339fa36b124fa221379bd5a38ffe9a6112cb2d94be3a437b879a08e45b5f72e8149c01efcb71429841d6a8879d4bbe27335604a5bff8dfdf85dcea00313d9b2f7c03733d6549ea3b810e5262ed844ea12f70993d87d3e0f04e3979ea0b59e3cdd6750fa8b15164612a5cb6567cdfb386d4e0137fccee5f35ab55d0efda0fe6db56e42f2057a071c980a778d9a0b61038f269dd74a0e90155b3f40f14364a08538587f2378a0849f9608942cf481da4120c360f8391bbcc225d811823c6432a026eac94e755534e16f9552e73025d6d9c30d1d7682a4cb5bd7741ddabfd48c50a041557da9a74ca68da793e743e81e2029b2835e1cc16e9e25bd0c1e89d4ccad6980a041dda0a40a21ade3a20fcd1a4abb2a42b74e9a32b02424ff8db4ea708a5e0fb9a09aaf8326a51f613607a8685f57458329b41e938bb761131a5747e066b81a0a16808080a022e6cef138e16d2272ef58434ddf49260dc1de1f8ad6dfca3da5d2a92aaaadc58080", "0xf851808080a009833150c367df138f1538689984b8a84fc55692d3d41fe4d1e5720ff5483a6980808080808080808080a0a319c1c415b271afc0adcb664e67738d103ac168e0bc0b7bd2da7966165cb9518080"], "balance": "0x0", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "nonce": "0x0", "storageHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "storageProof": [{"key": "0x0000000000000000000000000000000000000000000000000000000000000000", "value": "0x0", "proof": []}, {"key": "0x0000000000000000000000000000000000000000000000000000000000000001", "value": "0x0", "proof": []}]}}
```

### WebSocket Methods <a href="#websocket-methods" id="websocket-methods"></a>

#### `eth_subscribe` <a href="#eth-subscribe" id="eth-subscribe"></a>

subscribe using JSON-RPC notifications. 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.

**Parameters**

* Subscription Name
* Optional Arguments

```json
// Request
{"id": 1, "method": "eth_subscribe", "params": ["newHeads", {"includeTransactions": true}]}

// Result
< {"jsonrpc":"2.0","result":"0x34da6f29e3e953af4d0c7c58658fd525","id":1}
```

#### `eth_unsubscribe` <a href="#eth-unsubscribe" id="eth-unsubscribe"></a>

Unsubscribe from an event using the subscription id

**Parameters**

* Subscription ID

```json
// Request
{"id": 1, "method": "eth_unsubscribe", "params": ["0x34da6f29e3e953af4d0c7c58658fd525"]}

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

### Personal Methods <a href="#personal-methods" id="personal-methods"></a>

#### `personal_importRawKey` <a href="#personal-importrawkey" id="personal-importrawkey"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Imports the given unencrypted private key (hex encoded string) into the key store, encrypting it with the passphrase.

Returns the address of the new account.

**Parameters (2)**

**1:** privkey `string`

* Required: ✓ Yes

**2:** password `string`

* Required: ✓ Yes

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_importRawKey","params":["c5bd76cd0cd948de17a31261567d219576e992d9066fe1a6bca97496dec634e2c8e06f8949773b300b9f73fabbbc7710d5d6691e96bcf3c9145e15daf6fe07b9", "the key is this"],"id":1}' -H "Content-Type: application/json" http://localhost:8545
```

#### `personal_listAccounts` <a href="#personal-listaccounts" id="personal-listaccounts"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Returns a list of addresses for accounts this node manages.

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

// Result
{"jsonrpc":"2.0","id":1,"result":["0x3b7252d007059ffc82d16d022da3cbf9992d2f70","0xddd64b4712f7c8f1ace3c145c950339eddaf221d","0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0"]}
```

#### `personal_lockAccount` <a href="#personal-lockaccount" id="personal-lockaccount"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Removes the private key with given address from memory. The account can no longer be used to send transactions.

**Parameters**

* Account Address

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_lockAccount","params":["0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `personal_newAccount` <a href="#personal-newaccount" id="personal-newaccount"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Generates a new private key and stores it in the key store directory. The key file is encrypted with the given passphrase. Returns the address of the new account.

**Parameters**

* Passphrase

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_newAccount","params":["This is the passphrase"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `personal_unlockAccount` <a href="#personal-unlockaccount" id="personal-unlockaccount"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Decrypts the key with the given address from the key store.

Both passphrase and unlock duration are optional when using the JavaScript console. The unencrypted key will be held in memory until the unlock duration expires. If the unlock duration defaults to 300 seconds. An explicit duration of zero seconds unlocks the key until geth exits.

The account can be used with `eth_sign` and `eth_sendTransaction` while it is unlocked.

**Parameters**

* Account Address
* Passphrase
* Duration

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_unlockAccount","params":["0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0", "secret passphrase", 30],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `personal_sendTransaction` <a href="#personal-sendtransaction" id="personal-sendtransaction"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Validate the given passphrase and submit transaction.

The transaction is the same argument as for `eth_sendTransaction` and contains the `from` address. If the passphrase can be used to decrypt the private key belonging to `tx.from` the transaction is verified, signed and send onto the network.

{% hint style="warning" %}
The account is not unlocked globally in the node and cannot be used in other RPC calls.
{% endhint %}

**Parameters**

* Object containing:

  `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.

  `value`: QUANTITY - value sent with this transaction
* Passphrase

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_sendTransaction","params":[{"from":"0x3b7252d007059ffc82d16d022da3cbf9992d2f70","to":"0xddd64b4712f7c8f1ace3c145c950339eddaf221d", "value":"0x16345785d8a0000"}, "passphrase"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `personal_sign` <a href="#personal-sign" id="personal-sign"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

The sign method calculates an Ethereum specific signature with: `sign(keccack256("\x19Ethereum Signed Message:\n" + len(message) + message)))`,

**Parameters**

* Message
* Account Address
* Password

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_sign","params":["0xdeadbeaf", "0x3b7252d007059ffc82d16d022da3cbf9992d2f70", "password"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `personal_ecRecover` <a href="#personal-ecrecover" id="personal-ecrecover"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

`ecRecover` returns the address associated with the private key that was used to calculate the signature in `personal_sign`.

**Parameters**

* Message
* Signature returned from `personal_sign`

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_ecRecover","params":["0xdeadbeaf", "0xf9ff74c86aefeb5f6019d77280bbb44fb695b4d45cfe97e6eed7acd62905f4a85034d5c68ed25a2e7a8eeb9baf1b8401e4f865d92ec48c1763bf649e354d900b1c"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `personal_initializeWallet` <a href="#personal-initializewallet" id="personal-initializewallet"></a>

**Private**: Requires authentication.

Initializes a new wallet at the provided URL, by generating and returning a new private key.

**Parameters (1)**

Parameters must be given by position.

1: url `string`

* Required: ✓ Yes

**Client Examples**

:::: tabs ::: tab Shell HTTP

```bash
curl -X POST -H "Content-Type: application/json" http://localhost:8545 --data '{"jsonrpc": "2.0", "id": 42, "method": "personal_initializeWallet", "params": [<url>]}'
```

::: ::: tab Shell WebSocket

```bash
wscat -c ws://localhost:8546 -x '{"jsonrpc": "2.0", "id": 1, "method": "personal_initializeWallet", "params": [<url>]}'
```

::: ::: tab Javascript Console

```javascript
personal.initializeWallet(url);
```

::: ::::

#### `personal_unpair` <a href="#personal-unpair" id="personal-unpair"></a>

**Private**: Requires authentication.

Unpair deletes a pairing between wallet and the node.

**Parameters (2)**

* URL
* Pairing password

**Client Examples**

:::: tabs ::: tab Shell HTTP

```bash
curl -X POST -H "Content-Type: application/json" http://localhost:8545 --data '{"jsonrpc": "2.0", "id": 42, "method": "personal_unpair", "params": [<url>, <pin>]}'
```

::: ::: tab Shell WebSocket

```bash
wscat -c ws://localhost:8546 -x '{"jsonrpc": "2.0", "id": 1, "method": "personal_unpair", "params": [<url>, <pin>]}'
```

::: ::: tab Javascript Console

```javascript
personal.unpair(url,pin);
```

::: ::::

### Debug Methods <a href="#debug-methods" id="debug-methods"></a>

#### `debug_traceTransaction` <a href="#debug-tracetransaction" id="debug-tracetransaction"></a>

The `traceTransaction` debugging method will attempt to run the transaction in the exact same manner as it was executed on the network. It will replay any transaction that may have been executed prior to this one before it will finally attempt to execute the transaction that corresponds to the given hash.

**Parameters**

* Trace Config

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"debug_traceTransaction","params":["0xddecdb13226339681372b44e01df0fbc0f446fca6f834b2de5ecb1e569022ec8", {"tracer": "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}"}],"id":1}' -H "Content-Type: application/json" http://localhost:8545

//Result
["68410", "51470"]
```

#### `debug_traceBlockByNumber` <a href="#debug-traceblockbynumber" id="debug-traceblockbynumber"></a>

The `traceBlockByNumber` endpoint accepts a block number and will replay the block that is already present in the database.

**Parameters**

* Trace Config

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"debug_traceBlockByNumber","params":["0xe", {"tracer": "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}"}],"id":1}' -H "Content-Type: application/json" http://localhost:8545

//Result
{"jsonrpc":"2.0","id":1,"result":[{"result":["68410", "51470"]}]}
```

### Miner Methods <a href="#miner-methods" id="miner-methods"></a>

#### `miner_getHashrate` <a href="#miner-gethashrate" id="miner-gethashrate"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Get the hashrate in H/s (Hash operations per second).

{% hint style="warning" %}
Proof-of-Work specific. This endpoint always returns `0`.
{% endhint %}

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

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

#### `miner_setExtra` <a href="#miner-setextra" id="miner-setextra"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Sets the extra data a validator can include when proposing blocks. This is capped at 32 bytes.

{% hint style="warning" %}
Unsupported. This endpoint always returns an error
{% endhint %}

**Parameters**

* Data

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

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

#### `miner_setGasPrice` <a href="#miner-setgasprice" id="miner-setgasprice"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Sets the minimal gas price used to accept transactions. Any transaction below this limit is excluded from the validator block proposal process.

This method requires a `node` restart after being called because it changes the configuration file.

Make sure your `blockxd start` call is not using the flag `minimum-gas-prices` because this value will be used instead of the one set on the configuration file.

**Parameters**

* Hex Gas Price

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"miner_setGasPrice","params":["0x0"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `miner_start` <a href="#miner-start" id="miner-start"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Start the CPU validation process with the given number of threads.

{% hint style="warning" %}
Unsupported. This endpoint always returns an error
{% endhint %}

**Parameters**

* Hex Number of threads

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"miner_start","params":["0x1"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `miner_stop` <a href="#miner-stop" id="miner-stop"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Stop the validation operation.

{% hint style="warning" %}
Unsupported. This endpoint always performs a no-op.
{% endhint %}

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

#### `miner_setGasLimit` <a href="#miner-setgaslimit" id="miner-setgaslimit"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Sets the gas limit the miner will target when mining. Note: on networks where [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) is activated, this should be set to twice what you want the gas target (i.e. the effective gas used on average per block) to be.

{% hint style="warning" %}
Unsupported. This endpoint always returns `false`
{% endhint %}

**Parameters**

* Hex gas limit

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"miner_setGasLimit","params":["0x10000"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

#### `miner_setEtherbase` <a href="#miner-setetherbase" id="miner-setetherbase"></a>

{% hint style="info" %}
**Private**: Requires authentication.
{% endhint %}

Sets the etherbase. It changes the wallet where the validator rewards will be deposited.

**Parameters**

* Account Address

```bash
// Request
curl -X POST --data '{"jsonrpc":"2.0","method":"miner_setEtherbase","params":["0x3b7252d007059ffc82d16d022da3cbf9992d2f70"],"id":1}' -H "Content-Type: application/json" http://localhost:8545

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

### TxPool Methods <a href="#txpool-methods" id="txpool-methods"></a>

#### `txpool_content` <a href="#txpool-content" id="txpool-content"></a>

Returns a list of the exact details of all the transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only.

**Parameters (0)**

**Client Examples**

:::: tabs ::: tab Shell HTTP

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

::: ::: tab Shell WebSocket

```bash
wscat -c ws://localhost:8546 -x '{"jsonrpc": "2.0", "id": 1, "method": "txpool_content", "params": []}'
```

::: ::: tab Javascript Console

```javascript
txpool.content();
```

::: ::::

**Result**

```json
{"jsonrpc":"2.0","id":1,"result":{"pending":{},"queued":{}}
```

#### `txpool_inspect` <a href="#txpool-inspect" id="txpool-inspect"></a>

Returns a list on text format to summarize all the transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only. This is a method specifically tailored to developers to quickly see the transactions in the pool and find any potential issues.

**Parameters (0)**

**Client Examples**

:::: tabs ::: tab Shell HTTP

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

::: ::: tab Shell WebSocket

```bash
wscat -c ws://localhost:8546 -x '{"jsonrpc": "2.0", "id": 1, "method": "txpool_inspect", "params": []}'
```

::: ::: tab Javascript Console

```javascript
txpool.inspect();
```

::: ::::

**Result**

```json
{"jsonrpc":"2.0","id":1,"result":{"pending":{},"queued":{}}
```

#### `txpool_status` <a href="#txpool-status" id="txpool-status"></a>

Returns the number of transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only.

**Parameters (0)**

**Client Examples**

:::: tabs ::: tab Shell HTTP

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

::: ::: tab Shell WebSocket

```bash
wscat -c ws://localhost:8546 -x '{"jsonrpc": "2.0", "id": 1, "method": "txpool_status", "params": []}'
```

::: ::: tab Javascript Console

```javascript
txpool.status();
```

::: ::::

**Result**

```json
{"jsonrpc":"2.0","id":1,"result":{"pending":"0x0","queued":"0x0"}}\
```


# Events

*Events are objects that contain information about the execution of the application. They are mainly used by service providers like block explorers and wallet to track the execution of various messages and index transactions.*

### Subscribing to Events <a href="#subscribing-to-events" id="subscribing-to-events"></a>

#### Cosmos and Tendermint Events <a href="#cosmos-and-tendermint-events" id="cosmos-and-tendermint-events"></a>

It is possible to subscribe to `Events` via Tendermint's [Websocket](https://docs.tendermint.com/v0.34/tendermint-core/subscription.html). This is done by calling the `subscribe` RPC method via Websocket:

```json
{
    "jsonrpc": "2.0",
    "method": "subscribe",
    "id": "0",
    "params": {
        "query": "tm.event='<event_value>' AND eventType.eventAttribute='<attribute_value>'"
    }
}
```

These events are triggered after a block is committed.&#x20;

The `type` and `attribute` value of the `query` allow you to filter the specific `event` you are looking for. For example, a an Ethereum transaction on BlockX (`MsgEthereumTx`) triggers an `event` of type `ethermint` and has `sender` and `recipient` as `attributes`. Subscribing to this `event` would be done like so:

```json
{
    "jsonrpc": "2.0",
    "method": "subscribe",
    "id": "0",
    "params": {
        "query": "tm.event='Tx' AND ethereum.recipient='hexAddress'"
    }
}
```

where `hexAddress` is an Ethereum hex address (eg: `0x1122334455667788990011223344556677889900`).

#### Ethereum Events <a href="#ethereum-events" id="ethereum-events"></a>

BlockX also supports the Ethereum JSON-RPC filters calls to subscribe to [state logs](https://eth.wiki/json-rpc/API#eth_newfilter), [block](https://eth.wiki/json-rpc/API#eth_newblockfilter) or [pending transactions](https://eth.wiki/json-rpc/API#eth_newpendingtransactionfilter) changes.

Under the hood, it uses the Tendermint RPC client's event system to process subscriptions that are then formatted to Ethereum-compatible events.

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

{"jsonrpc":"2.0","id":1,"result":"0x3503de5f0c766c68f78a03a3b05036a5"}
```

Then you can check if the state changes with the `eth_getFilterChanges` call:

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

{"jsonrpc":"2.0","id":1,"result":["0x7d44dceff05d5963b5bc81df7e9f79b27e777b0a03a6feca09f3447b99c6fa71","0x3961e4050c27ce0145d375255b3cb829a5b4e795ac475c05a219b3733723d376","0xd7a497f95167d63e6feca70f344d9f6e843d097b62729b8f43bdcd5febf142ab","0x55d80a4ba6ef54f2a8c0b99589d017b810ed13a1fda6a111e1b87725bc8ceb0e","0x9e8b92c17280dd05f2562af6eea3285181c562ebf41fc758527d4c30364bcbc4","0x7353a4b9d6b35c9eafeccaf9722dd293c46ae2ffd4093b2367165c3620a0c7c9","0x026d91bda61c8789c59632c349b38fd7e7557e6b598b94879654a644cfa75f30","0x73e3245d4ddc3bba48fa67633f9993c6e11728a36401fa1206437f8be94ef1d3"]}
```

### Websocket Connection <a href="#websocket-connection" id="websocket-connection"></a>

#### Tendermint Websocket <a href="#tendermint-websocket" id="tendermint-websocket"></a>

To start a connection with the Tendermint websocket you need to define the address with the `--rpc.laddr` flag when starting the node (default `tcp://127.0.0.1:26657`):

```bash
# connect to tendermint websocket at port 8080 as defined above
ws ws://localhost:8080/websocket

# subscribe to new Tendermint block headers
> { "jsonrpc": "2.0", "method": "subscribe", "params": ["tm.event='NewBlockHeader'"], "id": 1 }
```

#### Ethereum Websocket <a href="#ethereum-websocket" id="ethereum-websocket"></a>

Since BlockX runs uses Tendermint Core as it's consensus Engine and it's built with the Cosmos SDK framework, it inherits the event format from them. However, in order to support the native Web3 compatibility for websockets of the [Ethereum's PubSubAPI](https://geth.ethereum.org/docs/rpc/pubsub), BlockX needs to cast the Tendermint responses retrieved into the Ethereum types.

You can start a connection with the Ethereum websocket using the `--json-rpc.ws-address` flag when starting the node (default `"0.0.0.0:8546"`):

```bash
blockxd start  --json-rpc.address"0.0.0.0:8545" --json-rpc.ws-address="0.0.0.0:8546" --evm.rpc.api="eth,web3,net,txpool,debug" --json-rpc.enable
```

Then, start a websocket subscription with [`ws`](https://github.com/hashrocket/ws)

```bash
# connect to tendermint websocet at port 8546 as defined above
ws ws://localhost:8546/

# subscribe to new Ethereum-formatted block Headers
> {"id": 1, "method": "eth_subscribe", "params": ["newHeads", {}]}
< {"jsonrpc":"2.0","result":"0x44e010cb2c3161e9c02207ff172166ef","id":1}
```


# Protocol Developers


# Modules

Here are some production-grade modules that can be used in BlockX applications, along with their respective documentation:

* claims - Rewards status and claiming process for the mainnet release.
* epochs - Executes custom state transitions every period (*aka* epoch).
* erc20 - Trustless, on-chain bidirectional internal conversion of tokens between the BlockX EVM and Cosmos runtimes.
* evm - Smart Contract deployment and execution on Cosmos
* feemarket - Fee market implementation based on the EIP1559 specification.
* feesplit - Split EVM transaction fees between block proposer and smart contract developers.
* incentives - Incentivize user interaction with governance-approved smart contracts.
* inflation - Mint tokens and allocate them to staking rewards, usage incentives and community pool.
* vesting - Vesting accounts with lockup and clawback capabilities.


# auth

## `auth`

### Abstract <a href="#abstract" id="abstract"></a>

This document specifies the auth module of the Cosmos SDK.

The auth module is responsible for specifying the base transaction and account types for an application, since the SDK itself is agnostic to these particulars.&#x20;

It contains the middlewares, where all basic transaction validity checks (signatures, nonces, auxiliary fields) are performed, and exposes the account keeper, which allows other modules to read, write, and modify accounts.

This module is used in the Cosmos Hub.


# Concepts

**Note:** The auth module is different from the authz module.

The differences are:

* `auth` - authentication of accounts and transactions for Cosmos SDK applications and is responsible for specifying the base transaction and account types.
* `authz` - authorization for accounts to perform actions on behalf of other accounts and enables a granter to grant authorizations to a grantee that allows the grantee to execute messages on behalf of the granter.

### Gas & Fees <a href="#gas-fees" id="gas-fees"></a>

Fees serve two purposes for an operator of the network.

Fees limit the growth of the state stored by every full node and allow for general purpose censorship of transactions of little economic value. Fees are best suited as an anti-spam mechanism where validators are disinterested in the use of the network and identities of users.

Fees are determined by the gas limits and gas prices transactions provide, where `fees = ceil(gasLimit * gasPrices)`. Txs incur gas costs for all state reads/writes, signature verification, as well as costs proportional to the tx size. Operators should set minimum gas prices when starting their nodes. They must set the unit costs of gas in each token denomination they wish to support:

`simd start ... --minimum-gas-prices=0.00001stake;0.05photinos`

When adding transactions to mempool or gossipping transactions, validators check if the transaction's gas prices, which are determined by the provided fees, meet any of the validator's minimum gas prices. In other words, a transaction must provide a fee of at least one denomination that matches a validator's minimum gas price.

Tendermint does not currently provide fee based mempool prioritization, and fee based mempool filtering is local to node and not part of consensus. But with minimum gas prices set, such a mechanism could be implemented by node operators.

Because the market value for tokens will fluctuate, validators are expected to dynamically adjust their minimum gas prices to a level that would encourage the use of the network.


# State

### Accounts <a href="#accounts" id="accounts"></a>

Accounts contain authentication information for a uniquely identified external user of an SDK blockchain, including public key, address, and account number / sequence number for replay protection. For efficiency, since account balances must also be fetched to pay fees, account structs also store the balance of a user as `sdk.Coins`.

Accounts are exposed externally as an interface, and stored internally as either a base account or vesting account. Module clients wishing to add more account types may do so.

* `0x01 | Address -> ProtocolBuffer(account)`

#### Account Interface <a href="#account-interface" id="account-interface"></a>

The account interface exposes methods to read and write standard account information. Note that all of these methods operate on an account struct confirming to the interface - in order to write the account to the store, the account keeper will need to be used.

```go
// AccountI is an interface used to store coins at a given address within state.
// It presumes a notion of sequence numbers for replay protection,
// a notion of account numbers for replay protection for previously pruned accounts,
// and a pubkey for authentication purposes.
//
// Many complex conditions can be used in the concrete struct which implements AccountI.
type AccountI interface {
	proto.Message

	GetAddress() sdk.AccAddress
	SetAddress(sdk.AccAddress) error // errors if already set.

	GetPubKey() crypto.PubKey // can return nil.
	SetPubKey(crypto.PubKey) error

	GetAccountNumber() uint64
	SetAccountNumber(uint64) error

	GetSequence() uint64
	SetSequence(uint64) error

	// Ensure that account implements stringer
	String() string
}
```

**Base Account**

A base account is the simplest and most common account type, which just stores all requisite fields directly in a struct.

```go
// BaseAccount defines a base account type. It contains all the necessary fields
// for basic account functionality. Any custom account type should extend this
// type for additional functionality (e.g. vesting).
message BaseAccount {
  string address = 1;
  google.protobuf.Any pub_key = 2;
  uint64 account_number = 3;
  uint64 sequence       = 4;
}
```


# AnteHandlers

The `x/auth` module presently has no transaction handlers of its own, but does expose the special `AnteHandler`, used for performing basic validity checks on a transaction, such that it could be thrown out of the mempool. The `AnteHandler` can be seen as a set of decorators that check transactions within the current context, per [ADR 010](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-010-modular-antehandler.md).

Note that the `AnteHandler` is called on both `CheckTx` and `DeliverTx`, as Tendermint proposers presently have the ability to include in their proposed block transactions which fail `CheckTx`.

### Decorators <a href="#decorators" id="decorators"></a>

The auth module provides `AnteDecorator`s that are recursively chained together into a single `AnteHandler` in the following order:

* `SetUpContextDecorator`: Sets the `GasMeter` in the `Context` and wraps the next `AnteHandler` with a defer clause to recover from any downstream `OutOfGas` panics in the `AnteHandler` chain to return an error with information on gas provided and gas used.
* `RejectExtensionOptionsDecorator`: Rejects all extension options which can optionally be included in protobuf transactions.
* `MempoolFeeDecorator`: Checks if the `tx` fee is above local mempool `minFee` parameter during `CheckTx`.
* `ValidateBasicDecorator`: Calls `tx.ValidateBasic` and returns any non-nil error.
* `TxTimeoutHeightDecorator`: Check for a `tx` height timeout.
* `ValidateMemoDecorator`: Validates `tx` memo with application parameters and returns any non-nil error.
* `ConsumeGasTxSizeDecorator`: Consumes gas proportional to the `tx` size based on application parameters.
* `DeductFeeDecorator`: Deducts the `FeeAmount` from first signer of the `tx`. If the `x/feegrant` module is enabled and a fee granter is set, it deducts fees from the fee granter account.
* `SetPubKeyDecorator`: Sets the pubkey from a `tx`'s signers that does not already have its corresponding pubkey saved in the state machine and in the current context.
* `ValidateSigCountDecorator`: Validates the number of signatures in `tx` based on app-parameters.
* `SigGasConsumeDecorator`: Consumes parameter-defined amount of gas for each signature. This requires pubkeys to be set in context for all signers as part of `SetPubKeyDecorator`.
* `SigVerificationDecorator`: Verifies all signatures are valid. This requires pubkeys to be set in context for all signers as part of `SetPubKeyDecorator`.
* `IncrementSequenceDecorator`: Increments the account sequence for each signer to prevent replay attacks.


# Keepers

The auth module only exposes one keeper, the account keeper, which can be used to read and write accounts.

### Account Keeper <a href="#account-keeper" id="account-keeper"></a>

Presently only one fully-permissioned account keeper is exposed, which has the ability to both read and write all fields of all accounts, and to iterate over all stored accounts.

```go
// AccountKeeperI is the interface contract that x/auth's keeper implements.
type AccountKeeperI interface {
	// Return a new account with the next account number and the specified address. Does not save the new account to the store.
	NewAccountWithAddress(sdk.Context, sdk.AccAddress) types.AccountI

	// Return a new account with the next account number. Does not save the new account to the store.
	NewAccount(sdk.Context, types.AccountI) types.AccountI

	// Check if an account exists in the store.
	HasAccount(sdk.Context, sdk.AccAddress) bool

	// Retrieve an account from the store.
	GetAccount(sdk.Context, sdk.AccAddress) types.AccountI

	// Set an account in the store.
	SetAccount(sdk.Context, types.AccountI)

	// Remove an account from the store.
	RemoveAccount(sdk.Context, types.AccountI)

	// Iterate over all accounts, calling the provided function. Stop iteration when it returns true.
	IterateAccounts(sdk.Context, func(types.AccountI) bool)

	// Fetch the public key of an account at a specified address
	GetPubKey(sdk.Context, sdk.AccAddress) (crypto.PubKey, error)

	// Fetch the sequence of an account at a specified address.
	GetSequence(sdk.Context, sdk.AccAddress) (uint64, error)

	// Fetch the next account number, and increment the internal counter.
	GetNextAccountNumber(sdk.Context) uint64
}
```


# Vesting

### Intro and Requirements

This specification defines the vesting account implementation that is used by the Cosmos Hub. The requirements for this vesting account is that it should be initialized during genesis with a starting balance `X` and a vesting end time `ET`.&#x20;

A vesting account may be initialized with a vesting start time `ST` and a number of vesting periods `P`. If a vesting start time is included, the vesting period does not begin until start time is reached. If vesting periods are included, the vesting occurs over the specified number of periods.

For all vesting accounts, the owner of the vesting account is able to delegate and undelegate from validators, however they cannot transfer coins to another account until those coins are vested. This specification allows for four different kinds of vesting:

* Delayed vesting, where all coins are vested once `ET` is reached.
* Continous vesting, where coins begin to vest at `ST` and vest linearly with respect to time until `ET` is reached
* Periodic vesting, where coins begin to vest at `ST` and vest periodically according to number of periods and the vesting amount per period. The number of periods, length per period, and amount per period are configurable. A periodic vesting account is distinguished from a continuous vesting account in that coins can be released in staggered tranches. For example, a periodic vesting account could be used for vesting arrangements where coins are relased quarterly, yearly, or over any other function of tokens over time.
* Permanent locked vesting, where coins are locked forever. Coins in this account can still be used for delegating and for governance votes even while locked.

### Note <a href="#note" id="note"></a>

Vesting accounts can be initialized with some vesting and non-vesting coins. The non-vesting coins would be immediately transferable. DelayedVesting and ContinuousVesting accounts can be created with normal messages after genesis. Other types of vesting accounts must be created at genesis, or as part of a manual network upgrade. The current specification only allows for *unconditional* vesting (ie. there is no possibility of reaching `ET` and having coins fail to vest).

### Vesting Account Types <a href="#vesting-account-types" id="vesting-account-types"></a>

```go
// VestingAccount defines an interface that any vesting account type must
// implement.
type VestingAccount interface {
  Account

  GetVestedCoins(Time)  Coins
  GetVestingCoins(Time) Coins

  // TrackDelegation performs internal vesting accounting necessary when
  // delegating from a vesting account. It accepts the current block time, the
  // delegation amount and balance of all coins whose denomination exists in
  // the account's original vesting balance.
  TrackDelegation(Time, Coins, Coins)

  // TrackUndelegation performs internal vesting accounting necessary when a
  // vesting account performs an undelegation.
  TrackUndelegation(Coins)

  GetStartTime() int64
  GetEndTime()   int64
}
```

#### BaseVestingAccount <a href="#basevestingaccount" id="basevestingaccount"></a>

```protobuf
// BaseVestingAccount implements the VestingAccount interface. It contains all
// the necessary fields needed for any vesting account implementation.
message BaseVestingAccount {
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  cosmos.auth.v1beta1.BaseAccount base_account       = 1 [(gogoproto.embed) = true];
  repeated cosmos.base.v1beta1.Coin original_vesting = 2
      [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
  repeated cosmos.base.v1beta1.Coin delegated_free = 3
      [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
  repeated cosmos.base.v1beta1.Coin delegated_vesting = 4
      [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
  int64 end_time = 5;
}
```

#### ContinuousVestingAccount <a href="#continuousvestingaccount" id="continuousvestingaccount"></a>

```protobuf
// ContinuousVestingAccount implements the VestingAccount interface. It
// continuously vests by unlocking coins linearly with respect to time.
message ContinuousVestingAccount {
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true];
  int64              start_time           = 2;
}
```

#### DelayedVestingAccount <a href="#delayedvestingaccount" id="delayedvestingaccount"></a>

```protobuf
// DelayedVestingAccount implements the VestingAccount interface. It vests all
// coins after a specific time, but non prior. In other words, it keeps them
// locked until a specified time.
message DelayedVestingAccount {
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true];
}
```

#### Period

```protobuf
// Period defines a length of time and amount of coins that will vest.
message Period {
  option (gogoproto.goproto_stringer) = false;

  int64    length                          = 1;
  repeated cosmos.base.v1beta1.Coin amount = 2
      [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}
```

```go
// Stores all vesting periods passed as part of a PeriodicVestingAccount
type Periods []Period
```

#### PeriodicVestingAccount <a href="#periodicvestingaccount" id="periodicvestingaccount"></a>

```protobuf
// PeriodicVestingAccount implements the VestingAccount interface. It
// periodically vests by unlocking coins during each specified period.
message PeriodicVestingAccount {
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true];
  int64              start_time           = 2;
  repeated Period    vesting_periods      = 3 [(gogoproto.nullable) = false];
}
```

In order to facilitate less ad-hoc type checking and assertions and to support flexibility in account balance usage, the existing `x/bank` `ViewKeeper` interface is updated to contain the following:

```go
type ViewKeeper interface {
  // ...

  // Calculates the total locked account balance.
  LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins

  // Calculates the total spendable balance that can be sent to other accounts.
  SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
}
```

#### PermanentLockedAccount <a href="#permanentlockedaccount" id="permanentlockedaccount"></a>

```protobuf
// PermanentLockedAccount implements the VestingAccount interface. It does
// not ever release coins, locking them indefinitely. Coins in this account can
// still be used for delegating and for governance votes even while locked.
//
// Since: cosmos-sdk 0.43
message PermanentLockedAccount {
  option (gogoproto.goproto_getters)  = false;
  option (gogoproto.goproto_stringer) = false;

  BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true];
}
```

### Vesting Account Specification <a href="#vesting-account-specification" id="vesting-account-specification"></a>

Given a vesting account, we define the following in the proceeding operations:

* `OV`: The original vesting coin amount. It is a constant value.
* `V`: The number of `OV` coins that are still *vesting*. It is derived by `OV`, `StartTime` and `EndTime`. This value is computed on demand and not on a per-block basis.
* `V'`: The number of `OV` coins that are *vested* (unlocked). This value is computed on demand and not a per-block basis.
* `DV`: The number of delegated *vesting* coins. It is a variable value. It is stored and modified directly in the vesting account.
* `DF`: The number of delegated *vested* (unlocked) coins. It is a variable value. It is stored and modified directly in the vesting account.
* `BC`: The number of `OV` coins less any coins that are transferred (which can be negative or delegated). It is considered to be balance of the embedded base account. It is stored and modified directly in the vesting account.

### Determining Vesting & Vested Amounts <a href="#determining-vesting-vested-amounts" id="determining-vesting-vested-amounts"></a>

It is important to note that these values are computed on demand and not on a mandatory per-block basis (e.g. `BeginBlocker` or `EndBlocker`).

**Continuously Vesting Accounts**

To determine the amount of coins that are vested for a given block time `T`, the following is performed:

1. Compute `X := T - StartTime`
2. Compute `Y := EndTime - StartTime`
3. Compute `V' := OV * (X / Y)`
4. Compute `V := OV - V'`

Thus, the total amount of *vested* coins is `V'` and the remaining amount, `V`, is *vesting*.

```go
func (cva ContinuousVestingAccount) GetVestedCoins(t Time) Coins {
    if t <= cva.StartTime {
        // We must handle the case where the start time for a vesting account has
        // been set into the future or when the start of the chain is not exactly
        // known.
        return ZeroCoins
    } else if t >= cva.EndTime {
        return cva.OriginalVesting
    }

    x := t - cva.StartTime
    y := cva.EndTime - cva.StartTime

    return cva.OriginalVesting * (x / y)
}

func (cva ContinuousVestingAccount) GetVestingCoins(t Time) Coins {
    return cva.OriginalVesting - cva.GetVestedCoins(t)
}
```

### Periodic Vesting Accounts <a href="#periodic-vesting-accounts" id="periodic-vesting-accounts"></a>

Periodic vesting accounts require calculating the coins released during each period for a given block time `T`. Note that multiple periods could have passed when calling `GetVestedCoins`, so we must iterate over each period until the end of that period is after `T`.

1. Set `CT := StartTime`
2. Set `V' := 0`

For each Period P:

1. Compute `X := T - CT`
2. IF `X >= P.Length`
   1. Compute `V' += P.Amount`
   2. Compute `CT += P.Length`
   3. ELSE break
3. Compute `V := OV - V'`

```go
func (pva PeriodicVestingAccount) GetVestedCoins(t Time) Coins {
  if t < pva.StartTime {
    return ZeroCoins
  }
  ct := pva.StartTime // The start of the vesting schedule
  vested := 0
  periods = pva.GetPeriods()
  for _, period  := range periods {
    if t - ct < period.Length {
      break
    }
    vested += period.Amount
    ct += period.Length // increment ct to the start of the next vesting period
  }
  return vested
}

func (pva PeriodicVestingAccount) GetVestingCoins(t Time) Coins {
    return pva.OriginalVesting - cva.GetVestedCoins(t)
}
```

**Delayed/Discrete Vesting Accounts**

Delayed vesting accounts are easier to reason about as they only have the full amount vesting up until a certain time, then all the coins become vested (unlocked). This does not include any unlocked coins the account may have initially.

```go
func (dva DelayedVestingAccount) GetVestedCoins(t Time) Coins {
    if t >= dva.EndTime {
        return dva.OriginalVesting
    }

    return ZeroCoins
}

func (dva DelayedVestingAccount) GetVestingCoins(t Time) Coins {
    return dva.OriginalVesting - dva.GetVestedCoins(t)
}
```

### Transferring/Sending <a href="#transferring-sending" id="transferring-sending"></a>

At any given time, a vesting account may transfer: `min((BC + DV) - V, BC)`.

In other words, a vesting account may transfer the minimum of the base account balance and the base account balance plus the number of currently delegated vesting coins less the number of coins vested so far.

However, given that account balances are tracked via the `x/bank` module and that we want to avoid loading the entire account balance, we can instead determine the locked balance, which can be defined as `max(V - DV, 0)`, and infer the spendable balance from that.

```go
func (va VestingAccount) LockedCoins(t Time) Coins {
   return max(va.GetVestingCoins(t) - va.DelegatedVesting, 0)
}
```

The `x/bank` `ViewKeeper` can then provide APIs to determine locked and spendable coins for any account:

```go
func (k Keeper) LockedCoins(ctx Context, addr AccAddress) Coins {
    acc := k.GetAccount(ctx, addr)
    if acc != nil {
        if acc.IsVesting() {
            return acc.LockedCoins(ctx.BlockTime())
        }
    }

    // non-vesting accounts do not have any locked coins
    return NewCoins()
}
```

**Keepers/Handlers**

The corresponding `x/bank` keeper should appropriately handle sending coins based on if the account is a vesting account or not.

```go
func (k Keeper) SendCoins(ctx Context, from Account, to Account, amount Coins) {
    bc := k.GetBalances(ctx, from)
    v := k.LockedCoins(ctx, from)

    spendable := bc - v
    newCoins := spendable - amount
    assert(newCoins >= 0)

    from.SetBalance(newCoins)
    to.AddBalance(amount)

    // save balances...
}
```

### Delegating <a href="#delegating" id="delegating"></a>

For a vesting account attempting to delegate `D` coins, the following is performed:

1. Verify `BC >= D > 0`
2. Compute `X := min(max(V - DV, 0), D)` (portion of `D` that is vesting)
3. Compute `Y := D - X` (portion of `D` that is free)
4. Set `DV += X`
5. Set `DF += Y`

```go
func (va VestingAccount) TrackDelegation(t Time, balance Coins, amount Coins) {
    assert(balance <= amount)
    x := min(max(va.GetVestingCoins(t) - va.DelegatedVesting, 0), amount)
    y := amount - x

    va.DelegatedVesting += x
    va.DelegatedFree += y
}
```

**Note:** `TrackDelegation` only modifies the `DelegatedVesting` and `DelegatedFree` fields, so upstream callers MUST modify the `Coins` field by subtracting `amount`.

**Keepers/Handlers**

```go
func DelegateCoins(t Time, from Account, amount Coins) {
    if isVesting(from) {
        from.TrackDelegation(t, amount)
    } else {
        from.SetBalance(sc - amount)
    }

    // save account...
}
```

### Undelegating <a href="#undelegating" id="undelegating"></a>

For a vesting account attempting to undelegate `D` coins, the following is performed: NOTE: `DV < D` and `(DV + DF) < D` may be possible due to quirks in the rounding of delegation/undelegation logic.

1. Verify `D > 0`
2. Compute `X := min(DF, D)` (portion of `D` that should become free, prioritizing free coins)
3. Compute `Y := min(DV, D - X)` (portion of `D` that should remain vesting)
4. Set `DF -= X`
5. Set `DV -= Y`

```go
func (cva ContinuousVestingAccount) TrackUndelegation(amount Coins) {
    x := min(cva.DelegatedFree, amount)
    y := amount - x

    cva.DelegatedFree -= x
    cva.DelegatedVesting -= y
}
```

**Note:** `TrackUnDelegation` only modifies the `DelegatedVesting` and `DelegatedFree` fields, so upstream callers MUST modify the `Coins` field by adding `amount`.

**Note**: If a delegation is slashed, the continuous vesting account ends up with an excess `DV` amount, even after all its coins have vested. This is because undelegating free coins are prioritized.

**Note**: The undelegation (bond refund) amount may exceed the delegated vesting (bond) amount due to the way undelegation truncates the bond refund, which can increase the validator's exchange rate (tokens/shares) slightly if the undelegated tokens are non-integral.

**Keepers/Handlers**

```go
func UndelegateCoins(to Account, amount Coins) {
    if isVesting(to) {
        if to.DelegatedFree + to.DelegatedVesting >= amount {
            to.TrackUndelegation(amount)
            // save account ...
        }
    } else {
        AddBalance(to, amount)
        // save account...
    }
}
```

### Keepers & Handlers <a href="#keepers-handlers-4" id="keepers-handlers-4"></a>

The `VestingAccount` implementations reside in `x/auth`. However, any keeper in a module (e.g. staking in `x/staking`) wishing to potentially utilize any vesting coins, must call explicit methods on the `x/bank` keeper (e.g. `DelegateCoins`) opposed to `SendCoins` and `SubtractCoins`.

In addition, the vesting account should also be able to spend any coins it receives from other users. Thus, the bank module's `MsgSend` handler should error if a vesting account is trying to send an amount that exceeds their unlocked coin amount.

See the above specification for full implementation details.

### Genesis Initialization <a href="#genesis-initialization" id="genesis-initialization"></a>

To initialize both vesting and non-vesting accounts, the `GenesisAccount` struct includes new fields: `Vesting`, `StartTime`, and `EndTime`. Accounts meant to be of type `BaseAccount` or any non-vesting type have `Vesting = false`. The genesis initialization logic (e.g. `initFromGenesisState`) must parse and return the correct accounts accordingly based off of these fields.

```go
type GenesisAccount struct {
    // ...

    // vesting account fields
    OriginalVesting  sdk.Coins `json:"original_vesting"`
    DelegatedFree    sdk.Coins `json:"delegated_free"`
    DelegatedVesting sdk.Coins `json:"delegated_vesting"`
    StartTime        int64     `json:"start_time"`
    EndTime          int64     `json:"end_time"`
}

func ToAccount(gacc GenesisAccount) Account {
    bacc := NewBaseAccount(gacc)

    if gacc.OriginalVesting > 0 {
        if ga.StartTime != 0 && ga.EndTime != 0 {
            // return a continuous vesting account
        } else if ga.EndTime != 0 {
            // return a delayed vesting account
        } else {
            // invalid genesis vesting account provided
            panic()
        }
    }

    return bacc
}
```

### Examples <a href="#examples" id="examples"></a>

#### Simple <a href="#simple" id="simple"></a>

Given a continuous vesting account with 10 vesting coins.

```
OV = 10
DF = 0
DV = 0
BC = 10
V = 10
V' = 0
```

1. Immediately receives 1 coin

```
BC = 11
```

&#x20; 2\. Time passes, 2 coins vest

```
V = 8
V' = 2
```

&#x20; 3\. Delegates 4 coins to validator A

```
DV = 4
BC = 7
```

&#x20; 4\. Sends 3 coins

```
BC = 4
```

&#x20; 5\. More time passes, 2 more coins vest

```
V = 6
V' = 4
```

&#x20; 6\. Sends 2 coins. At this point the account cannot send anymore until further coins vest or it receives additional coins. It can still however, delegate.

```
BC = 2
```

#### Slashing <a href="#slashing" id="slashing"></a>

Same initial starting conditions as the simple example.

1. Time passes, 5 coins vest

```
V = 5
V' = 5
```

&#x20; 2\. Delegate 5 coins to validator A

```
DV = 5
BC = 5
```

&#x20; 3\. Delegate 5 coins to validator B

```
DF = 5
BC = 0
```

&#x20; 4\. Validator A gets slashed by 50%, making the delegation to A now worth 2.5 coins

&#x20; 5\. Undelegate from validator A (2.5 coins)

```
DF = 5 - 2.5 = 2.5
BC = 0 + 2.5 = 2.5
```

&#x20; 6\. Undelegate from validator B (5 coins). The account at this point can only send 2.5 coins unless it receives more coins or until more coins vest. It can still however, delegate.

```
DV = 5 - 2.5 = 2.5
DF = 2.5 - 2.5 = 0
BC = 2.5 + 5 = 7.5
```

Notice how we have an excess amount of `DV`.

#### Periodic Vesting <a href="#periodic-vesting" id="periodic-vesting"></a>

A vesting account is created where 100 tokens will be released over 1 year, with 1/4 of tokens vesting each quarter. The vesting schedule would be as follows:

```
Periods:
- amount: 25stake, length: 7884000
- amount: 25stake, length: 7884000
- amount: 25stake, length: 7884000
- amount: 25stake, length: 7884000
```

```
OV = 100
DF = 0
DV = 0
BC = 100
V = 100
V' = 0
```

1. Immediately receives 1 coin

```
BC = 101
```

&#x20; 2\. Vesting period 1 passes, 25 coins vest

```
V = 75
V' = 25
```

&#x20; 3\. During vesting period 2, 5 coins are transferred and 5 coins are delegated

```
DV = 5
BC = 91
```

&#x20; 4\. Vesting period 2 passes, 25 coins vest

```
V = 50
V' = 50
```

### Glossary <a href="#glossary" id="glossary"></a>

* OriginalVesting: The amount of coins (per denomination) that are initially part of a vesting account. These coins are set at genesis.
* StartTime: The BFT time at which a vesting account starts to vest.
* EndTime: The BFT time at which a vesting account is fully vested.
* DelegatedFree: The tracked amount of coins (per denomination) that are delegated from a vesting account that have been fully vested at time of delegation.
* DelegatedVesting: The tracked amount of coins (per denomination) that are delegated from a vesting account that were vesting at time of delegation.
* ContinuousVestingAccount: A vesting account implementation that vests coins linearly over time.
* DelayedVestingAccount: A vesting account implementation that only fully vests all coins at a given time.
* PeriodicVestingAccount: A vesting account implementation that vests coins according to a custom vesting schedule.
* PermanentLockedAccount: It does not ever release coins, locking them indefinitely. Coins in this account can still be used for delegating and for governance votes even while locked.


# Parameters

The auth module contains the following parameters:

| Key                    | Type   | Example |
| ---------------------- | ------ | ------- |
| MaxMemoCharacters      | uint64 | 256     |
| TxSigLimit             | uint64 | 7       |
| TxSizeCostPerByte      | uint64 | 10      |
| SigVerifyCostED25519   | uint64 | 590     |
| SigVerifyCostSecp256k1 | uint64 | 1000    |


# Client Auth

### CLI <a href="#cli" id="cli"></a>

A user can query and interact with the `auth` module using the CLI.

#### Query <a href="#query" id="query"></a>

The `query` commands allow users to query `auth` state.

```bash
simd query auth --help
```

**account**

The `account` command allow users to query for an account by it's address.

```bash
simd query auth account [address] [flags]
```

Example:

```
simd query auth account cosmos1...
```

Example Output:

```bash
'@type': /cosmos.auth.v1beta1.BaseAccount
account_number: "0"
address: cosmos1zwg6tpl8aw4rawv8sgag9086lpw5hv33u5ctr2
pub_key:
  '@type': /cosmos.crypto.secp256k1.PubKey
  key: ApDrE38zZdd7wLmFS9YmqO684y5DG6fjZ4rVeihF/AQD
sequence: "1"
```

**accounts**

The `accounts` command allow users to query all the available accounts

```bash
simd query auth accounts [flags]
```

Example:

```bash
simd query auth accounts
```

Example Output:

```bash
accounts:
- '@type': /cosmos.auth.v1beta1.BaseAccount
  account_number: "0"
  address: cosmos1zwg6tpl8aw4rawv8sgag9086lpw5hv33u5ctr2
  pub_key:
    '@type': /cosmos.crypto.secp256k1.PubKey
    key: ApDrE38zZdd7wLmFS9YmqO684y5DG6fjZ4rVeihF/AQD
  sequence: "1"
- '@type': /cosmos.auth.v1beta1.ModuleAccount
  base_account:
    account_number: "8"
    address: cosmos1yl6hdjhmkf37639730gffanpzndzdpmhwlkfhr
    pub_key: null
    sequence: "0"
  name: transfer
  permissions:
  - minter
  - burner
- '@type': /cosmos.auth.v1beta1.ModuleAccount
  base_account:
    account_number: "4"
    address: cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh
    pub_key: null
    sequence: "0"
  name: bonded_tokens_pool
  permissions:
  - burner
  - staking
- '@type': /cosmos.auth.v1beta1.ModuleAccount
  base_account:
    account_number: "5"
    address: cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r
    pub_key: null
    sequence: "0"
  name: not_bonded_tokens_pool
  permissions:
  - burner
  - staking
- '@type': /cosmos.auth.v1beta1.ModuleAccount
  base_account:
    account_number: "6"
    address: cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn
    pub_key: null
    sequence: "0"
  name: gov
  permissions:
  - burner
- '@type': /cosmos.auth.v1beta1.ModuleAccount
  base_account:
    account_number: "3"
    address: cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl
    pub_key: null
    sequence: "0"
  name: distribution
  permissions: []
- '@type': /cosmos.auth.v1beta1.BaseAccount
  account_number: "1"
  address: cosmos147k3r7v2tvwqhcmaxcfql7j8rmkrlsemxshd3j
  pub_key: null
  sequence: "0"
- '@type': /cosmos.auth.v1beta1.ModuleAccount
  base_account:
    account_number: "7"
    address: cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q
    pub_key: null
    sequence: "0"
  name: mint
  permissions:
  - minter
- '@type': /cosmos.auth.v1beta1.ModuleAccount
  base_account:
    account_number: "2"
    address: cosmos17xpfvakm2amg962yls6f84z3kell8c5lserqta
    pub_key: null
    sequence: "0"
  name: fee_collector
  permissions: []
pagination:
  next_key: null
  total: "0"
```

**params**

The `params` command allow users to query the current auth parameters.

```bash
simd query auth params [flags]
```

Example:

```bash
simd query auth params
```

Example output:

```bash
max_memo_characters: "256"
sig_verify_cost_ed25519: "590"
sig_verify_cost_secp256k1: "1000"
tx_sig_limit: "7"
tx_size_cost_per_byte: "10"
```

### gRPC <a href="#grpc" id="grpc"></a>

A user can query the `auth` module using gRPC endpoints.

#### Account <a href="#account-2" id="account-2"></a>

The `account` endpoint allow users to query for an account by it's address.

```
cosmos.auth.v1beta1.Query/Account
```

Example:

```bash
grpcurl -plaintext \
    -d '{"address":"cosmos1.."}' \
    localhost:9090 \
    cosmos.auth.v1beta1.Query/Account
```

Example output:

```bash
{
  "account":{
    "@type":"/cosmos.auth.v1beta1.BaseAccount",
    "address":"cosmos1zwg6tpl8aw4rawv8sgag9086lpw5hv33u5ctr2",
    "pubKey":{
      "@type":"/cosmos.crypto.secp256k1.PubKey",
      "key":"ApDrE38zZdd7wLmFS9YmqO684y5DG6fjZ4rVeihF/AQD"
    },
    "sequence":"1"
  }
}
```

#### Accounts <a href="#accounts-2" id="accounts-2"></a>

The `accounts` endpoint allow users to query all the available accounts.

```bash
cosmos.auth.v1beta1.Query/Accounts
```

Example:

```bash
grpcurl -plaintext \
    localhost:9090 \
    cosmos.auth.v1beta1.Query/Accountsb
```

Example output:

```bash
{
   "accounts":[
      {
         "@type":"/cosmos.auth.v1beta1.BaseAccount",
         "address":"cosmos1zwg6tpl8aw4rawv8sgag9086lpw5hv33u5ctr2",
         "pubKey":{
            "@type":"/cosmos.crypto.secp256k1.PubKey",
            "key":"ApDrE38zZdd7wLmFS9YmqO684y5DG6fjZ4rVeihF/AQD"
         },
         "sequence":"1"
      },
      {
         "@type":"/cosmos.auth.v1beta1.ModuleAccount",
         "baseAccount":{
            "address":"cosmos1yl6hdjhmkf37639730gffanpzndzdpmhwlkfhr",
            "accountNumber":"8"
         },
         "name":"transfer",
         "permissions":[
            "minter",
            "burner"
         ]
      },
      {
         "@type":"/cosmos.auth.v1beta1.ModuleAccount",
         "baseAccount":{
            "address":"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh",
            "accountNumber":"4"
         },
         "name":"bonded_tokens_pool",
         "permissions":[
            "burner",
            "staking"
         ]
      },
      {
         "@type":"/cosmos.auth.v1beta1.ModuleAccount",
         "baseAccount":{
            "address":"cosmos1tygms3xhhs3yv487phx3dw4a95jn7t7lpm470r",
            "accountNumber":"5"
         },
         "name":"not_bonded_tokens_pool",
         "permissions":[
            "burner",
            "staking"
         ]
      },
      {
         "@type":"/cosmos.auth.v1beta1.ModuleAccount",
         "baseAccount":{
            "address":"cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn",
            "accountNumber":"6"
         },
         "name":"gov",
         "permissions":[
            "burner"
         ]
      },
      {
         "@type":"/cosmos.auth.v1beta1.ModuleAccount",
         "baseAccount":{
            "address":"cosmos1jv65s3grqf6v6jl3dp4t6c9t9rk99cd88lyufl",
            "accountNumber":"3"
         },
         "name":"distribution"
      },
      {
         "@type":"/cosmos.auth.v1beta1.BaseAccount",
         "accountNumber":"1",
         "address":"cosmos147k3r7v2tvwqhcmaxcfql7j8rmkrlsemxshd3j"
      },
      {
         "@type":"/cosmos.auth.v1beta1.ModuleAccount",
         "baseAccount":{
            "address":"cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q",
            "accountNumber":"7"
         },
         "name":"mint",
         "permissions":[
            "minter"
         ]
      },
      {
         "@type":"/cosmos.auth.v1beta1.ModuleAccount",
         "baseAccount":{
            "address":"cosmos17xpfvakm2amg962yls6f84z3kell8c5lserqta",
            "accountNumber":"2"
         },
         "name":"fee_collector"
      }
   ],
   "pagination":{
      "total":"9"
   }
}
```

#### Params <a href="#params-2" id="params-2"></a>

The `params` endpoint allow users to query the current auth parameters.

```bash
cosmos.auth.v1beta1.Query/Params
```

Example:

```
grpcurl -plaintext \
    localhost:9090 \
    cosmos.auth.v1beta1.Query/Params
```

Example output:

```bash
{
  "params": {
    "maxMemoCharacters": "256",
    "txSigLimit": "7",
    "txSizeCostPerByte": "10",
    "sigVerifyCostEd25519": "590",
    "sigVerifyCostSecp256k1": "1000"
  }
}
```

### REST <a href="#rest" id="rest"></a>

A user can query the `auth` module using REST endpoints.

#### Account <a href="#account-3" id="account-3"></a>

The `account` endpoint allow users to query for an account by it's address.

```bash
/cosmos/auth/v1beta1/account?address={address}
```

#### Accounts <a href="#accounts-3" id="accounts-3"></a>

The `accounts` endpoint allow users to query all the available accounts.

```
/cosmos/auth/v1beta1/accounts
```

#### Params <a href="#params-3" id="params-3"></a>

The `params` endpoint allow users to query the current auth parameters.

```
/cosmos/auth/v1beta1/params
```

## Vesting <a href="#vesting" id="vesting"></a>

### CLI <a href="#cli-2" id="cli-2"></a>

A user can query and interact with the `vesting` module using the CLI.

#### Transactions <a href="#transactions" id="transactions"></a>

The `tx` commands allow users to interact with the `vesting` module.

```bash
simd tx vesting --help
```

**create-periodic-vesting-account**

The `create-periodic-vesting-account` command creates a new vesting account funded with an allocation of tokens, where a sequence of coins and period length in seconds. Periods are sequential, in that the duration of of a period only starts at the end of the previous period. The duration of the first period starts upon account creation.

```bash
simd tx vesting create-periodic-vesting-account [to_address] [periods_json_file] [flags]
```

Example:

```bash
simd tx vesting create-periodic-vesting-account cosmos1.. periods.json
```

**create-vesting-account**

The `create-vesting-account` command creates a new vesting account funded with an allocation of tokens. The account can either be a delayed or continuous vesting account, which is determined by the '--delayed' flag. All vesting accounts created will have their start time set by the committed block's time. The end\_time must be provided as a UNI epoch timestamp.

```bash
simd tx vesting create-vesting-account [to_address] [amount] [end_time] [flags]
```

Example:

```bash
simd tx vesting create-vesting-account cosmos1.. 100stake 2592000
```


# bank

## `x/bank` <a href="#x-bank" id="x-bank"></a>

### Abstract <a href="#abstract" id="abstract"></a>

This document specifies the bank module of the Cosmos SDK.

The bank module is responsible for handling multi-asset coin transfers between accounts and tracking special-case pseudo-transfers which must work differently with particular kinds of accounts (notably delegating/undelegating for vesting accounts). It exposes several interfaces with varying capabilities for secure interaction with other modules which must alter user balances.

In addition, the bank module tracks and provides query support for the total supply of all assets used in the application.

This module will be used in the BlockX Chain.

### Supply <a href="#supply" id="supply"></a>

The `supply` functionality:

* passively tracks the total supply of coins within a chain,
* provides a pattern for modules to hold/interact with `Coins`, and
* introduces the invariant check to verify a chain's total supply.

#### Total Supply <a href="#total-supply" id="total-supply"></a>

The total `Supply` of the network is equal to the sum of all coins from the account. The total supply is updated every time a `Coin` is minted (eg: as part of the inflation mechanism) or burned (eg: due to slashing or if a governance proposal is vetoed).

### Module Accounts <a href="#module-accounts" id="module-accounts"></a>

The supply functionality introduces a new type of `auth.Account` which can be used by modules to allocate tokens and in special cases mint or burn tokens. At a base level these module accounts are capable of sending/receiving tokens to and from `auth.Account` and other module accounts.&#x20;

This design replaces previous alternative designs where, to hold tokens, modules would burn the incoming tokens from the sender account, and then track those tokens internally. Later, in order to send tokens, the module would need to effectively mint tokens within a destination account. The new design removes duplicate logic between modules to perform this accounting.

The `ModuleAccount` interface is defined as follows:

```go
type ModuleAccount interface {
  auth.Account               // same methods as the Account interface

  GetName() string           // name of the module; used to obtain the address
  GetPermissions() []string  // permissions of module account
  HasPermission(string) bool
}
```

{% hint style="warning" %}
**WARNING!** Any module or message handler that allows either direct or indirect sending of funds must explicitly guarantee those funds cannot be sent to module accounts (unless allowed).
{% endhint %}

The supply `Keeper` also introduces new wrapper functions for the auth `Keeper` and the bank `Keeper` that are related to `ModuleAccount` in order to be able to:

* Get and set `ModuleAccount` by providing the `Name`.
* Send coins from and to other `ModuleAccount` or standard `Account` (`BaseAccount` or `VestingAccount`) by passing only the `Name`.
* `Mint` or `Burn` coins for a `ModuleAccount` (restricted to its permissions).

#### Permissions <a href="#permissions" id="permissions"></a>

Each `ModuleAccount` has a different set of permissions that provide different object capabilities to perform certain actions. Permissions need to be registered upon the creation of the supply `Keeper` so that every time a `ModuleAccount` calls the allowed functions, the `Keeper` can lookup the permissions to that specific account and perform or not perform the action.

The available permissions are:

* `Minter`: allows for a module to mint a specific amount of coins.
* `Burner`: allows for a module to burn a specific amount of coins.
* `Staking`: allows for a module to delegate and undelegate a specific amount of coins.


# State

The `x/bank` module keeps state of the following primary objects:

1. Account balances
2. Denomination metadata
3. The total supply of all balances
4. Information on which denominations are allowed to be sent.

In addition, the `x/bank` module keeps the following indexes to manage the aforementioned state:

* Supply Index: `0x0 | byte(denom) -> byte(amount)`
* Denom Metadata Index: `0x1 | byte(denom) -> ProtocolBuffer(Metadata)`
* Balances Index: `0x2 | byte(address length) | []byte(address) | []byte(balance.Denom) -> ProtocolBuffer(balance)`
* Reverse Denomination to Address Index: `0x03 | byte(denom) | 0x00 | []byte(address) -> 0`

### Params <a href="#params" id="params"></a>

The bank module stores it's params in state with the prefix of `0x05`, it can be updated with governance or the address with authority.

* Params: `0x05 | ProtocolBuffer(Params)`

```protobuf
// Params defines the parameters for the bank module.
message Params {
  option (gogoproto.goproto_stringer)       = false;
  repeated SendEnabled send_enabled         = 1;
  bool                 default_send_enabled = 2;
}
```


# Keepers

The bank module provides these exported keeper interfaces that can be passed to other modules that read or update account balances. Modules should use the least-permissive interface that provides the functionality they require.

Best practices dictate careful review of `bank` module code to ensure that permissions are limited in the way that you expect.

### Blocklisting Addresses <a href="#blocklisting-addresses" id="blocklisting-addresses"></a>

The `x/bank` module accepts a map of addresses that are considered blocklisted from directly and explicitly receiving funds through means such as `MsgSend` and `MsgMultiSend` and direct API calls like `SendCoinsFromModuleToAccount`.

Typically, these addresses are module accounts. If these addresses receive funds outside the expected rules of the state machine, invariants are likely to be broken and could result in a halted network.

By providing the `x/bank` module with a blocklisted set of addresses, an error occurs for the operation if a user or client attempts to directly or indirectly send funds to a blocklisted account, for example, by using [IBC](https://ibc.cosmos.network).

### Common Types <a href="#common-types" id="common-types"></a>

#### Input <a href="#input" id="input"></a>

An input of a multiparty transfer

```protobuf
// Input models transaction input.
message Input {
  string   address                        = 1;
  repeated cosmos.base.v1beta1.Coin coins = 2;
}
```

#### Output <a href="#output" id="output"></a>

An output of a multiparty transfer.

```protobuf
// Output models transaction outputs.
message Output {
  string   address                        = 1;
  repeated cosmos.base.v1beta1.Coin coins = 2;
}
```

### BaseKeeper <a href="#basekeeper" id="basekeeper"></a>

The base keeper provides full-permission access: the ability to arbitrary modify any account's balance and mint or burn coins.

Restricted permission to mint per module could be achieved by using baseKeeper with `WithMintCoinsRestriction` to give specific restrictions to mint (e.g. only minting certain denom).

```go
// Keeper defines a module interface that facilitates the transfer of coins
// between accounts.
type Keeper interface {
    SendKeeper
    WithMintCoinsRestriction(MintingRestrictionFn) BaseKeeper

    InitGenesis(sdk.Context, *types.GenesisState)
    ExportGenesis(sdk.Context) *types.GenesisState

    GetSupply(ctx sdk.Context, denom string) sdk.Coin
    HasSupply(ctx sdk.Context, denom string) bool
    GetPaginatedTotalSupply(ctx sdk.Context, pagination *query.PageRequest) (sdk.Coins, *query.PageResponse, error)
    IterateTotalSupply(ctx sdk.Context, cb func(sdk.Coin) bool)
    GetDenomMetaData(ctx sdk.Context, denom string) (types.Metadata, bool)
    HasDenomMetaData(ctx sdk.Context, denom string) bool
    SetDenomMetaData(ctx sdk.Context, denomMetaData types.Metadata)
    IterateAllDenomMetaData(ctx sdk.Context, cb func(types.Metadata) bool)

    SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
    SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error
    SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
    DelegateCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
    UndelegateCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
    MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error
    BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error

    DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error
    UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error

    // GetAuthority gets the address capable of executing governance proposal messages. Usually the gov module account.
    GetAuthority() string

    types.QueryServer
}
```

### SendKeeper <a href="#sendkeeper" id="sendkeeper"></a>

The send keeper provides access to account balances and the ability to transfer coins between accounts. The send keeper does not alter the total supply (mint or burn coins).

```go
// SendKeeper defines a module interface that facilitates the transfer of coins
// between accounts without the possibility of creating coins.
type SendKeeper interface {
    ViewKeeper

    InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error
    SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error

    GetParams(ctx sdk.Context) types.Params
    SetParams(ctx sdk.Context, params types.Params) error

    IsSendEnabledDenom(ctx sdk.Context, denom string) bool
    SetSendEnabled(ctx sdk.Context, denom string, value bool)
    SetAllSendEnabled(ctx sdk.Context, sendEnableds []*types.SendEnabled)
    DeleteSendEnabled(ctx sdk.Context, denom string)
    IterateSendEnabledEntries(ctx sdk.Context, cb func(denom string, sendEnabled bool) (stop bool))
    GetAllSendEnabledEntries(ctx sdk.Context) []types.SendEnabled

    IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool
    IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error

    BlockedAddr(addr sdk.AccAddress) bool
}
```

### ViewKeeper <a href="#viewkeeper" id="viewkeeper"></a>

The view keeper provides read-only access to account balances. The view keeper does not have balance alteration functionality. All balance lookups are `O(1)`.

```go
// ViewKeeper defines a module interface that facilitates read only access to
// account balances.
type ViewKeeper interface {
    ValidateBalance(ctx sdk.Context, addr sdk.AccAddress) error
    HasBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coin) bool

    GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
    GetAccountsBalances(ctx sdk.Context) []types.Balance
    GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
    LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
    SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
    SpendableCoin(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin

    IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool))
    IterateAllBalances(ctx sdk.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool))
}
```


# Messages

### MsgSend <a href="#msgsend" id="msgsend"></a>

Send coins from one address to another.

```protobuf
// MsgSend represents a message to send coins from one account to another.
message MsgSend {
  option (cosmos.msg.v1.signer) = "from_address";

  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string   from_address                    = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string   to_address                      = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  repeated cosmos.base.v1beta1.Coin amount = 3
      [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}
```

The message will fail under the following conditions:

* The coins do not have sending enabled
* The `to` address is restricted

### MsgMultiSend <a href="#msgmultisend" id="msgmultisend"></a>

Send coins from and to a series of different address. If any of the receiving addresses do not correspond to an existing account, a new account is created.

```protobuf
// MsgMultiSend represents an arbitrary multi-in, multi-out send message.
message MsgMultiSend {
  option (cosmos.msg.v1.signer) = "inputs";

  option (gogoproto.equal) = false;

  repeated Input  inputs  = 1 [(gogoproto.nullable) = false];
  repeated Output outputs = 2 [(gogoproto.nullable) = false];
}
```

The message will fail under the following conditions:

* Any of the coins do not have sending enabled
* Any of the `to` addresses are restricted
* Any of the coins are locked
* The inputs and outputs do not correctly correspond to one another

### MsgUpdateParams <a href="#msgupdateparams" id="msgupdateparams"></a>

The `bank` module params can be updated through `MsgUpdateParams`, which can be done using governance proposal. The signer will always be the `gov` module account address.

```protobuf
// MsgUpdateParams is the Msg/UpdateParams request type.
//
// Since: cosmos-sdk 0.47
message MsgUpdateParams {
  option (cosmos.msg.v1.signer) = "authority";

  // authority is the address of the governance account.
  string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

  // params defines the x/bank parameters to update.
  //
  // NOTE: All parameters must be supplied.
  Params params = 2 [(gogoproto.nullable) = false];
}
```

The message handling can fail if:

* signer is not the gov module account address.


# Events

The bank module emits the following events:

### Handlers <a href="#handlers" id="handlers"></a>

#### MsgSend <a href="#msgsend" id="msgsend"></a>

| Type     | Attribute Key | Attribute Value |
| -------- | ------------- | --------------- |
| transfer | recipient     |                 |
| transfer | amount        |                 |
| message  | module        | bank            |
| message  | sender        | send            |
| message  | action        |                 |

#### MsgMultiSend <a href="#msgmultisend" id="msgmultisend"></a>

| Type     | Attribute Key | Attribute Value |
| -------- | ------------- | --------------- |
| transfer | recipient     |                 |
| transfer | amount        |                 |
| message  | module        | bank            |
| message  | sender        | multisend       |
| message  | action        |                 |

### Keeper events <a href="#keeper-events" id="keeper-events"></a>

In addition to handlers events, the bank keeper will produce events when the following methods are called (or any method which ends up calling them)

#### MintCoins <a href="#mintcoins" id="mintcoins"></a>

```json
{
  "type": "coinbase",
  "attributes": [
    {
      "key": "minter",
      "value": "{{sdk.AccAddress of the module minting coins}}",
      "index": true
    },
    {
      "key": "amount",
      "value": "{{sdk.Coins being minted}}",
      "index": true
    }
  ]
}
```

```json
{
  "type": "coin_received",
  "attributes": [
    {
      "key": "receiver",
      "value": "{{sdk.AccAddress of the module minting coins}}",
      "index": true
    },
    {
      "key": "amount",
      "value": "{{sdk.Coins being received}}",
      "index": true
    }
  ]
}
```

#### BurnCoins

```json
{
  "type": "burn",
  "attributes": [
    {
      "key": "burner",
      "value": "{{sdk.AccAddress of the module burning coins}}",
      "index": true
    },
    {
      "key": "amount",
      "value": "{{sdk.Coins being burned}}",
      "index": true
    }
  ]
}
```

```json5
{
  "type": "coin_spent",
  "attributes": [
    {
      "key": "spender",
      "value": "{{sdk.AccAddress of the module burning coins}}",
      "index": true
    },
    {
      "key": "amount",
      "value": "{{sdk.Coins being burned}}",
      "index": true
    }
  ]
}
```

#### addCoins

```json
{
  "type": "coin_received",
  "attributes": [
    {
      "key": "receiver",
      "value": "{{sdk.AccAddress of the address beneficiary of the coins}}",
      "index": true
    },
    {
      "key": "amount",
      "value": "{{sdk.Coins being received}}",
      "index": true
    }
  ]
}
```

#### subUnlockedCoins/DelegateCoins <a href="#subunlockedcoins-delegatecoins" id="subunlockedcoins-delegatecoins"></a>

```json
{
  "type": "coin_spent",
  "attributes": [
    {
      "key": "spender",
      "value": "{{sdk.AccAddress of the address which is spending coins}}",
      "index": true
    },
    {
      "key": "amount",
      "value": "{{sdk.Coins being spent}}",
      "index": true
    }
  ]
}
```


# Parameters

The bank module contains the following parameters:

| Key                | Type           | Example      |
| ------------------ | -------------- | ------------ |
| SendEnabled        | \[]SendEnabled | (deprecated) |
| DefaultSendEnabled | bool           | true         |

### SendEnabled <a href="#sendenabled" id="sendenabled"></a>

The SendEnabled parameter is now deprecated and not to be use. It is replaced with state store records.

### DefaultSendEnabled <a href="#defaultsendenabled" id="defaultsendenabled"></a>

The default send enabled value controls send transfer capability for all coin denominations unless specifically included in the array of `SendEnabled` parameters.


# Client

### CLI <a href="#cli" id="cli"></a>

A user can query and interact with the `bank` module using the CLI.

#### Query <a href="#query" id="query"></a>

The `query` commands allow users to query `bank` state.

```bash
simd query bank --help
```

**balances**

The `balances` command allows users to query account balances by address.

```bash
simd query bank balances [address] [flags]
```

Example:

```bash
simd query bank balances cosmos1..
```

Example output:

```bash
balances:
- amount: "1000000000"
  denom: stake
pagination:
  next_key: null
  total: "0"
```

**denom-metadata**

The `denom-metadata` command allows users to query metadata for coin denominations. A user can query metadata for a single denomination using the `--denom` flag or all denominations without it.

```bash
simd query bank denom-metadata [flags]
```

Example:

```bash
simd query bank denom-metadata --denom stake
```

Example output:

```bash
metadata:
  base: stake
  denom_units:
  - aliases:
    - STAKE
    denom: stake
  description: native staking token of simulation app
  display: stake
  name: SimApp Token
  symbol: STK
```

**total**

The `total` command allows users to query the total supply of coins. A user can query the total supply for a single coin using the `--denom` flag or all coins without it.

```bash
simd query bank total [flags]
```

Example:

```bash
simd query bank total --denom stake
```

Example output:

```
amount: "10000000000"
denom: stake
```

**send-enabled**

The `send-enabled` command allows users to query for all or some SendEnabled entries.

```bash
simd query bank send-enabled [denom1 ...] [flags]
```

Example:

```
simd query bank send-enabled
```

Example output:

```
send_enabled:
- denom: foocoin
  enabled: true
- denom: barcoin
pagination:
  next-key: null
  total: 2 
```

#### Transactions <a href="#transactions" id="transactions"></a>

The `tx` commands allow users to interact with the `bank` module.

```bash
simd tx bank --help
```

**send**

The `send` command allows users to send funds from one account to another.

```
simd tx bank send [from_key_or_address] [to_address] [amount] [flags]
```

Example:

```
simd tx bank send cosmos1.. cosmos1.. 100stake
```

### gRPC <a href="#grpc" id="grpc"></a>

A user can query the `bank` module using gRPC endpoints.

#### Balance <a href="#balance" id="balance"></a>

The `Balance` endpoint allows users to query account balance by address for a given denomination.

```
cosmos.bank.v1beta1.Query/Balance
```

Example:

```
grpcurl -plaintext \
    -d '{"address":"cosmos1..","denom":"stake"}' \
    localhost:9090 \
    cosmos.bank.v1beta1.Query/Balance
```

Example output:

```bash
{
  "balance": {
    "denom": "stake",
    "amount": "1000000000"
  }
}
```

#### AllBalances <a href="#allbalances" id="allbalances"></a>

The `AllBalances` endpoint allows users to query account balance by address for all denominations.

```
cosmos.bank.v1beta1.Query/AllBalances
```

Example:

```
grpcurl -plaintext \
    -d '{"address":"cosmos1.."}' \
    localhost:9090 \
    cosmos.bank.v1beta1.Query/AllBalancesn
```

Example output:

```bash
{
  "balances": [
    {
      "denom": "stake",
      "amount": "1000000000"
    }
  ],
  "pagination": {
    "total": "1"
  }
}
```

#### DenomMetadata <a href="#denommetadata" id="denommetadata"></a>

The `DenomMetadata` endpoint allows users to query metadata for a single coin denomination.

```
cosmos.bank.v1beta1.Query/DenomMetadata
```

Example:

```
grpcurl -plaintext \
    -d '{"denom":"stake"}' \
    localhost:9090 \
    cosmos.bank.v1beta1.Query/DenomMetadata
```

Example output:

```bash
{
  "metadata": {
    "description": "native staking token of simulation app",
    "denomUnits": [
      {
        "denom": "stake",
        "aliases": [
          "STAKE"
        ]
      }
    ],
    "base": "stake",
    "display": "stake",
    "name": "SimApp Token",
    "symbol": "STK"
  }
}
```

#### DenomsMetadata <a href="#denomsmetadata" id="denomsmetadata"></a>

The `DenomsMetadata` endpoint allows users to query metadata for all coin denominations.

```bash
cosmos.bank.v1beta1.Query/DenomsMetadata
```

Example:

```
grpcurl -plaintext \
    localhost:9090 \
    cosmos.bank.v1beta1.Query/DenomsMetadata
```

Example output:

```bash
{
  "metadatas": [
    {
      "description": "native staking token of simulation app",
      "denomUnits": [
        {
          "denom": "stake",
          "aliases": [
            "STAKE"
          ]
        }
      ],
      "base": "stake",
      "display": "stake",
      "name": "SimApp Token",
      "symbol": "STK"
    }
  ],
  "pagination": {
    "total": "1"
  }
}
```

#### DenomOwners <a href="#denomowners" id="denomowners"></a>

The `DenomOwners` endpoint allows users to query metadata for a single coin denomination.

```
cosmos.bank.v1beta1.Query/DenomOwners
```

Example:

```
grpcurl -plaintext \
    -d '{"denom":"stake"}' \
    localhost:9090 \
    cosmos.bank.v1beta1.Query/DenomOwners
```

Example output:

```bash
{
  "denomOwners": [
    {
      "address": "cosmos1..",
      "balance": {
        "denom": "stake",
        "amount": "5000000000"
      }
    },
    {
      "address": "cosmos1..",
      "balance": {
        "denom": "stake",
        "amount": "5000000000"
      }
    },
  ],
  "pagination": {
    "total": "2"
  }
}
```

#### TotalSupply <a href="#totalsupply" id="totalsupply"></a>

The `TotalSupply` endpoint allows users to query the total supply of all coins.

```
cosmos.bank.v1beta1.Query/TotalSupply
```

Example:

```
grpcurl -plaintext \
    localhost:9090 \
    cosmos.bank.v1beta1.Query/TotalSupply
```

Example output:

```bash
{
  "supply": [
    {
      "denom": "stake",
      "amount": "10000000000"
    }
  ],
  "pagination": {
    "total": "1"
  }
}
```

#### SupplyOf <a href="#supplyof" id="supplyof"></a>

The `SupplyOf` endpoint allows users to query the total supply of a single coin.

```
cosmos.bank.v1beta1.Query/SupplyOf
```

Example:

```
grpcurl -plaintext \
    -d '{"denom":"stake"}' \
    localhost:9090 \
    cosmos.bank.v1beta1.Query/SupplyOf
```

Example output:

```bash
{
  "amount": {
    "denom": "stake",
    "amount": "10000000000"
  }
}
```

#### Params <a href="#params" id="params"></a>

The `Params` endpoint allows users to query the parameters of the `bank` module.

```
cosmos.bank.v1beta1.Query/Params
```

Example:

```
grpcurl -plaintext \
    localhost:9090 \
    cosmos.bank.v1beta1.Query/Params
```

Example output:

```bash
{
  "params": {
    "defaultSendEnabled": true
  }
}
```

#### SendEnabled <a href="#sendenabled" id="sendenabled"></a>

The `SendEnabled` enpoints allows users to query the SendEnabled entries of the `bank` module.

Any denominations NOT returned, use the `Params.DefaultSendEnabled` value.

```
cosmos.bank.v1beta1.Query/SendEnabled
```

Example:

```
grpcurl -plaintext \
    localhost:9090 \
    cosmos.bank.v1beta1.Query/SendEnabled
```

Example output:

```bash
{
  "send_enabled": [
    {
      "denom": "foocoin",
      "enabled": true
    },
    {
      "denom": "barcoin"
    }
  ],
  "pagination": {
    "next-key": null,
    "total": 2
  }
}
```


# crisis

## `crisis` <a href="#crisis" id="crisis"></a>

### Overview <a href="#overview" id="overview"></a>

The crisis module halts the blockchain under the circumstance that a blockchain invariant is broken. Invariants can be registered with the application during the application initialization process.


# State

### ConstantFee <a href="#constantfee" id="constantfee"></a>

Due to the anticipated large gas cost requirement to verify an invariant (and potential to exceed the maximum allowable block gas limit) a constant fee is used instead of the standard gas consumption method. The constant fee is intended to be larger than the anticipated gas cost of running the invariant with the standard gas consumption method.

The ConstantFee param is stored in the module params state with the prefix of `0x01`, it can be updated with governance or the address with authority.

* Params: `mint/params -> legacy_amino(sdk.Coin)`


# Messages

In this section we describe the processing of the crisis messages and the corresponding updates to the state.

### MsgVerifyInvariant <a href="#msgverifyinvariant" id="msgverifyinvariant"></a>

Blockchain invariants can be checked using the `MsgVerifyInvariant` message.

```protobuf
// MsgVerifyInvariant represents a message to verify a particular invariance.
message MsgVerifyInvariant {
  option (cosmos.msg.v1.signer) = "sender";

  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string sender                = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string invariant_module_name = 2;
  string invariant_route       = 3;
}
```

This message is expected to fail if:

* the sender does not have enough coins for the constant fee
* the invariant route is not registered

This message checks the invariant provided, and if the invariant is broken it panics, halting the blockchain. If the invariant is broken, the constant fee is never deducted as the transaction is never committed to a block (equivalent to being refunded). However, if the invariant is not broken, the constant fee will not be refunded.


# Events

The crisis module emits the following events:

### Handlers <a href="#handlers" id="handlers"></a>

#### MsgVerifyInvariance <a href="#msgverifyinvariance" id="msgverifyinvariance"></a>

| Type      | Attribute Key | Attribute Value   |
| --------- | ------------- | ----------------- |
| invariant | route         |                   |
| message   | module        | crisis            |
| message   | action        | verify\_invariant |
| message   | sender        |                   |


# Parameters

The crisis module contains the following parameters:

| Key         | Type          | Example |
| ----------- | ------------- | ------- |
| ConstantFee | object (coin) |         |


# Client

### CLI <a href="#cli" id="cli"></a>

A user can query and interact with the `crisis` module using the CLI.

#### Transactions <a href="#transactions" id="transactions"></a>

The `tx` commands allow users to interact with the `crisis` module.

```bash
simd tx crisis --help
```

**invariant-broken**

The `invariant-broken` command submits proof when an invariant was broken to halt the chain

```bash
simd tx crisis invariant-broken [module-name] [invariant-route] [flags]
```

Example:

```bash
simd tx crisis invariant-broken bank total-supply --from=[keyname or address]
```


# distribution

## `distribution` <a href="#distribution" id="distribution"></a>

### Overview <a href="#overview" id="overview"></a>

This *simple* distribution mechanism describes a functional way to passively distribute rewards between validators and delegators. Note that this mechanism does not distribute funds in as precisely as active reward distribution mechanisms and will therefore be upgraded in the future.

The mechanism operates as follows. Collected rewards are pooled globally and divided out passively to validators and delegators. Each validator has the opportunity to charge commission to the delegators on the rewards collected on behalf of the delegators.&#x20;

Fees are collected directly into a global reward pool and validator proposer-reward pool. Due to the nature of passive accounting, whenever changes to parameters which affect the rate of reward distribution occurs, withdrawal of rewards must also occur.

* Whenever withdrawing, one must withdraw the maximum amount they are entitled to, leaving nothing in the pool.
* Whenever bonding, unbonding, or re-delegating tokens to an existing account, a full withdrawal of the rewards must occur (as the rules for lazy accounting change).
* Whenever a validator chooses to change the commission on rewards, all accumulated commission rewards must be simultaneously withdrawn.

The above scenarios are covered in `hooks.md`.

The distribution mechanism outlined herein is used to lazily distribute the following rewards between validators and associated delegators:

* multi-token fees to be socially distributed
* inflated staked asset provisions
* validator commission on all rewards earned by their delegators stake

Fees are pooled within a global pool. The mechanisms used allow for validators and delegators to independently and lazily withdraw their rewards.

### Shortcomings <a href="#shortcomings" id="shortcomings"></a>

As a part of the lazy computations, each delegator holds an accumulation term specific to each validator which is used to estimate what their approximate fair portion of tokens held in the global fee pool is owed to them.

```
entitlement = delegator-accumulation / all-delegators-accumulation
```

Under the circumstance that there was constant and equal flow of incoming reward tokens every block, this distribution mechanism would be equal to the active distribution (distribute individually to all delegators each block). However, this is unrealistTo learn more, see the F1 Fee Distribution paper.ic so deviations from the active distribution will occur based on fluctuations of incoming reward tokens as well as timing of reward withdrawal by other delegators.

If you happen to know that incoming rewards are about to significantly increase, you are incentivized to not withdraw until after this event, increasing the worth of your existing *accum*.&#x20;

### Effect on Staking <a href="#effect-on-staking" id="effect-on-staking"></a>

Charging commission on Atom provisions while also allowing for Atom-provisions to be auto-bonded (distributed directly to the validators bonded stake) is problematic within BPoS. Fundamentally, these two mechanisms are mutually exclusive.&#x20;

If both commission and auto-bonding mechanisms are simultaneously applied to the staking-token then the distribution of staking-tokens between any validator and its delegators will change with each block. This then necessitates a calculation for each delegation records for each block - which is considered computationally expensive.

In conclusion, we can only have Atom commission and unbonded atoms provisions or bonded atom provisions with no Atom commission, and we elect to implement the former. Stakeholders wishing to rebond their provisions may elect to set up a script to periodically withdraw and rebond rewards.


# Concepts

In Proof of Stake (PoS) blockchains, rewards gained from transaction fees are paid to validators. The fee distribution module fairly distributes the rewards to the validators' constituent delegators.

Rewards are calculated per period. The period is updated each time a validator's delegation changes, for example, when the validator receives a new delegation. The rewards for a single validator can then be calculated by taking the total rewards for the period before the delegation started, minus the current total rewards.

The commission to the validator is paid when the validator is removed or when the validator requests a withdrawal. The commission is calculated and incremented at every `BeginBlock` operation to update accumulated fee amounts.

The rewards to a delegator are distributed when the delegation is changed or removed, or a withdrawal is requested. Before rewards are distributed, all slashes to the validator that occurred during the current delegation are applied.

### Reference Counting in F1 Fee Distribution <a href="#reference-counting-in-f1-fee-distribution" id="reference-counting-in-f1-fee-distribution"></a>

In F1 fee distribution, the rewards a delegator receives are calculated when their delegation is withdrawn. This calculation must read the terms of the summation of rewards divided by the share of tokens from the period which they ended when they delegated, and the final period that was created for the withdrawal.

Additionally, as slashes change the amount of tokens a delegation will have (but we calculate this lazily, only when a delegator un-delegates), we must calculate rewards in separate periods before / after any slashes which occurred in between when a delegator delegated and when they withdrew their rewards. Thus slashes, like delegations, reference the period which was ended by the slash event.

All stored historical rewards records for periods which are no longer referenced by any delegations or any slashes can thus be safely removed, as they will never be read (future delegations and future slashes will always reference future periods). This is implemented by tracking a `ReferenceCount` along with each historical reward storage entry.&#x20;

Each time a new object (delegation or slash) is created which might need to reference the historical record, the reference count is incremented. Each time one object which previously needed to reference the historical record is deleted, the reference count is decremented. If the reference count hits zero, the historical record is deleted.


# State

### FeePool <a href="#feepool" id="feepool"></a>

All globally tracked parameters for distribution are stored within `FeePool`. Rewards are collected and added to the reward pool and distributed to validators/delegators from here.

Note that the reward pool holds decimal coins (`DecCoins`) to allow for fractions of coins to be received from operations like inflation. When coins are distributed from the pool they are truncated back to `sdk.Coins` which are non-decimal.

* FeePool: `0x00 -> ProtocolBuffer(FeePool)`

```go
// coins with decimal
type DecCoins []DecCoin

type DecCoin struct {
    Amount sdk.Dec
    Denom  string
}
```

```protobuf
// FeePool is the global fee pool for distribution.
message FeePool {
  repeated cosmos.base.v1beta1.DecCoin community_pool = 1
      [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"];
}
```

### Validator Distribution <a href="#validator-distribution" id="validator-distribution"></a>

Validator distribution information for the relevant validator is updated each time:

1. delegation amount to a validator is updated,
2. any delegator withdraws from a validator, or
3. the validator withdraws its commission.

* ValidatorDistInfo: `0x02 | ValOperatorAddrLen (1 byte) | ValOperatorAddr -> ProtocolBuffer(validatorDistribution)`

```go
type ValidatorDistInfo struct {
    OperatorAddress     sdk.AccAddress
    SelfBondRewards     sdk.DecCoins
    ValidatorCommission types.ValidatorAccumulatedCommission
}
```

### Delegation Distribution <a href="#delegation-distribution" id="delegation-distribution"></a>

Each delegation distribution only needs to record the height at which it last withdrew fees. Because a delegation must withdraw fees each time it's properties change (aka bonded tokens etc.) its properties will remain constant and the delegator's *accumulation* factor can be calculated passively knowing only the height of the last withdrawal and its current properties.

* DelegationDistInfo: `0x02 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValOperatorAddrLen (1 byte) | ValOperatorAddr -> ProtocolBuffer(delegatorDist)`

```go
type DelegationDistInfo struct {
    WithdrawalHeight int64    // last time this delegation withdrew rewards
}
```

### Params <a href="#params" id="params"></a>

The distribution module stores it's params in state with the prefix of `0x09`, it can be updated with governance or the address with authority.

* Params: `0x09 | ProtocolBuffer(Params)`

```protobuf
// Params defines the set of params for the distribution module.
message Params {
  option (gogoproto.goproto_stringer) = false;
  string community_tax                = 1 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  string base_proposer_reward = 2 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  string bonus_proposer_reward = 3 [
    (cosmos_proto.scalar)  = "cosmos.Dec",
    (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
    (gogoproto.nullable)   = false
  ];
  bool withdraw_addr_enabled = 4;
}
```


# Begin Block

At each `BeginBlock`, all fees received in the previous block are transferred to the distribution `ModuleAccount` account. When a delegator or validator withdraws their rewards, they are taken out of the `ModuleAccount`. During begin block, the different claims on the fees collected are updated as follows:

* The reserve community tax is charged.
* The remainder is distributed proportionally by voting power to all bonded validators

### The Distribution Scheme <a href="#the-distribution-scheme" id="the-distribution-scheme"></a>

Let `fees` be the total fees collected in the previous block, including inflationary rewards to the stake. All fees are collected in a specific module account during the block. During `BeginBlock`, they are sent to the `"distribution"` `ModuleAccount`.&#x20;

No other sending of tokens occurs. Instead, the rewards each account is entitled to are stored, and withdrawals can be triggered through the messages `FundCommunityPool`, `WithdrawValidatorCommission` and `WithdrawDelegatorReward`.

#### Reward to the Community Pool <a href="#reward-to-the-community-pool" id="reward-to-the-community-pool"></a>

The community pool gets `community_tax * fees`, plus any remaining dust after validators get their rewards that are always rounded down to the nearest integer value.

#### Reward To the Validators <a href="#reward-to-the-validators" id="reward-to-the-validators"></a>

The proposer receives no extra rewards. All fees are distributed among all the bonded validators, including the proposer, in proportion to their consensus power.

```
powFrac = validator power / total bonded validator power
voteMul = 1 - community_tax
```

#### Rewards to Delegators <a href="#rewards-to-delegators" id="rewards-to-delegators"></a>

Each validator's rewards are distributed to its delegators. The validator also has a self-delegation that is treated like a regular delegation in distribution calculations.

The validator sets a commission rate. The commission rate is flexible, but each validator sets a maximum rate and a maximum daily increase. These maximums cannot be exceeded and protect delegators from sudden increases of validator commission rates to prevent validators from taking all of the rewards.

The outstanding rewards that the operator is entitled to are stored in `ValidatorAccumulatedCommission`, while the rewards the delegators are entitled to are stored in `ValidatorCurrentRewards`. The F1 fee distribution scheme is used to calculate the rewards per delegator as they withdraw or update their delegation, and is thus not handled in `BeginBlock`.

#### Example Distribution <a href="#example-distribution" id="example-distribution"></a>

For this example distribution, the underlying consensus engine selects block proposers in proportion to their power relative to the entire bonded power.

All validators are equally performant at including pre-commits in their proposed blocks. Then hold `(pre_commits included) / (total bonded validator power)` constant so that the amortized block reward for the validator is `( validator power / total bonded power) * (1 - community tax rate)` of the total rewards. Consequently, the reward for a single delegator is:

```
(delegator proportion of the validator power / validator power) * (validator power / total bonded power)
  * (1 - community tax rate) * (1 - validator commission rate)
= (delegator proportion of the validator power / total bonded power) * (1 -
community tax rate) * (1 - validator commission rate)
```


# Messages

### MsgSetWithdrawAddress <a href="#msgsetwithdrawaddress" id="msgsetwithdrawaddress"></a>

By default, the withdraw address is the delegator address. To change its withdraw address, a delegator must send a `MsgSetWithdrawAddress` message. Changing the withdraw address is possible only if the parameter `WithdrawAddrEnabled` is set to `true`.

The withdraw address cannot be any of the module accounts. These accounts are blocked from being withdraw addresses by being added to the distribution keeper's `blockedAddrs` array at initialization.

Response:

```protobuf
// MsgSetWithdrawAddress sets the withdraw address for
// a delegator (or validator self-delegation).
message MsgSetWithdrawAddress {
  option (cosmos.msg.v1.signer) = "delegator_address";

  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string withdraw_address  = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
```

```go
func (k Keeper) SetWithdrawAddr(ctx sdk.Context, delegatorAddr sdk.AccAddress, withdrawAddr sdk.AccAddress) error
	if k.blockedAddrs[withdrawAddr.String()] {
		fail with "`{withdrawAddr}` is not allowed to receive external funds"
	}

	if !k.GetWithdrawAddrEnabled(ctx) {
		fail with `ErrSetWithdrawAddrDisabled`
	}

	k.SetDelegatorWithdrawAddr(ctx, delegatorAddr, withdrawAddr)
```

### MsgWithdrawDelegatorReward <a href="#msgwithdrawdelegatorreward" id="msgwithdrawdelegatorreward"></a>

A delegator can withdraw its rewards. Internally in the distribution module, this transaction simultaneously removes the previous delegation with associated rewards, the same as if the delegator simply started a new delegation of the same value. The rewards are sent immediately from the distribution `ModuleAccount` to the withdraw address.&#x20;

Any remainder (truncated decimals) are sent to the community pool. The starting height of the delegation is set to the current validator period, and the reference count for the previous period is decremented. The amount withdrawn is deducted from the `ValidatorOutstandingRewards` variable for the validator.

In the F1 distribution, the total rewards are calculated per validator period, and a delegator receives a piece of those rewards in proportion to their stake in the validator. In basic F1, the total rewards that all the delegators are entitled to between to periods is calculated the following way.&#x20;

Let `R(X)` be the total accumulated rewards up to period `X` divided by the tokens staked at that time. The delegator allocation is `R(X) * delegator_stake`. Then the rewards for all the delegators for staking between periods `A` and `B` are `(R(B) - R(A)) * total stake`. However, these calculated rewards don't account for slashing.

Taking the slashes into account requires iteration. Let `F(X)` be the fraction a validator is to be slashed for a slashing event that happened at period `X`. If the validator was slashed at periods `P1, ..., PN`, where `A < P1`, `PN < B`, the distribution module calculates the individual delegator's rewards, `T(A, B)`, as follows:

```go
stake := initial stake
rewards := 0
previous := A
for P in P1, ..., PN`:
    rewards = (R(P) - previous) * stake
    stake = stake * F(P)
    previous = P
rewards = rewards + (R(B) - R(PN)) * stake
```

The historical rewards are calculated retroactively by playing back all the slashes and then attenuating the delegator's stake at each step. The final calculated stake is equivalent to the actual staked coins in the delegation with a margin of error due to rounding errors.

Response:

```protobuf
// MsgWithdrawDelegatorReward represents delegation withdrawal to a delegator
// from a single validator.
message MsgWithdrawDelegatorReward {
  option (cosmos.msg.v1.signer) = "delegator_address";

  option (gogoproto.equal)           = false;
  option (gogoproto.goproto_getters) = false;

  string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
  string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
```

### WithdrawValidatorCommission <a href="#withdrawvalidatorcommission" id="withdrawvalidatorcommission"></a>

The validator can send the WithdrawValidatorCommission message to withdraw their accumulated commission. The commission is calculated in every block during `BeginBlock`, so no iteration is required to withdraw.&#x20;

The amount withdrawn is deducted from `ValidatorOutstandingRewards` variable for the validator. Only integer amounts can be sent. If the accumulated awards have decimals, the amount is truncated before the withdrawal is sent, and the remainder is left to be withdrawn later.

### FundCommunityPool <a href="#fundcommunitypool" id="fundcommunitypool"></a>

This message sends coins directly from the sender to the community pool.

The transaction fails if the amount cannot be transferred from the sender to the distribution module account.

```go
func (k Keeper) FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error {
    if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, amount); err != nil {
        return err
    }

	feePool := k.GetFeePool(ctx)
	feePool.CommunityPool = feePool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...)
	k.SetFeePool(ctx, feePool)

	return nil
}
```

### Common distribution operations <a href="#common-distribution-operations" id="common-distribution-operations"></a>

These operations take place during many different messages.

#### Initialize delegation <a href="#initialize-delegation" id="initialize-delegation"></a>

Each time a delegation is changed, the rewards are withdrawn and the delegation is reinitialized. Initializing a delegation increments the validator period and keeps track of the starting period of the delegation.

```go
// initialize starting info for a new delegation
func (k Keeper) initializeDelegation(ctx sdk.Context, val sdk.ValAddress, del sdk.AccAddress) {
    // period has already been incremented - we want to store the period ended by this delegation action
    previousPeriod := k.GetValidatorCurrentRewards(ctx, val).Period - 1

	// increment reference count for the period we're going to track
	k.incrementReferenceCount(ctx, val, previousPeriod)

	validator := k.stakingKeeper.Validator(ctx, val)
	delegation := k.stakingKeeper.Delegation(ctx, del, val)

	// calculate delegation stake in tokens
	// we don't store directly, so multiply delegation shares * (tokens per share)
	// note: necessary to truncate so we don't allow withdrawing more rewards than owed
	stake := validator.TokensFromSharesTruncated(delegation.GetShares())
	k.SetDelegatorStartingInfo(ctx, val, del, types.NewDelegatorStartingInfo(previousPeriod, stake, uint64(ctx.BlockHeight())))
}
```

### MsgUpdateParams <a href="#msgupdateparams" id="msgupdateparams"></a>

Distribution module params can be updated through `MsgUpdateParams`, which can be done using governance proposal and the signer will always be gov module account address.

```protobuf
// MsgUpdateParams is the Msg/UpdateParams request type.
//
// Since: cosmos-sdk 0.47
message MsgUpdateParams {
  option (cosmos.msg.v1.signer) = "authority";

  // authority is the address of the governance account.
  string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

  // params defines the x/distribution parameters to update.
  //
  // NOTE: All parameters must be supplied.
  Params params = 2 [(gogoproto.nullable) = false];
}
```

The message handling can fail if:

* signer is not the gov module account address.


# Hooks

Available hooks that can be called by and from this module.

### Create or modify delegation distribution <a href="#create-or-modify-delegation-distribution" id="create-or-modify-delegation-distribution"></a>

* triggered-by: `staking.MsgDelegate`, `staking.MsgBeginRedelegate`, `staking.MsgUndelegate`

#### Before <a href="#before" id="before"></a>

* The delegation rewards are withdrawn to the withdraw address of the delegator. The rewards include the current period and exclude the starting period.
* The validator period is incremented. The validator period is incremented because the validator's power and share distribution might have changed.
* The reference count for the delegator's starting period is decremented.

#### After <a href="#after" id="after"></a>

The starting height of the delegation is set to the previous period. Because of the `Before`-hook, this period is the last period for which the delegator was rewarded.

### Validator created <a href="#validator-created" id="validator-created"></a>

* triggered-by: `staking.MsgCreateValidator`

When a validator is created, the following validator variables are initialized:

* Historical rewards
* Current accumulated rewards
* Accumulated commission
* Total outstanding rewards
* Period

By default, all values are set to a `0`, except period, which is set to `1`.

### Validator removed <a href="#validator-removed" id="validator-removed"></a>

* triggered-by: `staking.RemoveValidator`

Outstanding commission is sent to the validator's self-delegation withdrawal address. Remaining delegator rewards get sent to the community fee pool.

Note: The validator gets removed only when it has no remaining delegations. At that time, all outstanding delegator rewards will have been withdrawn. Any remaining rewards are dust amounts.

### Validator is slashed <a href="#validator-is-slashed" id="validator-is-slashed"></a>

* triggered-by: `staking.Slash`
* The current validator period reference count is incremented. The reference count is incremented because the slash event has created a reference to it.
* The validator period is incremented.
* The slash event is stored for later use. The slash event will be referenced when calculating delegator rewards.


# Events

The distribution module emits the following events:

### BeginBlocker <a href="#beginblocker" id="beginblocker"></a>

| Type             | Attribute Key | Attribute Value |
| ---------------- | ------------- | --------------- |
| proposer\_reward | validator     |                 |
| proposer\_reward | reward        |                 |
| commission       | amount        |                 |
| commission       | validator     |                 |
| rewards          | amount        |                 |
| rewards          | validator     |                 |

### Handlers <a href="#handlers" id="handlers"></a>

#### MsgSetWithdrawAddress <a href="#msgsetwithdrawaddress" id="msgsetwithdrawaddress"></a>

| Type                   | Attribute Key     | Attribute Value        |
| ---------------------- | ----------------- | ---------------------- |
| set\_withdraw\_address | withdraw\_address |                        |
| message                | module            | distribution           |
| message                | action            | set\_withdraw\_address |
| message                | sender            |                        |

#### MsgWithdrawDelegatorReward <a href="#msgwithdrawdelegatorreward" id="msgwithdrawdelegatorreward"></a>

| Type              | Attribute Key | Attribute Value             |
| ----------------- | ------------- | --------------------------- |
| withdraw\_rewards | amount        |                             |
| withdraw\_rewards | validator     |                             |
| message           | module        | distribution                |
| message           | action        | withdraw\_delegator\_reward |
| message           | sender        |                             |

#### MsgWithdrawValidatorCommission <a href="#msgwithdrawvalidatorcommission" id="msgwithdrawvalidatorcommission"></a>

| Type                 | Attribute Key | Attribute Value                 |
| -------------------- | ------------- | ------------------------------- |
| withdraw\_commission | amount        |                                 |
| message              | module        | distribution                    |
| message              | action        | withdraw\_validator\_commission |
| message              | sender        |                                 |


# Parameters

The distribution module contains the following parameters:

| Key                 | Type         | Example                     |
| ------------------- | ------------ | --------------------------- |
| communitytax        | string (dec) | "0.020000000000000000" \[0] |
| baseproposerreward  | string (dec) | "0.010000000000000000" \[0] |
| bonusproposerreward | string (dec) | "0.040000000000000000" \[0] |
| withdrawaddrenabled | bool         | true                        |

* \[0] `communitytax`, `baseproposerreward` and `bonusproposerreward` must be positive and their sum cannot exceed 1.00.


# Client

### CLI <a href="#cli" id="cli"></a>

A user can query and interact with the `distribution` module using the CLI.

#### Query <a href="#query" id="query"></a>

The `query` commands allow users to query `distribution` state.

```
simd query distribution --help
```

**commission**

The `commission` command allows users to query validator commission rewards by address.

```
simd query distribution commission [address] [flags]
```

Example:

```
simd query distribution commission cosmosvaloper1..
```

Example output:

```
commission:
- amount: "1000000.000000000000000000"
  denom: stake
```

**community-pool**

The `community-pool` command allows users to query all coin balances within the community pool.

```
simd query distribution community-pool [flags]
```

Example:

```
simd query distribution community-pool
```

Example output:

```
pool:
- amount: "1000000.000000000000000000"
  denom: stake
```

**params**

The `params` command allows users to query the parameters of the `distribution` module.

```
simd query distribution params [flags]
```

Example:

```
simd query distribution params
```

Example output:

```
base_proposer_reward: "0.010000000000000000"
bonus_proposer_reward: "0.040000000000000000"
community_tax: "0.020000000000000000"
withdraw_addr_enabled: true
```

**rewards**

The `rewards` command allows users to query delegator rewards. Users can optionally include the validator address to query rewards earned from a specific validator.

```
simd query distribution rewards [delegator-addr] [validator-addr] [flags]
```

Example:

```
simd query distribution rewards cosmos1..
```

Example output:

```
rewards:
- reward:
  - amount: "1000000.000000000000000000"
    denom: stake
  validator_address: cosmosvaloper1..
total:
- amount: "1000000.000000000000000000"
  denom: stake
```

**slashes**

The `slashes` command allows users to query all slashes for a given block range.

```
simd query distribution slashes [validator] [start-height] [end-height] [flags]
```

Example:

```
simd query distribution slashes cosmosvaloper1.. 1 1000
```

Example output:

```
pagination:
  next_key: null
  total: "0"
slashes:
- validator_period: 20,
  fraction: "0.009999999999999999"
```

**validator-outstanding-rewards**

The `validator-outstanding-rewards` command allows users to query all outstanding (un-withdrawn) rewards for a validator and all their delegations.

```
simd query distribution validator-outstanding-rewards [validator] [flags]
```

Example:

```
simd query distribution validator-outstanding-rewards cosmosvaloper1..
```

Example output:

```
rewards:
- amount: "1000000.000000000000000000"
  denom: stake
```

#### Transactions <a href="#transactions" id="transactions"></a>

The `tx` commands allow users to interact with the `distribution` module.

```
simd tx distribution --help
```

**fund-community-pool**

The `fund-community-pool` command allows users to send funds to the community pool.

```
simd tx distribution fund-community-pool [amount] [flags]
```

Example:

```
simd tx distribution fund-community-pool 100stake --from cosmos1..
```

**set-withdraw-addr**

The `set-withdraw-addr` command allows users to set the withdraw address for rewards associated with a delegator address.

```
simd tx distribution set-withdraw-addr [withdraw-addr] [flags]
```

Example:

```
simd tx distribution set-withdraw-addr cosmos1.. --from cosmos1..
```

**withdraw-all-rewards**

The `withdraw-all-rewards` command allows users to withdraw all rewards for a delegator.

```
simd tx distribution withdraw-all-rewards [flags]
```

Example:

```
simd tx distribution withdraw-all-rewards --from cosmos1..
```

**withdraw-rewards**

The `withdraw-rewards` command allows users to withdraw all rewards from a given delegation address, and optionally withdraw validator commission if the delegation address given is a validator operator and the user proves the `--commision` flag.

```
simd tx distribution withdraw-rewards [validator-addr] [flags]
```

Example:

```
simd tx distribution withdraw-rewards cosmosvaloper1.. --from cosmos1.. --commision
```

### gRPC <a href="#grpc" id="grpc"></a>

A user can query the `distribution` module using gRPC endpoints.

#### Params <a href="#params-2" id="params-2"></a>

The `Params` endpoint allows users to query parameters of the `distribution` module.

Example:

```
grpcurl -plaintext \
    localhost:9090 \
    cosmos.distribution.v1beta1.Query/Params
```

Example output:

```json
{
  "params": {
    "communityTax": "20000000000000000",
    "baseProposerReward": "10000000000000000",
    "bonusProposerReward": "40000000000000000",
    "withdrawAddrEnabled": true
  }
}
```

#### ValidatorOutstandingRewards <a href="#validatoroutstandingrewards" id="validatoroutstandingrewards"></a>

The `ValidatorOutstandingRewards` endpoint allows users to query rewards of a validator address.

Example:

```
grpcurl -plaintext \
    -d '{"validator_address":"cosmosvalop1.."}' \
    localhost:9090 \
    cosmos.distribution.v1beta1.Query/ValidatorOutstandingRewards
```

Example output:

```json
{
  "rewards": {
    "rewards": [
      {
        "denom": "stake",
        "amount": "1000000000000000"
      }
    ]
  }
}
```

#### ValidatorCommission <a href="#validatorcommission" id="validatorcommission"></a>

The `ValidatorCommission` endpoint allows users to query accumulated commission for a validator.

Example:

```
grpcurl -plaintext \
    -d '{"validator_address":"cosmosvalop1.."}' \
    localhost:9090 \
    cosmos.distribution.v1beta1.Query/ValidatorCommission
```

Example output:

```json
{
  "commission": {
    "commission": [
      {
        "denom": "stake",
        "amount": "1000000000000000"
      }
    ]
  }
}
```

#### ValidatorSlashes <a href="#validatorslashes" id="validatorslashes"></a>

The `ValidatorSlashes` endpoint allows users to query slash events of a validator.

Example:

```
grpcurl -plaintext \
    -d '{"validator_address":"cosmosvalop1.."}' \
    localhost:9090 \
    cosmos.distribution.v1beta1.Query/ValidatorSlashes
```

Example output:

```json
{
  "slashes": [
    {
      "validator_period": "20",
      "fraction": "0.009999999999999999"
    }
  ],
  "pagination": {
    "total": "1"
  }
}
```

#### DelegationRewards <a href="#delegationrewards" id="delegationrewards"></a>

The `DelegationRewards` endpoint allows users to query the total rewards accrued by a delegation.

Example:

```
grpcurl -plaintext \
    -d '{"delegator_address":"cosmos1..","validator_address":"cosmosvalop1.."}' \
    localhost:9090 \
    cosmos.distribution.v1beta1.Query/DelegationRewards
```

Example output:

```json
{
  "rewards": [
    {
      "denom": "stake",
      "amount": "1000000000000000"
    }
  ]
}
```

#### DelegationTotalRewards <a href="#delegationtotalrewards" id="delegationtotalrewards"></a>

The `DelegationTotalRewards` endpoint allows users to query the total rewards accrued by each validator.

Example:

```
grpcurl -plaintext \
    -d '{"delegator_address":"cosmos1.."}' \
    localhost:9090 \
    cosmos.distribution.v1beta1.Query/DelegationTotalRewards
```

Example output:

```json
{
  "rewards": [
    {
      "validatorAddress": "cosmosvaloper1..",
      "reward": [
        {
          "denom": "stake",
          "amount": "1000000000000000"
        }
      ]
    }
  ],
  "total": [
    {
      "denom": "stake",
      "amount": "1000000000000000"
    }
  ]
}
```

#### DelegatorValidators <a href="#delegatorvalidators" id="delegatorvalidators"></a>

The `DelegatorValidators` endpoint allows users to query all validators for given delegator.

Example:

```
grpcurl -plaintext \
    -d '{"delegator_address":"cosmos1.."}' \
    localhost:9090 \
    cosmos.distribution.v1beta1.Query/DelegatorValidators
```

Example output:

```json
{
  "validators": [
    "cosmosvaloper1.."
  ]
}
```

#### DelegatorWithdrawAddress <a href="#delegatorwithdrawaddress" id="delegatorwithdrawaddress"></a>

The `DelegatorWithdrawAddress` endpoint allows users to query the withdraw address of a delegator.

Example:

```
grpcurl -plaintext \
    -d '{"delegator_address":"cosmos1.."}' \
    localhost:9090 \
    cosmos.distribution.v1beta1.Query/DelegatorWithdrawAddress
```

Example output:

```json
{
  "withdrawAddress": "cosmos1.."
}
```

#### CommunityPool <a href="#communitypool" id="communitypool"></a>

The `CommunityPool` endpoint allows users to query the community pool coins.

Example:

```bash
grpcurl -plaintext \
    localhost:9090 \
    cosmos.distribution.v1beta1.Query/CommunityPool
```

Example output:

```json
{
  "pool": [
    {
      "denom": "stake",
      "amount": "1000000000000000000"
    }
  ]
}
```


# epochs

### Abstract <a href="#abstract" id="abstract"></a>

This document specifies the internal `x/epochs` module of the BlockX Chain.

Often, when working with the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk), we would like to run certain pieces of code every so often.

The purpose of the `epochs` module is to allow other modules to maintain that they would like to be signaled once in a time period. So, another module can specify it wants to execute certain code once a week, starting at UTC-time = x. `epochs` creates a generalized epoch interface to other modules so they can be more easily signaled upon such events.


# Concepts

The `epochs` module defines on-chain timers that execute at fixed time intervals. Other BlockX modules can then register logic to be executed at the timer ticks. We refer to the period in between two timer ticks as an "epoch".

Every timer has a unique identifier, and every epoch will have a start time and an end time, where `end time = start time + timer interval`.


# State

### State Objects <a href="#state-objects" id="state-objects"></a>

The `x/epochs` module keeps the following `objects in state`:

| State Object | Description         | Key                  | Value               | Store |
| ------------ | ------------------- | -------------------- | ------------------- | ----- |
| `EpochInfo`  | Epoch info bytecode | `[]byte{identifier}` | `[]byte{epochInfo}` | KV    |

#### EpochInfo <a href="#epochinfo" id="epochinfo"></a>

An `EpochInfo` defines several variables:

1. `identifier` keeps an epoch identification string
2. `start_time` keeps the start time for epoch counting: if block height passes `start_time`, then `epoch_counting_started` is set
3. `duration` keeps the target epoch duration
4. `current_epoch` keeps the current active epoch number
5. `current_epoch_start_time` keeps the start time of the current epoch
6. `epoch_counting_started` is a flag set with `start_time`, at which point `epoch_number` will be counted
7. `current_epoch_start_height` keeps the start block height of the current epoch

```protobuf
message EpochInfo {
    string identifier = 1;
    google.protobuf.Timestamp start_time = 2 [
        (gogoproto.stdtime) = true,
        (gogoproto.nullable) = false,
        (gogoproto.moretags) = "yaml:\"start_time\""
    ];
    google.protobuf.Duration duration = 3 [
        (gogoproto.nullable) = false,
        (gogoproto.stdduration) = true,
        (gogoproto.jsontag) = "duration,omitempty",
        (gogoproto.moretags) = "yaml:\"duration\""
    ];
    int64 current_epoch = 4;
    google.protobuf.Timestamp current_epoch_start_time = 5 [
        (gogoproto.stdtime) = true,
        (gogoproto.nullable) = false,
        (gogoproto.moretags) = "yaml:\"current_epoch_start_time\""
    ];
    bool epoch_counting_started = 6;
    reserved 7;
    int64 current_epoch_start_height = 8;
}
```

The `epochs` module keeps these `EpochInfo` objects in state, which are initialized at genesis and are modified on begin blockers or end blockers.

#### Genesis State <a href="#genesis-state" id="genesis-state"></a>

The `x/epochs` module's `GenesisState` defines the state necessary for initializing the chain from a previously exported height. It contains a slice containing all the `EpochInfo` objects kept in state:

```go
// Genesis State defines the epoch module's genesis state
type GenesisState struct {
    // list of EpochInfo structs corresponding to all epochs
	Epochs []EpochInfo `protobuf:"bytes,1,rep,name=epochs,proto3" json:"epochs"`
}
```


# Events

The `x/epochs` module emits the following events:

### BeginBlocker <a href="#beginblocker" id="beginblocker"></a>

| Type          | Attribute Key    | Attribute Value  |
| ------------- | ---------------- | ---------------- |
| `epoch_start` | `"epoch_number"` | `{epoch_number}` |
| `epoch_start` | `"start_time"`   | `{start_time}`   |

### EndBlocker <a href="#endblocker" id="endblocker"></a>

| Type        | Attribute Key    | Attribute Value  |
| ----------- | ---------------- | ---------------- |
| `epoch_end` | `"epoch_number"` | `{epoch_number}` |


# Keepers

The `x/epochs` module only exposes one keeper, the epochs keeper, which can be used to manage epochs.

### Epochs Keeper <a href="#epochs-keeper" id="epochs-keeper"></a>

Presently only one fully-permissioned epochs keeper is exposed, which has the ability to both read and write the `EpochInfo` for all epochs, and to iterate over all stored epochs.

```go
// Keeper of epoch nodule maintains collections of epochs and hooks.
type Keeper struct {
	cdc      codec.Codec
	storeKey sdk.StoreKey
	hooks    types.EpochHooks
}
```

```go
// Keeper is the interface for epoch module keeper
type Keeper interface {
  // GetEpochInfo returns epoch info by identifier
  GetEpochInfo(ctx sdk.Context, identifier string) types.EpochInfo

  // SetEpochInfo set epoch info
  SetEpochInfo(ctx sdk.Context, epoch types.EpochInfo)

  // DeleteEpochInfo delete epoch info
  DeleteEpochInfo(ctx sdk.Context, identifier string)

  // IterateEpochInfo iterate through epochs
  IterateEpochInfo(ctx sdk.Context, fn func(index int64, epochInfo types.EpochInfo) (stop bool))

  // Get all epoch infos
  AllEpochInfos(ctx sdk.Context) []types.EpochInfo
}
```


# Hooks

The `x/epochs` module implements hooks so that other modules can use epochs to allow facets of the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) to run on specific schedules.

### Hooks Implementation <a href="#hooks-implementation" id="hooks-implementation"></a>

```go
// combine multiple epoch hooks, all hook functions are run in array sequence
type MultiEpochHooks []types.EpochHooks

// AfterEpochEnd is called when epoch is going to be ended, epochNumber is the
// number of epoch that is ending
func (mh MultiEpochHooks) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64) {...}

// BeforeEpochStart is called when epoch is going to be started, epochNumber is
// the number of epoch that is starting
func (mh MultiEpochHooks) BeforeEpochStart(ctx sdk.Context, epochIdentifier string, epochNumber int64) {...}

// AfterEpochEnd executes the indicated hook after epochs ends
func (k Keeper) AfterEpochEnd(ctx sdk.Context, identifier string, epochNumber int64) {...}

// BeforeEpochStart executes the indicated hook before the epochs
func (k Keeper) BeforeEpochStart(ctx sdk.Context, identifier string, epochNumber int64) {...}
```

### Recieving Hooks <a href="#recieving-hooks" id="recieving-hooks"></a>

When other modules (outside of `x/epochs`) recieve hooks, they need to filter the value `epochIdentifier`, and only do executions for a specific `epochIdentifier`.

The filtered values from `epochIdentifier` could be stored in the `Params` of other modules, so they can be modified by governance.

Governance can change epoch periods from `week` to `day` as needed.


# Queries

The `x/epochs` module provides the following queries to check the module's state.

```protobuf
service Query {
  // EpochInfos provide running epochInfos
  rpc EpochInfos(QueryEpochsInfoRequest) returns (QueryEpochsInfoResponse) {}
  // CurrentEpoch provide current epoch of specified identifier
  rpc CurrentEpoch(QueryCurrentEpochRequest) returns (QueryCurrentEpochResponse) {}
}
```


# Future Improvements

### Correct Usage <a href="#correct-usage" id="correct-usage"></a>

In the current design, each epoch should be at least two blocks, as the start block should be different from the endblock. Because of this, the time allocated to each epoch will be `max(block_time x 2, epoch_duration)`. For example: if the `epoch_duration` is set to `1s`, and `block_time` is `5s`, actual epoch time should be `10s`.

It is recommended to configure `epoch_duration` to be more than two times the `block_time`, to use this module correctly. If there is a mismatch between the `epoch_duration` and the actual epoch time, as in the example above, then module logic could become invalid.

### Block-Time Drifts <a href="#block-time-drifts" id="block-time-drifts"></a>

This implementation of the `x/epochs` module has block-time drifts based on the value of `block_time`. For example: if we have an epoch of 100 units that ends at `t=100`, and we have a block at `t=97` and a block at `t=104` and `t=110`, this epoch ends at `t=104`, and the new epoch will start at `t=110`.

There are time drifts here, varying about 1-2 blocks time, which will slow down epochs.


# erc20

### Abstract <a href="#abstract" id="abstract"></a>

This document specifies the internal `x/erc20` module of the BlockX Chain.

The `x/erc20` module enables the BlockX Chain to support a trustless, on-chain bidirectional internal conversion of tokens between BlockX' EVM and Cosmos runtimes, specifically the `x/evm` and `x/bank` modules.&#x20;

This allows token holders on BlockX to instantaneously convert their native Cosmos `sdk.Coins` (in this document referred to as "Coin(s)") to ERC-20 (aka "Token(s)") and vice versa, while retaining fungibility with the original asset on the issuing environment/runtime (EVM or Cosmos) and preserving ownership of the ERC-20 contract.

This conversion functionality is fully governed by native $BCX token holders who manage the canonical `TokenPair` registrations (ie, ERC20 ←→ Coin mappings). This governance functionality is implemented using the Cosmos-SDK `gov` module with custom proposal types for registering and updating the canonical mappings respectively.

Why is this important? Cosmos and the EVM are two runtimes that are not compatible by default. The native Cosmos Coins cannot be used in applications that require the ERC-20 standard. Cosmos coins are held on the `x/bank` module (with access to module methods like querying the supply or balances) and ERC-20 Tokens live on smart contracts. This problem is similar to [wETH](https://weth.io/), with the difference, that it not only applies to gas tokens (like $BCX), but to all Cosmos Coins (IBC vouchers, staking and gov coins, etc.) as well.

With the `x/erc20` users on BlockX can

* use existing native cosmos assets (like $OSMO or $ATOM) on EVM-based chains, e.g. for Trading IBC tokens on DeFi protocols, buying NFT, etc.
* transfer existing tokens on Ethereum and other EVM-based chains to BlockX to take advantage of application-specific chains in the Cosmos ecosystem
* build new applications that are based on ERC-20 smart contracts and have access to the Cosmos ecosystem.


# Concepts

### Token Pair <a href="#token-pair" id="token-pair"></a>

The `x/erc20` module maintains a canonical one-to-one mapping of native Cosmos Coin denomination to ERC20 Token contract addresses (i.e `sdk.Coin` ←→ ERC20), called `TokenPair`. The conversion of the ERC20 tokens ←→ Coin of a given pair can be enabled or disabled via governance.

### Token Pair Registration <a href="#token-pair-registration" id="token-pair-registration"></a>

Users can register a new token pair proposal through the governance module and initiate a vote to include the token pair in the module. Depending on which exists first, the coin or the token, you can either register a Cosmos Coin or a ERC20 Token to create a token pair.

When the proposal passes, the erc20 module registers the Cosmos Coin and ERC20 Token mapping on the application's store.

#### Registration of a Cosmos Coin <a href="#registration-of-a-cosmos-coin" id="registration-of-a-cosmos-coin"></a>

A native Cosmos Coin corresponds to an `sdk.Coin` that is native to the bank module. It can be either the native staking/gas denomination (eg: BCX, ATOM, etc) or an IBC fungible token voucher (i.e with denom format of `ibc/{hash}`).

When a proposal is initiated for an existing native Cosmos Coin, the erc20 module will deploy a factory ERC20 contract, representing the ERC20 token for the token pair, giving the module ownership of that contract.

#### Registration of an ERC20 token <a href="#registration-of-an-erc20-token" id="registration-of-an-erc20-token"></a>

A proposal for an existing (i.e already deployed) ERC20 contract can be initiated too. In this case, the ERC20 maintains the original owner of the contract and uses an escrow & mint / burn & unescrow mechanism similar to the one defined by the [ICS20 - Fungible Token Transfer ](https://github.com/cosmos/ibc/blob/master/spec/app/ics-020-fungible-token-transfer)specification. The token pair is composed of the original ERC20 token and a corresponding native Cosmos coin denomination.

#### Token details and metadata <a href="#token-details-and-metadata" id="token-details-and-metadata"></a>

Coin metadata is derived from the ERC20 token details (name, symbol, decimals) and vice versa. A special case is also described below that for the ERC20 representation of IBC fungible token (ICS20) vouchers.

**Coin Metadata to ERC20 details**

During the registration of a Cosmos Coin the following bank `Metadata` is used to deploy a ERC20 contract:

* **Name**
* **Symbol**
* **Decimals**

The native Cosmos Coin contains a more extensive metadata than the ERC20 and includes all necessary details for the conversion into a ERC20 Token, which requires no additional population of data.

**IBC voucher Metadata to ERC20 details**

IBC vouchers should comply to the following standard:

* **Name**: `{NAME} channel-{channel}`
* **Symbol**: `ibc{NAME}-{channel}`
* **Decimals**: derived from bank `Metadata`

**ERC20 details to Coin Metadata**

During the Registration of an ERC20 Token the Coin metadata is derived from the ERC20 metadata and the bank metadata:

* **Description**: `Cosmos coin token representation of {contractAddress}`
* **DenomUnits**:
  * Coin: `0`
  * ERC20: `{uint32(erc20Data.Decimals)}`
* **Base**: `{"erc20/%s", address}`
* **Display**: `{erc20Data.Name}`
* **Name**: `{types.CreateDenom(strContract)}`
* **Symbol:** `{erc20Data.Symbol}`

### Token Pair Modifiers <a href="#token-pair-modifiers" id="token-pair-modifiers"></a>

A valid token pair can be modified through several governance proposals. The internal conversion of a token pair can be toggled with `ToggleTokenConversionProposal`, so that the conversions between the token pair's tokens can be enabled or disabled.

### Token Conversion <a href="#token-conversion" id="token-conversion"></a>

Once a token pair proposal passes, the module allows for the conversion of that token pair. Holders of native Cosmos coins and IBC vouchers on the Evmos chain can convert their Coin into ERC20 Tokens, which can then be used in BlockX EVM, by creating a `ConvertCoin` Tx. Vice versa, the `ConvertERC20` Tx allows holders of ERC20 tokens on the BlockX chain to convert ERC-20 tokens back to their native Cosmos Coin representation.

Depending on the ownership of the ERC20 contract, the ERC20 tokens either follow a burn/mint or a transfer/escrow mechanism during conversion.

### Malicious Contracts <a href="#malicious-contracts" id="malicious-contracts"></a>

The ERC20 standard is an interface that defines a set of method signatures (name, arguments and output) without defining its methods' internal logic. Therefore it is possible for developers to deploy contracts that contain hidden malicious behavior within those methods.&#x20;

For instance, the ERC20 `transfer` method, which is responsible for sending an `amount` of tokens to a given `recipient` could include code to siphon some amount of tokens intended for the recipient into a different predefined account, which is owned by the malicious contract deployer.

More sophisticated malicious implementations might also inherit code from customized ERC20 contracts that include malicious behavior. For an overview of more extensive examples, please review the x/erc20 audit, section `IF-EVMOS-06: IERC20 Contracts may execute arbitrary code`.

As the `x/erc20` module allows any arbitrary ERC20 contract to be registered through governance, it is essential that the proposer or the voters manually verify during voting phase that the proposed contract uses the default ERC20.sol implementation.

Here are our recommendations for the reviewing process:

* contract solidity code should be verified and accessible (e.g. using an explorer)
* contract should be audited by a reputable auditor
* inherited contracts need to be verified for correctness


# State

### State Objects <a href="#state-objects" id="state-objects"></a>

The `x/erc20` module keeps the following objects in state:

| State Object       | Description                                    | Key                         | Value               | Store |
| ------------------ | ---------------------------------------------- | --------------------------- | ------------------- | ----- |
| `TokenPair`        | Token Pair bytecode                            | `[]byte{1} + []byte(id)`    | `[]byte{tokenPair}` | KV    |
| `TokenPairByERC20` | Token Pair id bytecode by erc20 contract bytes | `[]byte{2} + []byte(erc20)` | `[]byte(id)`        | KV    |
| `TokenPairByDenom` | Token Pair id bytecode by denom string         | `[]byte{3} + []byte(denom)` | `[]byte(id)`        | KV    |

#### Token Pair <a href="#token-pair" id="token-pair"></a>

One-to-one mapping of native Cosmos coin denomination to ERC20 token contract addresses (i.e `sdk.Coin` ←→ ERC20).

```go
type TokenPair struct {
	// address of ERC20 contract token
	Erc20Address string `protobuf:"bytes,1,opt,name=erc20_address,json=erc20Address,proto3" json:"erc20_address,omitempty"`
	// cosmos base denomination to be mapped to
	Denom string `protobuf:"bytes,2,opt,name=denom,proto3" json:"denom,omitempty"`
	// shows token mapping enable status
	Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3" json:"enabled,omitempty"`
	// ERC20 owner address ENUM (0 invalid, 1 ModuleAccount, 2 external address
	ContractOwner Owner `protobuf:"varint,4,opt,name=contract_owner,json=contractOwner,proto3,enum=blockx.erc20.v1.Owner" json:"contract_owner,omitempty"`
}
```

#### Token pair ID <a href="#token-pair-id" id="token-pair-id"></a>

The unique identifier of a `TokenPair` is obtained by obtaining the SHA256 hash of the ERC20 hex contract address and the Coin denomination using the following function:

```go
tokenPairId = sha256(erc20 + "|" + denom)
```

#### Token Origin <a href="#token-origin" id="token-origin"></a>

The `ConvertCoin` and `ConvertERC20` functionalities use the owner field to check whether the token being used is a native Coin or a native ERC20. The field is based on the token registration proposal type (`RegisterCoinProposal` = 1, `RegisterERC20Proposal` = 2).

The `Owner` enumerates the ownership of a ERC20 contract.

```go
type Owner int32

const (
	// OWNER_UNSPECIFIED defines an invalid/undefined owner.
	OWNER_UNSPECIFIED Owner = 0
	// OWNER_MODULE erc20 is owned by the erc20 module account.
	OWNER_MODULE Owner = 1
	// EXTERNAL erc20 is owned by an external account.
	OWNER_EXTERNAL Owner = 2
)
```

The `Owner` can be checked with the following helper functions:

```go
// IsNativeCoin returns true if the owner of the ERC20 contract is the
// erc20 module account
func (tp TokenPair) IsNativeCoin() bool {
	return tp.ContractOwner == OWNER_MODULE
}

// IsNativeERC20 returns true if the owner of the ERC20 contract not the
// erc20 module account
func (tp TokenPair) IsNativeERC20() bool {
	return tp.ContractOwner == OWNER_EXTERNAL
}
```

#### Token Pair by ERC20 and by Denom <a href="#token-pair-by-erc20-and-by-denom" id="token-pair-by-erc20-and-by-denom"></a>

`TokenPairByERC20` and `TokenPairByDenom` are additional state objects for querying a token pair id.

### Genesis State <a href="#genesis-state" id="genesis-state"></a>

The `x/erc20` module's `GenesisState` defines the state necessary for initializing the chain from a previous exported height. It contains the module parameters and the registered token pairs :

```go
// GenesisState defines the module's genesis state.
type GenesisState struct {
	// module parameters
	Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
	// registered token pairs
	TokenPairs []TokenPair `protobuf:"bytes,2,rep,name=token_pairs,json=tokenPairs,proto3" json:"token_pairs"`
}
```


# State Transitions

The erc20 modules allows for two types of registration state transitions. Depending on how token pairs are registered, with `RegisterCoinProposal` or `RegisterERC20Proposal`, there are four possible conversion state transitions.

### Token Pair Registration <a href="#token-pair-registration" id="token-pair-registration"></a>

#### 1. Register Coin <a href="#id-1-register-coin" id="id-1-register-coin"></a>

A user registers a native Cosmos Coin. Once the proposal passes (i.e is Approval by governance), the ERC20 module uses a factory pattern to deploy an ERC20 token contract representation of the Cosmos Coin.&#x20;

Note that the native BlockX coin cannot be registered, as any coin including "evm" in its denomination cannot be registered. Instead the BlockX token can be converted by Nomand's wrapped BlockX (WBCX) contract.

1. User submits a `RegisterCoinProposal`
2. Validators of the BlockX Chain vote on the proposal using `MsgVote` and proposal passes
3. If Cosmos coin or IBC voucher exist on the bank module supply, create the ERC20 token contract on the EVM based on the ERC20Mintable ([ERC20Mintable by openzeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20)) interface
   * Initial supply: 0
   * Token details (Name, Symbol, Decimals, etc) are derived from the bank module `Metadata` field on the proposal content.

#### 2. Register ERC20 <a href="#id-2-register-erc20" id="id-2-register-erc20"></a>

A user registers a ERC20 token contract that is already deployed on the EVM module. Once the proposal passes (i.e is approved by governance), the ERC20 module creates a Cosmos coin representation of the ERC20 token.

1. User submits a `RegisterERC20Proposal`
2. Validators of the BlockX chain vote on the proposal using `MsgVote` and proposal passes
3. If ERC-20 contract is deployed on the EVM module, create a bank coin `Metadata` from the ERC20 details.

### Token Pair Conversion <a href="#token-pair-conversion" id="token-pair-conversion"></a>

Conversion of a registered `TokenPair` can be done via:

* Cosmos transaction (`ConvertCoin` and `ConvertERC20)`
* Ethereum transaction (i.e sending a `MsgEthereumTx` that leverages the EVM hook)

#### 1. Registered Coin <a href="#id-1-registered-coin" id="id-1-registered-coin"></a>

{% hint style="info" %}
**Context:** A `TokenPair` has been created through a `RegisterCoinProposal` governance proposal. The proposal created an `ERC20` contract ([ERC20Mintable by openzeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20)) of the ERC20 token representation of the Coin from the `ModuleAccount`, assigning it as the `owner` of the contract and thus granting it the permission to call the `mint()` and `burnFrom()` methods of the ERC20.
{% endhint %}

**Invariants**

* Only the `ModuleAccount` should have the Minter Role on the ERC20. Otherwise, the user could unilaterally mint an infinite supply of the ERC20 token and then convert them to the native Coin
* The user and the `ModuleAccount` (owner) should be the only ones that have the Burn Role for a Cosmos Coin
* There shouldn't exist any native Cosmos Coin ERC20 Contract (eg BCX, Atom, Osmo ERC20 contracts) that is not owned by the governance
* Token/Coin supply is maintained at all times:
  * Total Coin supply = Coins + Escrowed Coins
  * Total Token supply = Escrowed Coins = Minted Tokens

**1.1 Coin to ERC20**

1. User submits `ConvertCoin` Tx
2. Check if conversion is allowed for the pair, sender and recipient
   * global parameter is enabled
   * token pair is enabled
   * sender tokens are not vesting (checked in the bank module)
   * recipient address is not blocklisted
3. If Coin is a native Cosmos Coin and Token Owner is `ModuleAccount`
   1. Escrow Cosmos coin by sending them to the erc20 module account
   2. Call `mint()` ERC20 tokens from the `ModuleAccount` address and send minted tokens to recipient address
4. Check if token balance increased by amount

**1.2 ERC20 to Coin**

1. User submits a `ConvertERC20` Tx
2. Check if conversion is allowed for the pair, sender and recipient (see [1.1 Coin to ERC20](https://docs.evmos.org/modules/erc20/03_state_transitions.html#11-coin-to-erc20))
3. If token is a ERC20 and Token Owner is `ModuleAccount`
   1. Call `burnCoins()` on ERC20 to burn ERC20 tokens from the user balance
   2. Send Coins (previously escrowed, see [1.1 Coin to ERC20](https://docs.evmos.org/modules/erc20/03_state_transitions.html#11-coin-to-erc20)) from module to the recipient address.
4. Check if
   * Coin balance increased by amount
   * Token balance decreased by amount

#### 2. Registered ERC20 <a href="#id-2-registered-erc20" id="id-2-registered-erc20"></a>

{% hint style="info" %}
**Context:** A `TokenPair` has been created through a `RegisterERC20Proposal` governance proposal. The `ModuleAccount` is not the owner of the contract, so it can't mint new tokens or burn on behalf of the user. The mechanism described below follows the same model as the ICS20 standard, by using escrow & mint / burn & unescrow logic.
{% endhint %}

**Invariants**

* ERC20 Token supply on the EVM runtime is maintained at all times:
  * Escrowed ERC20 + Minted Cosmos Coin representation of ERC20 = Burned Cosmos Coin representation of ERC20 + Unescrowed ERC20
    * Convert 10 ERC20 → Coin, the total supply increases by 10. Mint on Cosmos side, no changes on EVM
    * Convert 10 Coin → ERC20, the total supply decreases by 10. Burn on Cosmos side , no changes of supply on EVM
  * Total ERC20 token supply = Non Escrowed Tokens + Escrowed Tokens (on Module account address)
  * Total Coin supply for the native ERC20 = Escrowed ERC20 Tokens on module account (i.e balance) = Minted Coins

**2.1 ERC20 to Coin**

1. User submits a `ConvertERC20` Tx
2. Check if conversion is allowed for the pair, sender and recipient (See [1.1 Coin to ERC20](https://docs.evmos.org/modules/erc20/03_state_transitions.html#11-coin-to-erc20))
3. If token is a ERC20 and Token Owner is **not** `ModuleAccount`
   1. Escrow ERC20 token by sending them to the erc20 module account
   2. Mint Cosmos coins of the corresponding token pair denomination and send coins to the recipient address
4. Check if
   * Coin balance increased by amount
   * Token balance decreased by amount
5. Fail if unexpected `Approval` event found in logs to prevent malicious contract behavior

**2.2 Coin to ERC20**

1. User submits `ConvertCoin` Tx
2. Check if conversion is allowed for the pair, sender and recipient
3. If coin is a native Cosmos coin and Token Owner is **not** `ModuleAccount`
   1. Escrow Cosmos Coins by sending them to the erc20 module account
   2. Unlock escrowed ERC20 from the module address by sending it to the recipient
   3. Burn escrowed Cosmos coins
4. Check if token balance increased by amount
5. Fail if unexpected `Approval` event found in logs to prevent malicious contract behavior


# Transactions

This section defines the `sdk.Msg` concrete types that result in the state transitions defined on the previous section.

### `RegisterCoinProposal` <a href="#registercoinproposal" id="registercoinproposal"></a>

A gov `Content` type to register a token pair from a Cosmos Coin. Governance users vote on this proposal and it automatically executes the custom handler for `RegisterCoinProposal` when the vote passes.

```go
type RegisterCoinProposal struct {
	// title of the proposal
	Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
	// proposal description
	Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
	// token pair of Cosmos native denom and ERC20 token address
	Metadata types.Metadata `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata"`
}
```

The proposal content stateless validation fails if:

* Title is invalid (length or char)
* Description is invalid (length or char)
* Metadata is invalid
  * Name and Symbol are not blank
  * Base and Display denominations are valid coin denominations
  * Base and Display denominations are present in the DenomUnit slice
  * Base denomination has exponent 0
  * Denomination units are sorted in ascending order
  * Denomination units not duplicated

### `RegisterERC20Proposal` <a href="#registererc20proposal" id="registererc20proposal"></a>

A gov `Content` type to register a token pair from an ERC20 Token. Governance users vote on this proposal and it automatically executes the custom handler for `RegisterERC20Proposal` when the vote passes.

```go
type RegisterERC20Proposal struct {
	// title of the proposal
	Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
	// proposal description
	Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
	// contract address of ERC20 token
	Erc20Address string `protobuf:"bytes,3,opt,name=erc20address,proto3" json:"erc20address,omitempty"`
}
```

The proposal Content stateless validation fails if:

* Title is invalid (length or char)
* Description is invalid (length or char)
* ERC20Address is invalid

### `MsgConvertCoin` <a href="#msgconvertcoin" id="msgconvertcoin"></a>

A user broadcasts a `MsgConvertCoin` message to convert a Cosmos Coin to a ERC20 token.

```go
type MsgConvertCoin struct {
	// Cosmos coin which denomination is registered on erc20 bridge.
	// The coin amount defines the total ERC20 tokens to convert.
	Coin types.Coin `protobuf:"bytes,1,opt,name=coin,proto3" json:"coin"`
	// recipient hex address to receive ERC20 token
	Receiver string `protobuf:"bytes,2,opt,name=receiver,proto3" json:"receiver,omitempty"`
	// cosmos bech32 address from the owner of the given ERC20 tokens
	Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,omitempty"`
}
```

Message stateless validation fails if:

* Coin is invalid (invalid denom or non-positive amount)
* Receiver hex address is invalid
* Sender bech32 address is invalid

### `MsgConvertERC20` <a href="#msgconverterc20" id="msgconverterc20"></a>

A user broadcasts a `MsgConvertERC20` message to convert a ERC20 token to a native Cosmos coin.

```go
type MsgConvertERC20 struct {
	// ERC20 token contract address registered on erc20 bridge
	ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"`
	// amount of ERC20 tokens to mint
	Amount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount"`
	// bech32 address to receive SDK coins.
	Receiver string `protobuf:"bytes,3,opt,name=receiver,proto3" json:"receiver,omitempty"`
	// sender hex address from the owner of the given ERC20 tokens
	Sender string `protobuf:"bytes,4,opt,name=sender,proto3" json:"sender,omitempty"`
}
```

Message stateless validation fails if:

* Contract address is invalid
* Amount is not positive
* Receiver bech32 address is invalid
* Sender hex address is invalid

### `ToggleTokenConversionProposal` <a href="#toggletokenconversionproposal" id="toggletokenconversionproposal"></a>

A gov Content type to toggle the internal conversion of a token pair.

```go
type ToggleTokenConversionProposal struct {
	// title of the proposal
	Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
	// proposal description
	Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
	// token identifier can be either the hex contract address of the ERC20 or the
	// Cosmos base denomination
	Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"`
}
```


# Hooks

The erc20 module implements transaction hooks from the EVM in order to trigger token pair conversion.

### EVM Hooks <a href="#evm-hooks" id="evm-hooks"></a>

The EVM hooks allows users to convert ERC20s to Cosmos Coins by sending an Ethereum tx transfer to the module account address. This enables native conversion of tokens via Metamask and EVM-enabled wallets for both token pairs that have been registered through a native Cosmos coin or an ERC20 token.&#x20;

Note that additional coin/token balance checks for sender and receiver to prevent malicious contract behaviour (as performed in the `ConvertERC20` msg) cannot be done here, as the balance prior to the transaction is not avaialble in the hook.

#### Registered Coin: ERC20 to Coin <a href="#registered-coin-erc20-to-coin" id="registered-coin-erc20-to-coin"></a>

1. User transfers ERC20 tokens to the `ModuleAccount` address to escrow them
2. Check if the ERC20 Token that was transferred from the sender is a native ERC20 or a native Cosmos Coin by looking at the [Ethereum event logs ](https://medium.com/mycrypto/understanding-event-logs-on-the-ethereum-blockchain-f4ae7ba50378#:~:text=A%20log%20record%20can%20be,or%20a%20change%20of%20ownership.\&text=Each%20log%20record%20consists%20of,going%20on%20in%20an%20event)
3. If the token contract address corresponds to the ERC20 representation of a native Cosmos Coin
   1. Call `burn()` ERC20 method from the `ModuleAccount`. Note that this is the same as 1.2, but since the tokens are already on the ModuleAccount balance, we burn the tokens from the module address instead of calling `burnFrom()`. Also note that we don't need to mint because 1.1 coin to erc20 escrows the coin
   2. Transfer Cosmos Coin to the bech32 account address of the sender hex address

#### Registered ERC20: ERC20 to Coin <a href="#registered-erc20-erc20-to-coin" id="registered-erc20-erc20-to-coin"></a>

1. User transfers coins to the`ModuleAccount` to escrow them
2. Check if the ERC20 Token that was transferred is a native ERC20 or a native cosmos coin
3. If the token contract address is a native ERC20 token
   1. Mint Cosmos Coin
   2. Transfer Cosmos Coin to the bech32 account address of the sender hex


# Events

The `x/erc20` module emits the following events:

### Register Coin Proposal <a href="#register-coin-proposal" id="register-coin-proposal"></a>

| Type            | Attribute Key   | Attribute Value   |
| --------------- | --------------- | ----------------- |
| `register_coin` | `"cosmos_coin"` | `{denom}`         |
| `register_coin` | `"erc20_token"` | `{erc20_address}` |

### Register ERC20 Proposal <a href="#register-erc20-proposal" id="register-erc20-proposal"></a>

| Type             | Attribute Key   | Attribute Value   |
| ---------------- | --------------- | ----------------- |
| `register_erc20` | `"cosmos_coin"` | `{denom}`         |
| `register_erc20` | `"erc20_token"` | `{erc20_address}` |

### Toggle Token Conversion <a href="#toggle-token-conversion" id="toggle-token-conversion"></a>

| Type                      | Attribute Key   | Attribute Value   |
| ------------------------- | --------------- | ----------------- |
| `toggle_token_conversion` | `"erc20_token"` | `{erc20_address}` |
| `toggle_token_conversion` | `"cosmos_coin"` | `{denom}`         |

### Convert Coin <a href="#convert-coin" id="convert-coin"></a>

| Type           | Attribute Key   | Attribute Value              |
| -------------- | --------------- | ---------------------------- |
| `convert_coin` | `"sender"`      | `{msg.Sender}`               |
| `convert_coin` | `"receiver"`    | `{msg.Receiver}`             |
| `convert_coin` | `"amount"`      | `{msg.Coin.Amount.String()}` |
| `convert_coin` | `"cosmos_coin"` | `{denom}`                    |
| `convert_coin` | `"erc20_token"` | `{erc20_address}`            |

### Convert ERC20 <a href="#convert-erc20" id="convert-erc20"></a>

| Type            | Attribute Key   | Attribute Value         |
| --------------- | --------------- | ----------------------- |
| `convert_erc20` | `"sender"`      | `{msg.Sender}`          |
| `convert_erc20` | `"receiver"`    | `{msg.Receiver}`        |
| `convert_erc20` | `"amount"`      | `{msg.Amount.String()}` |
| `convert_erc20` | `"cosmos_coin"` | `{denom}`               |
| `convert_erc20` | `"erc20_token"` | `{msg.ContractAddress}` |


# Parameters

The erc20 module contains the following parameters:

| Key             | Type | Default Value |
| --------------- | ---- | ------------- |
| `EnableErc20`   | bool | `true`        |
| `EnableEVMHook` | bool | `true`        |

### Enable ERC20 <a href="#enable-erc20" id="enable-erc20"></a>

The `EnableErc20` parameter toggles all state transitions in the module. When the parameter is disabled, it will prevent all token pair registration and conversion functionality.

### Enable EVM Hook <a href="#enable-evm-hook" id="enable-evm-hook"></a>

The `EnableEVMHook` parameter enables the EVM hook to convert an ERC20 token to a Cosmos Coin by transferring the Tokens through a `MsgEthereumTx` to the `ModuleAddress` Ethereum address.


# Clients

### CLI <a href="#cli" id="cli"></a>

Find below a list of  `blockxd` commands added with the `x/erc20` module. You can obtain the full list by using the `blockxd -h` command. A CLI command can look like this:

```bash
blockxd query erc20 params
```

#### Queries <a href="#queries" id="queries"></a>

| Command         | Subcommand    | Description                    |
| --------------- | ------------- | ------------------------------ |
| `query` `erc20` | `params`      | Get erc20 params               |
| `query` `erc20` | `token-pair`  | Get registered token pair      |
| `query` `erc20` | `token-pairs` | Get all registered token pairs |

#### Transactions

| Command      | Subcommand      | Description                    |
| ------------ | --------------- | ------------------------------ |
| `tx` `erc20` | `convert-coin`  | Convert a Cosmos Coin to ERC20 |
| `tx` `erc20` | `convert-erc20` | Convert a ERC20 to Cosmos Coin |

#### Proposals <a href="#proposals" id="proposals"></a>

The `tx gov submit-proposal` commands allow users to query create a proposal using the governance module CLI:

**`register-coin`**

Allows users to submit a `RegisterCoinProposal`.

```bash
blockxd tx gov submit-proposal register-coin [metadata] [flags]
```

**`register-erc20`**

Allows users to submit a `RegisterERC20Proposal`.

```bash
blockxd tx gov submit-proposal register-erc20 [erc20-address] [flags]
```

**`toggle-token-conversion`**

Allows users to submit a `ToggleTokenConversionProposal`.

```
blockxd tx gov submit-proposal toggle-token-conversion [token] [flags]
```

**`param-change`**

Allows users to submit a \`ParameterChangeProposal\`\`.

```
blockxd tx gov submit-proposal param-change [proposal-file] [flags]
```

### gRPC <a href="#grpc" id="grpc"></a>

#### Queries <a href="#queries-2" id="queries-2"></a>

| Verb   | Method                             | Description                    |
| ------ | ---------------------------------- | ------------------------------ |
| `gRPC` | `blockx.erc20.v1.Query/Params`     | Get erc20 params               |
| `gRPC` | `blockx.erc20.v1.Query/TokenPair`  | Get registered token pair      |
| `gRPC` | `blockx.erc20.v1.Query/TokenPairs` | Get all registered token pairs |
| `GET`  | `/blockx/erc20/v1/params`          | Get erc20 params               |
| `GET`  | `/blockx/erc20/v1/token_pair`      | Get registered token pair      |
| `GET`  | `/blockx/erc20/v1/token_pairs`     | Get all registered token pairs |

#### Transactions

| Verb   | Method                              | Description                    |
| ------ | ----------------------------------- | ------------------------------ |
| `gRPC` | `blockx.erc20.v1.Msg/ConvertCoin`   | Convert a Cosmos Coin to ERC20 |
| `gRPC` | `blockx.erc20.v1.Msg/ConvertERC20`  | Convert a ERC20 to Cosmos Coin |
| `GET`  | `/blockx/erc20/v1/tx/convert_coin`  | Convert a Cosmos Coin to ERC20 |
| `GET`  | `/blockx/erc20/v1/tx/convert_erc20` | Convert a ERC20 to Cosmos Coin |


# evidence

## `x/evidence` <a href="#x-evidence" id="x-evidence"></a>

### Abstract <a href="#abstract" id="abstract"></a>

`x/evidence` is an implementation of a Cosmos SDK module, per [ADR 009](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-009-evidence-module.md), that allows for the submission and handling of arbitrary evidence of misbehavior such as equivocation and counterfactual signing.

The evidence module differs from standard evidence handling which typically expects the underlying consensus engine, e.g. Tendermint, to automatically submit evidence when it is discovered by allowing clients and foreign chains to submit more complex evidence directly.

All concrete evidence types must implement the `Evidence` interface contract. Submitted `Evidence` is first routed through the evidence module's `Router` in which it attempts to find a corresponding registered `Handler` for that specific `Evidence` type. Each `Evidence` type must have a `Handler` registered with the evidence module's keeper in order for it to be successfully routed and executed.

Each corresponding handler must also fulfill the `Handler` interface contract. The `Handler` for a given `Evidence` type can perform any arbitrary state transitions such as slashing, jailing, and tombstoning.




---

[Next Page](/llms-full.txt/1)

