What is Smart Contract Storage?

Smart contract storage refers to the persistent data layer of an Ethereum Virtual Machine (EVM) contract. It’s where your variables and state information are stored on-chain. Unlike local or in-memory variables, data stored in contract storage remains on the blockchain and can be accessed or updated by functions within your smart contract—or external actors that call those functions.

Why Does it Matter?

  • Data Persistence: Stored data is immutable once published on-chain (except when updated through contract logic).
  • Security: The data is secured by the blockchain network’s consensus mechanism.
  • Accessibility: The data is publicly accessible, ensuring transparency.

Potential Use Cases

  • Token Balances: ERC-20 tokens keep track of users’ balances and allowances in contract storage.
  • User Registries: Store user information like IDs, addresses, or roles.
  • Voting Systems: Keep track of votes, proposals, or election results.
  • Marketplace Data: Save product listings, ownership information, or transaction details.

Prerequisites

  • Familiar with Solidity syntax, how to write a simple contract, and how to deploy it.
  • 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).
  • Have access to an account or wallet (e.g., MetaMask) funded with enough test tokens (for a testnet) or actual tokens (for mainnet) to pay for gas fees.
  • You know how to connect to the peaq network or you’re following official peaq documentation for endpoint configuration.

Instructions

Below is a step-by-step process for writing data to contract storage using Solidity. We’ll create a simple contract that demonstrates both storing a single variable and mapping key-value pairs.

1. Define the Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract DataStorage {
    
    // Simple storage variable
    uint256 public storedNumber;

    // Mapping to store addresses and their associated data
    mapping(address => string) public userData;

    /**
     * @dev Constructor that sets an initial number
     * @param _initialNumber The initial number to store
     */
    constructor(uint256 _initialNumber) {
        storedNumber = _initialNumber;
    }
}

Explanation

  • storedNumber is a public state variable of type uint256.
  • userData is a public mapping from an Ethereum (or peaq EVM) address to a string.
  • State variables and mappings like these are stored in the contract’s storage on-chain.

2. Creating Functions to Write Data

We’ll add two functions:

  1. setNumber() - to update the stored number.
  2. setUserData() - to write user-specific data into the userData mapping.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract DataStorage {
    
    // Simple storage variable
    uint256 public storedNumber;

    // Mapping to store addresses and their associated data
    mapping(address => string) public userData;

    /**
     * @dev Constructor that sets an initial number
     */
    constructor(uint256 _initialNumber) {
        storedNumber = _initialNumber;
    }

    /**
     * @dev Updates the stored number in contract storage
     * @param _newNumber The new number to be stored
     */
    function setNumber(uint256 _newNumber) external {
        storedNumber = _newNumber;
    }

    /**
     * @dev Writes or updates user data in the mapping
     * @param _data The data string associated with the caller’s address
     */
    function setUserData(string calldata _data) external {
        userData[msg.sender] = _data;
    }
}

Explanation

  • When setNumber is called, it changes the storedNumber variable.
  • When setUserData is called, it sets or updates the string in the mapping for the calling address (msg.sender).

3. Deploying the Contract

  • Configure your deployment environment
    • If using Hardhat, update the hardhat.config.js (or truffle-config.js for Truffle) to point to a peaq EVM endpoint (e.g. https://peaq.api.onfinality.io/public )
    • If using Remix, simply select the appropriate network in the environment settings.
  • Deploy
    • In Hardhat: npx hardhat run scripts/deploy.js --network yourPeaqNetworkConfig
    • In Truffle: truffle migrate --network yourPeaqNetworkConfig
    • In Remix: Use the “Deploy” button after selecting the correct network and providing the constructor argument _initialNumber.

4. Interacting with the Deployed Contract

After deployment, you can write data to the contract storage:

  • Update the Number
    • Call the setNumber function with a new number. For example, setNumber(42).
  • Write User Data
    • Call the setUserData function with a string. For example, setUserData("Hello, peaq!").

Each transaction will:

  • Consume gas.
  • Write data to the blockchain.
  • Persist the updated data in the contract’s storage.

Summary

Writing data to a smart contract’s storage is fundamental in building decentralized applications. By storing variables and mappings within your Solidity code, you create a transparent, tamper-resistant record of information on the blockchain. Here’s what you’ve learned:

  1. Smart Contract Storage
    • How state variables and mappings persist data on-chain.
  2. Use Cases
    • Simple counters, user registries, voting systems, and more.
  3. Implementation Steps
    • Defining state variables, writing setter functions, deploying to the peaq EVM, and interacting with your contract.

With this knowledge, you can confidently manage on-chain data. Be mindful of gas costs and storage optimization techniques—especially for larger, more complex data structures. For further exploration, look into: