Skip to main content
Reading a peaq contract’s state costs no gas when you call it off chain. This guide covers how EVM storage is laid out, how to expose state variables, and how to read them from JavaScript or Remix.

Prerequisites

  • Solidity basics.
  • A contract deployed on peaq, or the means to deploy one.
  • The contract ABI, which your Solidity compiler generates.
  • A client library such as ethers.js or web3.js, or any other JSON-RPC client.

Instructions

1. EVM contract storage

Each contract on peaq has its own storage, split into slots of 256 bits:
  • State variables occupy one or more slots.
  • A mapping value lives at a slot derived from the hash of its key.
  • Arrays follow their own packing rules.
Reads are cheaper than writes. An eth_call is not a transaction, so the caller pays nothing. A view function called from inside a transaction still costs gas.

2. Declare and store data

This contract keeps a number and a mapping of balances:
  • storedValue is a public uint256. By making it public, Solidity automatically creates a getter function storedValue() that returns the value.
  • balances is a public mapping from address to uint256. Likewise, balances(address) becomes a getter function to read the balance for any given address.

3. Read the data

With ethers.js

storedValue() and balances(address) are view functions, so reading them sends no transaction and costs no gas.

Using Remix

  1. Load your contract in Remix and compile it.
  2. In the “Deploy & run transactions” panel, connect to a peaq endpoint and deploy.
  3. Click storedValue to read the current value, or pass an address to balances to read that entry of the mapping.

4. Fetch structs and nested mappings

Solidity generates getters for public structs and nested mappings, but the mapping below is private, so it needs a getter you write yourself. For example:
The User struct lives in a private mapping, and getUser returns its fields in a single call. Read it from JavaScript the same way:
private keeps other contracts and the generated ABI out of users, but it hides nothing: all contract storage is readable straight from the chain with eth_getStorageAt. Never put a secret in a contract.