# Ethernal Documentation

Learn here what you can do with Ethernal, and how to get the most out of it.

Ethernal is an open-source block explorer for private EVM-based chains, similar to Etherscan.\
Once you are set up, you will be able to browse blocks, transactions, accounts, and contracts. But also read contract variables, decode function calls and events.

You can connect Ethernal to any chain, whether you are running it locally or on a remote server.

Ethernal works with a CLI that listens to blocks and transactions and synchronizes them to your dashboard.

In order to decode contract variables data, you can also synchronize artifacts data through the CLI for Truffle projects or a dedicated plugin for Hardhat projects.

If you want to know more about what data is synchronized and why, the [FAQ](/faq) can help you.

{% content-ref url="/pages/-MU0WfFr9BN8IXBjuyPL" %}
[Getting Started](/getting-started/quickstart)
{% endcontent-ref %}

{% content-ref url="/pages/-MU0XWyAAinUQY-\_EY7G" %}
[Dashboard](/dashboard-pages/addresses)
{% endcontent-ref %}


# FAQ

Find answers to the most common questions about Ethernal.

## What data do you synchronize?

* The whole responses from web3js `getBlock()`, `getTransaction()`, and `getTransactionReceipt()`.&#x20;
* Accounts addresses & balances
* Contract artifact data:
  * contractName
  * abi
  * ast
  * source

You can verify this on our [Github account](https://github.com/tryethernal) under the [CLI](https://github.com/tryethernal/ethernal-cli) & [Hardhat plugin](https://github.com/tryethernal/hardhat-ethernal) repositories.

## Why do you need to synchronize artifact data?

`contractName` is used to label your contract in the dashboard.

`abi` is used to decode function calls and events data.

`ast` and `source` are used to decode contract variables data.

## Can I host my data on my own Firebase instance?

Yes, see [here](broken://pages/4AVypQIVrCwZGRC7rEGw) for how to self-host.

## How much does Ethernal cost?

Ethernal has a free plan and a paid plan. The limits to the free plan are:

* You can't sync more than 10 contracts
* You can only have 1 workspace

Couldn't find your answers here or in the doc? You can ask us at <contact@tryethernal.com> and we'll do our best to answer you and update this page!


# Quickstart

Get up and running with Ethernal in a few minutes

To signup, just head to <https://app.tryethernal.com>. You will just need an email address.

On your first login, you will be asked to create a workspace.\
Workspaces consist of a name & a server address.

Each workspace has its own dashboard, with its own data. It's useful if you are working with different chains.

The dashboard will be accessible even if your server is not running. However, it needs to be at the time of the workspace creation.

Once the connection to the server has been established you'll be asked to install the CLI. To do so, just run the following command:

```bash
npm install ethernal -g
```

Then, log in with your credentials and start listening to transactions:

```bash
ethernal login
```

```bash
ethernal listen
```

You can also skip the login command and use env variables:

```bash
ETHERNAL_EMAIL=your@email.com ETHERNAL_PASSWORD=yourpwd ethernal listen
```

To complete your onboarding, you will need to generate one transaction. You can run a migration for example.

After that, go back to your dashboard, and should see a confirmation that the transaction has been received. Your dashboard is now ready!

As a next step, we recommend that you set up data synchronization for contracts.

{% content-ref url="/pages/-MU0XHUqKpa8aio9dVR9" %}
[Hardhat Project Setup](/getting-started/hardhat-project-setup)
{% endcontent-ref %}

{% content-ref url="/pages/-MU0XS8YM1GEGUJ1WKrH" %}
[Truffle Project Setup](/getting-started/truffle-project-setup)
{% endcontent-ref %}


# CLI

Learn how to use the Ethernal CLI

The CLI serves two purposes:

* Synchronizing blocks & transactions with your dashboard
* Synchronizing contract's artifact data for Truffle projects

{% hint style="info" %}
Artifact data for Hardhat projects are synchronized with a [plugin](/getting-started/hardhat-project-setup)
{% endhint %}

### Installation

Install the CLI globally with the following command:

```bash
npm install -g ethernal
```

### Logging In

If you haven't done so already, this is the first thing to do after installing.\
Your email is stored in `~/.config/configstore/ethernal.email.json`.\
Your password is stored in your local keychain.\
You only need to login once. If you need to log in with another account, you can just run the command again.

```bash
ethernal login
```

You can also skip the login command and use env variables:

```bash
ETHERNAL_EMAIL=your@email.com ETHERNAL_PASSWORD=yourpwd ethernal listen
```

### Listening to transactions

To listen to transactions, the CLI will pull the server address of the latest used workspace. If you want to specify a different workspace you can use the `-w` flag.

```bash
ethernal listen
```

Or for a different workspace:

```bash
ethernal listen -w staging
```

If the passed workspace name is not found, it will default to the latest used.

{% hint style="info" %}
When starting the CLI, it will automatically synchronize all blocks & transactions that are missing (if some happened when the CLI wasn't running for example).
{% endhint %}

### Watching contracts artifacts (Truffle projects only)

{% hint style="warning" %}
If you are using Hardhat, head to [this section](/getting-started/hardhat-project-setup).
{% endhint %}

The CLI will also watch by default your artifacts if you have run it in a Truffle project (there needs to be a truffle-config.js file in the directory).

If you are looking to set up a Truffle project:

{% content-ref url="/pages/-MU0XS8YM1GEGUJ1WKrH" %}
[Truffle Project Setup](/getting-started/truffle-project-setup)
{% endcontent-ref %}

If your chain is not running locally and you don't want to listen to transactions, but only synchronize artifacts, you can run

```bash
ethernal listen -l
```

And if you are on a remote server hosting the chain, and you don't want to watch for contracts, you can run:

```bash
ethernal listen -s
```

By default, only the name and the ABI of the contract are going to be uploaded. If you want to use the "Storage" tab of contracts page, you'll need to have the AST uploaded as well. To do so, pass the `--astUpload` flag as a parameter (this will upload the ast field, as well as the source field).

```
ethernal listen --astUpload
```

### Parameters

| Parameter | Alias     | Description                                                                                                           | Default                     |
| --------- | --------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| -w        | workspace | Specify the workspace to connect to                                                                                   | Latest used / First Created |
| -d        | dir       | Specify the directory to watch for artifact change. You can pass multiple parameters by using a comma as a separator. | . (current directory)       |
| -s        | server    | Do not watch for artifact change - only listen for transactions                                                       | false                       |
| -a        | astUpload | Upload AST to decode storage                                                                                          | true                        |
| -l        | local     | Do not listen for transactions - only watch for contract changes                                                      | false                       |

### Resetting a workspace

This will delete all accounts/blocks/transactions/contracts from a specific workspace

```bash
ethernal reset [workspace]
```


# Hardhat Project Setup

Install and use the Hardhat plugin

The Hardhat plugin extends Hardhat network by listening to incoming blocks and synchronizing them directly with the dashboard. Once installed and included, you won't need to run the CLI as it will be able to listen and synchronize blocks directly.

### Installation

Add `hardhat-ethernal` to your `package.json`, and run `npm install` or `yarn`

### Synchronize blocks & transactions

In your `hardhat-config.js`file, require the plugin:

```javascript
require('hardhat-ethernal');
```

That's it! Blocks and transactions will now be synchronized.

#### Options

It's possible to disable the synchronization by setting `ethernalSync` to `false` on the `hre` object.

You can also specify which workspace you want to synchronize blocks & transactions to (default to the last one used in the dashboard).

By default, transactions will be traced using `experimentalAddHardhatNetworkMessageTraceHook`, showing CALLx and CREATEx operations in the dashboard. You can disable this feature with the `ethernalTrace` flag.

You can automatically reset your workspace by setting the `ethernalResetOnStart` property to the name of the workspace. Everytime the node starts, all accounts/blocks/transactions/contracts will be deleted.

```javascript
extendEnvironment((hre) => {
    hre.ethernalSync = true;
    hre.ethernalWorkspace = 'Workspace';
    hre.ethernalTrace = false;
    hre.ethernalResetOnStart = 'Hardhat';
});
```

### Logging In

You can log in either by using

```
ethernal login
```

Or by calling Hardhat commands with extra env variables:

```bash
ETHERNAL_EMAIL=your@email.com ETHERNAL_PASSWORD=yourpwd npx hardhat node
```

### Synchronize artifacts

Require the package in your deploy script:

```javascript
require('hardhat-ethernal');
```

The plugin will add an `ethernal` object with a `push` function on the `hre` object.\
This function takes two parameters:

* `name`: name of the contract (case sensitive). It needs to match exactly the name of the deployed contract
* `address`: address of the contract

You should call this function anytime after the contract has been successfully deployed.

This function returns an empty promise.

By default, the push function is not going to upload AST to Ethernal. If you want to use "Storage" tab on contracts pages, you'll need to activate it. To do so, set the `hre.ethernalUploadAst = true` flag in your Hardhat config file (this will upload the ast field, as well as the source field).

#### Example

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

async function main() {
  
  const Greeter = await hre.ethers.getContractFactory("Greeter");
  const greeter = await Greeter.deploy("Hello, Hardhat!");

  await hre.ethernal.push({
      name: 'Greeter',
      address: greeter.address
  })

  console.log("Greeter deployed to:", greeter.address);
}

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

```

### Reset a workspace

You can manually reset a workspace by calling: `hre.ethernal.resetWorkspace(workspaceName)` (async function). All accounts/blocks/transactions/contracts will be deleted;


# Truffle Project Setup

If you've already installed the CLI, then you are already good to go, as the synchronization is done by it as well!

You just need to make sure that you are either calling the `listen` command from your Truffle project directory. Or that you pass the -d parameter.

When starting the CLI, contracts will be synchronized, so the output should look like the following:

![Artifact synchronization](/files/-MU5Y-UBUGJC0H1vawdA)

{% hint style="warning" %}
The CLI watches *any* changes in the artifacts. So if you manually edit a field that is synchronized, it might make the decoding impossible!
{% endhint %}


# Addresses

Address pages will display all IN and OUT transactions of this address along with some basic information such as the timestamp, fees, or value.

All address pages URL follow the pattern `/address/${address}`.

If the address is a contract (ie `getCode()` doesn't return `0x`), it will display two more tabs related to that. See the [Contracts section](/dashboard-pages/contracts) for more info on this.


# Accounts

Ethernal will pull available accounts on the workspace server and display them there along with their balance.

If you click on the address, you'll be able to see the transaction history.

You'll be able to use any of the accounts listed here when interacting with contracts.

### Unlocked Accounts

To add an unlocked account and start using it, you can use the "Add Account" button.\
No verification is made to make sure the account is available, so you'll need to check that before.

### Private Keys

If you set up a private key for an account, it will be used for every read & write request from it.

### Impersonate Accounts

You can also impersonate accounts from this page ("Add Account" button).

This tries to call `evm_unlockUnknownAccount` and then `hardhat_impersonateAccount`, if one of them succeed the account is added to the list, its token balance will be displayed for detected tokens, and you'll be able to use it to call contracts methods.


# Blocks

## Index

The [/blocks](https://app.tryethernal.com/blocks) page will display all synchronized blocks, with basic details such as mining timestamp or the number of transactions.\
Block numbers link to the block details page\
If a block is mined but the CLI is not listening, the block won't appear here.

### Details

Each block has its own page, with the URL following the pattern `/block/${blockNumber}`.&#x20;

Transactions contained in this block are all displayed.\
If a transaction is a contract call and artifacts have been uploaded, clicking on it will decode the data.\
You'll be able to see:

* Function call signature with the parameters
* Emitted events
* Watched variables data

The watched variables data will be the one watched for the contract called in the transaction.


# Transactions

### Index

The [/transactions](https://app.tryethernal.com/transactions) page will display all synchronized blocks, with basic details such as age or sender and destination.\
No destination means it's a contract creation.\
Transaction hashes link to the transaction details page\
If a transaction is mined but the CLI is not listening, it won't appear here.

If the address is a known contract (the name has been set manually, or synchronized) it will be displayed instead of the address.

### Details

Each block has its own page, with the URL following the pattern `/transaction/${txHash}`.&#x20;

Based on what happened during the transactions different sections will be displayed:

* Token transfers: if the transaction emitted standard ERC\_20 `Transfer()` events, they will formatted and displayed here with contract names and formatted amounts.
* Token balances: Also based on `Transfer()` events, for each emitted event, a query to get the balance will be made on the current & previous block, both values will be displayed, as well as the difference.

If the transaction is a contract call and the artifacts have been uploaded, you'll be able to see:

* Function call signature with the parameters
* Emitted events
* Watched variables data

The watched variables data will be the one watched for the contract called in the transaction.

### Tracing

If you are connected to a node that supports `debug_traceTransaction`,  you'll be able to see the Trace section on every transaction page.

This feature is similar to the "Internal Txns" Etherscan page, it will show you interactions that happened with other contracts during the transaction.

By default, transaction tracing is not activated in any of your workspaces. In order to do that you need to go in the "Settings" page, scroll down to the "Advanced Options" panel, select the tracing mode in the dropdown, and click "Update".

{% hint style="warning" %}
After changing this setting, you'll need to restart the CLI (or the Hardhat node if you are using the plugin).
{% endhint %}

There are two different modes: "Tracing on a Hardhat network" and "Tracing a non-Hardhat network". This distinction is needed because transaction tracing is handled a bit differently with Hardhat.

Once tracing has been activated it will be ran for every write transaction, and the trace will be displayed, after processing, on the transaction page.

Here is what you'll see:

* Type of action (CALL, CREATE, etc...)
* Address of the contract called (or created)
* Name of the contract
* Decoded function called with parameters

For the last two, it will be available if Ethernal was able to match it with an existing  contract, or able to pull info from Etherscan.

Once all the steps have been collected, we are trying to get as much info as possible from each step:

If it's a CALLx step, we try three different strategies, and use the first one that returns the info that we need:

1. We look for the called address in your synchronized contracts, if there is a match, we'll use this info to decode the parameters and display the name along the trace
2. We hash the called bytecode, and compare it to hashes of your other contracts. If there is match, we set the name & the ABI from it.
3. We look for an existing address on Etherscan, and if there is a match we pull the name and ABI from there, and associate it with the trace.

For CREATEx steps, it's only trying strategy #2.

Depending on how big the trace is, and how many requests to Etherscan are made, this process can take a bit of time. However, once it's finished, your trace becomes much easier to understand!

A more in-depth article on how it works is available on the blog: <https://blog.tryethernal.com/transaction-tracing-with-ethernal/>


# Contracts

Contract pages are address pages and follow the same pattern URL (`/address/${address}`).

If calling`getCode(address)`returns anything different than`0x`, the contract interface will appear.

This page is composed of three tabs:

### Transactions

Lists all IN and OUT transactions along with some basic info about it.

### Contract

This is where you can interact with your contract.

{% content-ref url="/pages/-MU0XiGxR3EnGmqlJb4-" %}
[Interacting with the contract](/dashboard-pages/contracts/interacting-with-the-contract)
{% endcontent-ref %}

### Storage

This is where you'll be able to read contract variables.

{% content-ref url="/pages/-MU0XlssLyY3I7PW14qN" %}
[Reading variables](/dashboard-pages/contracts/reading-variables)
{% endcontent-ref %}


# Importing mainnet contracts

Import contracts that have been verified on Etherscan to easily use them on your mainnet fork

{% hint style="warning" %}
This feature will only work on workspaces connected to a mainnet fork
{% endhint %}

![Importing and interacting with the mainnet Uniswap contract](/files/-MZm2sa7lcvkhgrpD8H3)

This feature lets you import mainnet contracts that have been verified on Etherscan, Polygonscan or Bscscan (depending on the chain set for the workspace). Once the contract has been imported, it will appear in your contracts list, you'll be able to see transactions sent to it on your fork, and to interact with all read & write methods.

To get started, go to the "Contracts" page, click on "Import Contract", enter the address, and click "Import". This will pull the name and the ABI from the explorer, and populate your contracts list.

Once this is done, go to the contract page, and from there you'll be able to see the list of transactions sent to this address on your fork, and, on the "Contract" tab, to interact with all the read & write methods.

{% hint style="info" %}
The "Storage" tab is not available yet for this feature, if you need it, you'll have to redeploy the contract with Truffle or Hardhat
{% endhint %}

{% hint style="info" %}
This feature is currently available for Ethereum, Polygon & BSC mainnet forks. If you'd like to request compatibility with other networks, please reach out to @antoinedc on Discord
{% endhint %}


# Interacting with the contract

If no artifact has been uploaded for the contract, a message will invite you to do so.\
Artifacts are uploaded through the [CLI](/getting-started/cli#watching-contracts-artifacts-truffle-projects-only) for Truffle projects or a [plugin](/getting-started/hardhat-project-setup) for Hardhat projects.

Once it's been done, you'll have access to three sections:

### Call Options

These parameters will be used when calling any of the read and write functions.\
If you set them globally in the settings, they will be set here too.

### Read Methods

This section will show all read methods, they won't consume any gas when calling them, won't change the state of the chain, and won't generate a transaction.

The result (or the error) will be displayed above the "Query" button.

Ethernal attempts to automatically format the result based on the return type and its content. You can switch between raw/formatted values by clicking the button next to it:

* uint256 are not formatted by default, but if you format them, they will be converted as gwei to ether
* addresses are made clickable and the name of the contract is displayed instead of the hash when applicable
* strings are formatted depending of their content:
  * http(s) & ipfs links are made clickable
  * json & strings starting with `data:application/json;base64` are formatted nicely
  * svg & strings starting with `data:img` are displayed in an `img` tag (note that svg are automatically resized to 200x200)

Feel free to ask for support for more formats in the Discord!

{% hint style="info" %}
This formatting is used across the web app, so it applies for variable displayed in emitted events on transaction pages for example.
{% endhint %}

### Write Methods

This section will show all write methods, they might change the state of the chain and will generate a transaction.

If the transaction succeeds, a link will be displayed above the "Query button", if it fails the error message will be displayed instead.

If you send a transaction to a node that supports the debug\_traceTransaction method, it will be used to display more info about interactions of this transaction with other contracts. See the [Transactions](/dashboard-pages/transactions#trace) page for more details on how it works.


# Reading variables

Decode your contract's variables

{% hint style="warning" %}
This feature needs contracts AST upload, which is disabled by default. To learn how to activate it check the [CLI](/getting-started/cli) or [Hardhat plugin](/getting-started/hardhat-project-setup) doc.
{% endhint %}

Decoding variables works using the [Truffle Decoder](https://www.trufflesuite.com/docs/truffle/codec/modules/_truffle_decoder.html) package.

The first section of this tab will show all the decodable variables and their types.

To decode a variable, it first needs to be watched.\
\
By default, all variables that are declared in the contract **except for mappings** are watched and will be decoded automatically.

For mappings, you need to specify the key that you want to watch.

Let's take the following smart contract as an example

```javascript
contract Store {
    mapping(address => uint256) public values;
    uint256 latest;
    Transaction[] history;
    
    struct Transaction {
        address from;
        address to;
        uint256 amount;
    }
}
```

In this case, when a transaction arrives `latest` and `history` will be decoded automatically.

In the case of `history`, the struct will be decoded as well.

For `values`, you need to explicitly tell which keys you want to watch using the "+" button next to the name of the variable.

It is possible to watch nested mappings. You just need to specify the key at each nesting level until you arrive at a non-mapping variable.

![Adding keys to mappings](/files/-MU9YwgWjeQ0YFQkGF_0)

Below this section, you will find the list of transactions. Clicking on a transaction will show in a panel all the values for the watched variables, as well as the function signature, its params, and emitted events.

![Example with the variables of the above contract](/files/-MU9h6PQvUXIjIVe2Iuh)

You can re-decode the transaction, by clicking on the circling arrow icon on the top right of the "Data" section. It can be useful if you just added a new key to track and want to see its value in past blocks.

{% hint style="warning" %}
The AST is necessary for this feature to work. It is uploaded by the CLI and the Hardhat plugin. However, for free users, it's deleted from the database after 1 week in order to save space. Data that has been decoded stays available on the transaction page though.
{% endhint %}


# Tokens

When a contract is added to your dashboard, whether it's through artifact sync, manual contract import or automatic import during tracing, Ethernal calls the following methods on it:

* decimals()
* symbol()
* name()

If none of these methods fail, the contract is tagged as `erc20` and will appears in the Tokens page.

If the ABI associated to those tagged contracts is not an ERC-20 ABI, the contract will also be tagged as `proxy`.

The Tokens page will display some extra tokens info that are not present on the Contracts page such as the token name and symbol.

When going on the address page of a token, you'll find an extra "Token" tab on it. At the moment, this tab only shows the balance of all available addresses (ie: all addresses under the "Accounts" tab), for this token. If you want to know the balance of a particular address, you need to add it in the "Accounts" page either by impersonating it or by adding the private key.


# Settings

This page allows you to configure your dashboard.\
It's not possible to edit the server of the workspace. If you need to work on another one, you can create another workspace

### Server

You can choose to set which chain is running on the server. This will change the display of the native currency and the source to import contracts metadata:

| Chain    | Currency | Contract Metadata Source |
| -------- | -------- | ------------------------ |
| Ethereum | Ether    | Etherscan                |
| BSC      | BNB      | BSCscan                  |
| Matic    | Matic    | Polygonscan              |

### **Default Contracts Call Options**

On contract interaction tabs, the call options will be filled by default with values here.

When creating a new workspace, the "Default From Account" will be filled with the first value returned by `getAccounts()`, and "Default Maximum Gas" with the gas limit of the block returned by `getBlock('latest')`.

### Workspaces

Having different workspaces is useful if you are working with different chains. Free users only have one, but premium users can add as many as they want.\
\
When adding a workspace, it will check the connection with the chain so make sure it's running.

To switch between workspaces, just click on the switch icon in the table.

![](/files/-MU9jEwoddxQ1-Aa9W3v)

### Reset Workspace

Resetting your workspace can be useful if you are not persisting your blockchain data and don't want your dashboard polluted with outdated transactions.

Doing so will clear all accounts, blocks, transactions & contracts from your dashboard.

Settings (server, gas price, etc...) are not reset.

Be careful with this as there is no way to recover the data once it's been deleted.


# Alchemy

Synchronize transactions going through your Alchemy app with Ethernal

[Alchemy API](https://www.alchemy.com) is a gateway to different Ethereum public networks (Mainnet, Kovan, ...), but unlike others, it also provides development tools on top of that. You can, for example, explore & replay raw transactions that you sent through their node, making it very useful for debugging decentralized apps.

One interesting feature that Alchemy provides is triggering a webhook every time a transaction going through their RPC endpoint is mined. So we built an endpoint that can receive those webhooks, fetch the corresponding block & transaction on the network, and combine it with your contract's metadata, turning all of this in a dashboard that can give you a complete, and easy to read view of what's going on with your dapp.

#### Setup

You can set up this integration in any workspace, but, to avoid mixing your data, we recommend that you create another one. A good practice is to have one workspace per Alchemy endpoint.

Get your Alchemy endpoint in your dashboard, and create a new workspace with it on Ethernal ( "Settings" > "Create Workspace").

Once this is done, in the "Integrations" panel, click on "Manage" next to "Alchemy API". Toggle the switch in the modal window, and your webhook endpoint will appear.

![Alchemy Webhook Activation](/files/-MZUTEwYxT4IweIRJGUr)

Now, for the last step of the setup, go back to the ["Notify" section](https://dashboard.alchemyapi.io/notify) of your Alchemy dashboard. (The link is in the top navigation bar).

Scroll down to "Mined Transaction Notifications", click on "Create Webhook", select the app, paste the webhook in the field, confirm, and you are done!

Now all your dapp transactions will appear on your Ethernal dashboard, a few seconds after they have been mined.

One last thing to note: as mentioned above, running your CLI on this workspace would synchronize every block of the network. If you want to only synchronize contract metadata, run the cli with the `-l` option: `ethernal listen -d ~/solidity/token -l`

If you run into any issues, feel free to send an email to <antoine@tryethernal.com>, or to ask me (@antoinedc) on the [Discord server](https://discord.gg/jEAprf45jj).\
We'll also happily take integrations requests if you know of other Ethereum gateways that provide similar webhooks!


# API

Pull data programmatically from Ethernal

At the moment, only one endpoint is available, if there is some data that you'd like to fetch from the API, please reach out to <antoine@tryethernal.com>, @antoinedc on Discord or @adechevigne on Twitter!

## Authentication

To authenticate, you'll need an auth token that you will find on the "Settings" page. The "API" integration needs to be enabled for requests to go through.

Once you've enabled the integration, the token will be displayed below.

Pass it in a `token` GET parameter to the endpoint you'd like to use.

{% hint style="warning" %}
Each workspace has its own token
{% endhint %}

## Endpoints

## Storage

<mark style="color:blue;">`GET`</mark> `https://api.tryethernal.com/contracts/:contractAddress/storage?token=xxx&paths[]=["balances", "0x123456789"]`

Reads values of the variables of the contract at address `contractAddress`. This makes available data you'll find in the "Storage" tab in contracts pages through an API.\
\
You need to pass an array of arrays, where each element is the path to the variable you want to read.\
Top level primitives are automatically decoded, you don't need to specify them in the path.\
If a variable is not found, an error will be returned.\
\
Example:\
If we have a contract with the following variables declared:\
`(address => uint256) balances;`\
`uint256 total;`\
\
And if we want to read the total and the balance for addresses `0x1234` and `0x5678`, we would call the following:\
`https://api.tryethernal.com/contracts/0xabcdef/storage?token=xxx&paths[]=["balances", "0x1234"]&paths[]=["balances", "0x5678"]`\
\
`total` will always be returned.\
\
The response will have two fields: a paths field that returns asked paths, and a storage field that will contains the values.\
In this case, it would be:\
`{`\
&#x20;   `paths: [`\
&#x20;      `['balances', '0x1234'],`\
&#x20;      `['balances', '0x5678']`\
&#x20;   `],`\
&#x20;   `storage: {`\
&#x20;       `balances: {`\
&#x20;           `'Ox1234': '10000',`\
&#x20;           `'0x5678': '20000'`\
&#x20;       `},`\
&#x20;       `total: '30000'`\
&#x20;   `}`\
`}`\
\
You can find more details about variable reading in this section.

#### Path Parameters

| Name            | Type   | Description             |
| --------------- | ------ | ----------------------- |
| contractAddress | string | Address of the contract |

#### Query Parameters

| Name  | Type   | Description                             |
| ----- | ------ | --------------------------------------- |
| paths | array  | Paths of the variables you want to read |
| token | string | Authentication token                    |

{% tabs %}
{% tab title="200 Returns queried path and variables values." %}

```
{
    paths: [
       ['balances', '0x1234'],
       ['balances', '0x5678']
    ],
    storage: {
        balances: {
            'Ox1234': '10000',
            '0x5678': '20000'
        },
        total: '30000'
    }
}
```

{% endtab %}

{% tab title="400 Can return one of the following:" %}

```
{ message: 'API integration for workspace Hardhat is disabled' }
{ message: 'No contract at 0xabcd in workspace Hardhat' }
{ message: 'API integration for workspace Hardhat is disabled' }
{ message: 'No artifact for contract at 0xabcd in Hardhat' }
{ message: 'No such variable balance' }
```

{% endtab %}

{% tab title="401 Can return one of the following" %}

```
{ message: 'Failed authentication' }
{ message: 'Missing auth token' }
```

{% endtab %}
{% endtabs %}


