Accessing Private Data| Hack Solidity #4

Before starting, we need to understand how the storage of state variables works in solidity via SLOTS.
You can follow the Smart Contract Programmer’s video if you have difficulty understanding the concepts I am going to explain.
The Slot System
Solidity stores the variables defined in the contract via slots. Each slot can hold up to 32 bytes or 256 bits. Look at the image given below, the variables foo, bar, and num occupy the whole slot because their size is equivalent to 256 bits. the address takes up to 20 bytes and the boolean needs 1 byte. When multiple variables are getting filled in the same slot index, they get filled from right to left.

The access specifier (private)
When writing code for a blockchain-based application(dApps), you can define a variable to be public
or private
. The whole point of defining a variable private
is to prevent other contracts from modifying it. But, remember blockchains are supposed to be transparent, which means irrespective of the variable being private
or public
, everyone can read it. Hence, storing sensitive information like passwords is a very bad idea.
Understanding via Example
The Vault Contract has various kinds of variables defined but the most interesting is the bytes32 password, an array of struct Users that stores id and password.

addUsers
function pushes additional users to the Users struct-array.

The contract is already deployed at Ropsten TestNet Address “0x3505a02BCDFbb225988161a95528bfDb279faD6b”
Let's use truffle to learn how to interact with the slots and finally extract the passwords.
Truffle Demo
Let's connect to Ropsten and initialize the contract address we have.

If you are looking at the contract above, I have already marked what variables are stored in which slots.
//Syntax to access the data stored in the slots
web3.eth.getStorageAt(contractAddress, slotIndex, console.log)
In the below example, we are reading the data at slotIndex=0, and then converting the hex-to-decimal.

In this example, we are trying to read the contents of the slotIndex=2 i.e., the password
variable. The output is in bytes32, which can be converted to ASCII via web3.utils.toAscii
function.

Finally, time to read the user ids and passwords. The first getStorageAt
call outputs the array length. The soliditySha3
returns the hash of the storage of the first array element.
To access the next storage item. we need to increment the hash value by 1. Therefore, 3f — >40.

The Solution
Blockchains are transparent-by-design, so do not store your sensitive information on the blockchain.
Hope you enjoyed reading it.
Ciao!!!