Cast Storage

NEWSLETTER

Drop your email to read the BlockApex newsletter and keep yourself updated around the clock.

    Table Of Content

    Share:

    Introduction

    Lets understand the smart contract storage model in Ethereum and EVM-based chains and how you can access the public and private variables of any smart contract deployed on the blockchain. We can do this by using cast storage. 

    Contract:

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.7;
    contract Storage {
    address public contractAddress = address(this);
    bytes private BlockApex = hex"426c6f636b41706578";
    uint256 public Slot = 0;
    struct Passwords {
     string name;
    uint256 secretKey;
    string password;
    }
    Passwords[] private passwords;
    mapping (uint256 => Passwords) private destiny;
    }

    Contract Address (Rinkeby) : 0xfE43d853eBa639c40d071ebd046c9F61fF215ebF

    Contract Link : https://rinkeby.etherscan.io/address/0xfe43d853eba639c40d071ebd046c9f61ff215ebf

    Let's start: 

    | - - - - - - - - - - - -Slot 0 - - - - - - - - - - - -|
    address public contractAddress = address(this); 
    | - - - - - - - - - - - -Slot 1 - - - - - - - - - - - -|
    bytes private BlockApex = hex"426c6f636b41706578";
    | - - - - - - - - - - - -Slot 2 - - - - - - - - - - - -|
    uint256 public Slot = 0;
    | - - - - - - - -No Slot Consumed- - - - - - - -|
    struct Passwords {
    string name;
    uint256 secretKey;
    string password;
    }
    | - - - - - - - - - - - -Slot 3 - - - - - - - - - - - -| // size will be here
    Passwords[] private passwords;
    | - - - - - - - - - - - -Slot 4 - - - - - - - - - - - -|
    mapping (uint256 => Passwords) private destiny;

    Static Sized Variables can be simply accessed with command

    Cast storage $ContractAddress slotNumber
    cast storage 0xfE43d853eBa639c40d071ebd046c9F61fF215ebF 0

    Similarly for the storage slot 1 

    cast storage 0xfE43d853eBa639c40d071ebd046c9F61fF215ebF 1

    This command will lead you to the data stored in memory slots. . 

    The data you receive might be in hex, to make it meaningful try using (cast —to-ascii (hex))

    Eg:

    cast storage 0xfE43d853eBa639c40d071ebd046c9F61fF215ebF 1

    Result: 0x426c6f636b417065780000000000000000000000000000000000000000000012

    cast –to-ascii 0x426c6f636b417065780000000000000000000000000000000000000000000012

    Result: BlockApex

    Accessing mapping data in solidity is a little bit complex. First you  identify the slot where your mapping currently stands. In our case, the mapping is on the 4th slot. Another important thing to note is since mappings  are hashTables they are only accessed by keys so you need to pass [key + StorageSlot] to the keccak hashing function in order to retrieve the data. 

    Eg: 

    cast keccak (key + storageSlot) 
    cast keccak “0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004

    This command will give you the respective hash which is actually the slot of the first element  stored in mapping. To access the 2nd element increment in the key like:

    Eg: 

    cast keccak (key++  +  storageSlot) 
    cast keccak “0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004

    It will give you the hash slot of the 2nd item of the mapping, if you iterate through you can access all the items.

    Now send this hash (result of keccak) to the cast command as follows 

    Eg: 

    cast storage $contractAddress hash
    cast storage 0xfE43d853eBa639c40d071ebd046c9F61fF215ebF 0xabd6e7cb50984ff9c2f3e18a2660c3353dadf4e3291deeb275dae2cd1e44fe05

    This command leads you to the 1st property of the struct that is saved in the mapping and further on as you increment in the key. 

    Now the problem is if your mapping contains a struct, you only get the 1st element of the struct which is the string property [name] in our case.

    Eg: 

    struct Passwords {
    string name;
    uint256 secretKey;
    string password;
    }

    To iterate further in the same struct, you need to increment one in your keccak hash, for instance if you get a hash like 

    0xabd6e7cb50984ff9c2f3e18a2660c3353dadf4e3291deeb275dae2cd1e44fe05+1 (add 1) 

    the next element is held in

    0xabd6e7cb50984ff9c2f3e18a2660c3353dadf4e3291deeb275dae2cd1e44fe06

    Now we send this updated hash to the cast command like 

    Eg: 

    cast storage $contractAddress hash
    cast storage 0xfE43d853eBa639c40d071ebd046c9F61fF215ebF 0xabd6e7cb50984ff9c2f3e18a2660c3353dadf4e3291deeb275dae2cd1e44fe06

    This leads you to the second element of the struct which is the secretKey.

    Further add 1 again in the hash.

    0xabd6e7cb50984ff9c2f3e18a2660c3353dadf4e3291deeb275dae2cd1e44fe06+1 

    the next element is held in 0xabd6e7cb50984ff9c2f3e18a2660c3353dadf4e3291deeb275dae2cd1e44fe07

    Again hit the contract with the updated hash and you will get the password which is the last element of the struct stored in mapping!

    Congrats you have unveiled the mystery of Solidity internals!
    PS: cast can come handy only if you want.

    More Weblogs

    How Can a VPN Protect You From Spying?

    VPN uses a private network that helps users mask their surfing history on the internet, hackers even advertisers can’t steal the data and use it for their means. 

    Smart Contract Security Audit: An Auditor's Interrogation

    A comprehensive introduction to smart contract security audit and preparation of relevant interview questions.

    GameFi: Future of Gaming or Short-lived Gimmick?

    On the surface, the GameFi industry sounds revolutionary. However, digging a little deeper reveals several questions about its legitimacy. What are the risks associated with its play-to-earn model? Are all games which claim to be a part of GameFi credible? And, at the end of the day, is this a viable direction for gaming, or nothing more than a short-lived gimmick?

    Designed & Developed by: 
    All rights reserved. Copyright 2020-21