> ## Documentation Index
> Fetch the complete documentation index at: https://docs.peaq.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Fetching Data

Smart contract storage can be used to **read** from smart contract state variables and to **retrieve** stored information. This could be anything from user balances, configuration parameters,
or complex data structures such as mappings and arrays.

In this guide, we will walk through:

* How smart contract storage works in general.
* Common scenarios where you need to retrieve data from contract storage.
* Step-by-step **instructions** on how to fetch data, using **Solidity** and a client library (e.g., `web3.js` or `ethers.js`).
* Best practices and potential pitfalls.

By the end, you will understand how to confidently and securely fetch data from your peaq-based smart contracts.

## Prerequisites

* Understanding of Solidity
* You have a working development environment set up with:
  * A Solidity compiler (e.g., via Hardhat, Truffle, or Remix).
  * Access to the peaq network's EVM endpoint (or a local test EVM).
* Using a library like `web3.js` or `ethers.js` to interact with your deployed contracts. Alternatively, any other JSON-RPC client can be used if you are comfortable with lower-level interactions.
* Already have a deployed contract on the peaq network, or you have the means to deploy one during testing.
* Access to contract's its Application Binary Interface (ABI). This is generally generated automatically when compiling your Solidity smart contract.

## Instructions

### 1. Understanding EVM Contract Storage

In EVM-based networks like peaq, each contract has its own allocated storage. Storage is typically broken down into **slots** of 256 bits each:

* **State Variables** store data in these storage slots.
* **Mappings** are hashed to find their storage slots.
* **Arrays** and other data structures have their own packing and storage rules.

When writing or reading from storage, gas costs and efficient layout (for writes) can be important. However, retrieving data (a read) is **cheaper**
than storing data (a write). For reads, you can **query** the node's state without incurring on-chain transaction costs.

### 2. Declaring and Storing Data in Solidity

Let's look at a simple example contract that stores some data:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 public storedValue;
    mapping(address => uint256) public balances;

    constructor(uint256 initialValue) {
        storedValue = initialValue;
        balances[msg.sender] = 100;
    }

    // A simple setter function
    function setValue(uint256 newValue) external {
        storedValue = newValue;
    }

    // A simple function that updates balances
    function updateBalance(address account, uint256 amount) external {
        balances[account] = amount;
    }
}

```

* `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. Interacting With the Contract to Fetch Data

#### Using a Script (JavaScript + ethers.js/web3.js)

Below is an example of how to fetch data from `storedValue` and `balances` using `ethers.js`.
**Ethers.js Example:**

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
import { ethers } from 'ethers';

// 1. Connect to the peaq network (replace with actual provider endpoint)
const provider = new ethers.JsonRpcProvider("https://your-peaq-rpc-endpoint");

// 2. Define the contract ABI (simplified for this example)
const abi = [
  "function storedValue() view returns (uint256)",
  "function balances(address) view returns (uint256)"
];

// 3. The deployed contract address
const contractAddress = "0xYourContractAddressOnPeaq";

// 4. Create an instance of the contract
const contract = new ethers.Contract(contractAddress, abi, provider);

async function readData() {
  try {
    // 5. Call the view functions
    const value = await contract.storedValue();
    console.log("storedValue:", value.toString());

    const someAddress = "0x1234..."; // Replace with a valid address
    const balance = await contract.balances(someAddress);
    console.log(`Balance of ${someAddress}:`, balance.toString());
  } catch (error) {
    console.error("Error fetching data:", error);
  }
}

readData();
```

**Key Points**

* We use the `view` functions (`storedValue()` and `balances(address)`) to retrieve data without sending a transaction.
* This means there is no cost in terms of gas for these read operations; only the provider's request/response overhead applies.

#### Using the Remix IDE

If you prefer a browser-based approach:

1. Open Remix IDE.
2. Select the “Solidity” environment and load your contract code.
3. Compile and Deploy to a peaq network-compatible endpoint (via “Deploy & run transactions” panel).
4. After deployment, you will see the contract’s interface in Remix.
   * Clicking on `storedValue` will fetch and display the current `storedValue`.
   * Providing an address to `balances` will fetch and display the mapping value for that address.

### 4. Fetching Custom or Complex Data Types

If you have **custom** data structures like **structs** or **nested mappings**, you can expose them through custom getter functions. For example:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract ComplexStorage {
    struct User {
        uint256 id;
        uint256 balance;
        address userAddress;
    }

    mapping(address => User) private users;

    // Insert or update user
    function setUser(address _address, uint256 _id, uint256 _balance) external {
        users[_address] = User(_id, _balance, _address);
    }

    // Public function to read user data
    function getUser(address _address) external view returns (uint256, uint256, address) {
        User memory user = users[_address];
        return (user.id, user.balance, user.userAddress);
    }
}
```

Here, the struct `User` is stored in a private mapping. We expose a `getUser` function that returns the data in a single call. You can fetch it from your JavaScript code similarly with a function call:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
const contractAbi = [
  "function getUser(address _address) view returns (uint256, uint256, address)"
];

const contract = new ethers.Contract(contractAddress, contractAbi, provider);

const userData = await contract.getUser(someUserAddress);
console.log("User Data => ID:", userData[0].toString(), 
            "Balance:", userData[1].toString(), 
            "User Address:", userData[2]);
```

This approach helps keep your contract's data **private** while still allowing necessary read-access to data via dedicated functions.

## Summary

Fetching data from smart contract storage on the peaq network (or any EVM-compatible network) follows the same paradigm as Ethereum:

* You **define** state variables in Solidity.
* You **expose** those variables either with the `public` keyword or dedicated getter functions.
* You **interact** with them through a client library (e.g., `ethers.js`, `web3.js`) or Remix IDE.

**Key Takeaways**:

* **Public Variables**: Automatically generate getter functions, convenient for straightforward retrieval.
* **View/Pure Functions**: Cost no gas when called off-chain, making them ideal for reading data.
* **Custom Getter Functions**: Useful for complex data structures or additional data processing.
* **Security**: Ensure that any data you do not want freely accessible remains in private variables, and only expose it through controlled view functions as needed.

With these core principles in mind, you can confidently **fetch data** from your peaq-based Solidity contracts, enabling rich dApp functionality and user-friendly front-end experiences.
