Illustration of how you can access values of private variables instead of them being private
- Project needs to be deployed on Ropsten testnet guide
This project is Deployed @ : 0x2a6f12F36e59453202af66C84cfda52e0826A451
on Ropsten public testnet for testing purpose.
- Locate
truffle-config.js
file in the project and give a 1min read, you shall find private key and infura api key words mentioned.- Reason being you have to mention your API keys in the
.env
file.
- Reason being you have to mention your API keys in the
npx truffle console --network ropsten
-
addr = "0x2a6f12F36e59453202af66C84cfda52e0826A451"
-
web3.eth.getStorageAt(addr,0,console.log)
Result ( in our case ) :
null 0x0000000000000000000000000000000000000000000000000000000000000064
'0x0000000000000000000000000000000000000000000000000000000000000064'
parseInt("0x64", 10)
parseInt("0x64", 16)
web3.eth.getStorageAt(addr,1,console.log)
parseInt("0x1f",16)
web3.eth.getStorageAt(addr,2,console.log)
web3.utils.toAscii("0x7077640000000000000000000000000000000000000000000000000000000006")
Result
'pwd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06'
Got the Private variable value
, our password which we passed during deploy in 1_deploy_storage.js
{ Value in our case : pwd }
For checking value at slot 6, first you have to call function addUser() and pass in the bytes32 password.
For inputing a value which is bytes32, you may need to : i) Convert your string to hexadecimal ii) Add as many zeros to make it a hexadecimal of length 64.
In our case, we used stringtohexconvertor and added 0's at the start. guide
Our input was : 0x00000000000000000000000000000000000000000000000000006e6577707764 which equivalent to 'newpwd' in string. 0x is mandatory
Now move to Ropsten testnet and at your deployed contract address and call function addUser.
Once it's done, you have a value at slot 6. To get the value stored at slot 6,
web3.eth.getStorageAt(addr,6,console.log)
To get password of first user which you added by calling addUser() function in Ropsten,
web3.utils.soliditySha3({ type:"uint", value:6})
( Since value is stored at the hash of 6th slot, therefor using soliditySha3() and '6' as the value ) Our case :0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f
hash = '0xabcd'
( Set the value of 10th point as the hash )web3.eth.getStorageAt(addr, hash, console.log)
This shows null but as we add 1 to the hash, we reach to password storage which in our case is 0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40
and follow the same command :
hash = '0xabcd'
web3.utils.getStorageAt(addr,hash,console.log)
- Convert the result received by 14th point to Ascii value by
web.utils.toAscii("0xabcd")
.
There is your password of user you added, in our case it's shows \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00newpwd'
Now time to check mapping.
Let's add another user following the same steps from line.no 41 to 49.
Now we have 2 users. Let's get the hash of slot 7 but because it's mapping so we need hash of (key,slot), so here we have to specify the key also.
web3.utils.soliditySha3({ type :"uint", value:"1"},{ type:"uint",value:7})
hash = '0xabcd'
( replace 0xabcd with the value received from 16th point line no.77 )web3.eth.getStorageAt(addr,hash,console.log)
( you may get0x0000000000000000000000000000000000000000000000000000000000000001
if you have 2 users and followed same process as ours. )
Now let's get the password for second user we added during line 73.
Same process, we need to add 1 to hash which gives us 0xb39221ace053465ec3453ce2b36430bd138b997ecea25c1043da0c366812b829
19. hash = 0xabcd
20. web3.eth.getStorageAt(addr,hash,console.log)
Result in our case : 0x000000000000000000000000000000000000000000000000000074776f707764
To convert to string : 21. `web3.utils.toAscii("0x000000000000000000000000000000000000000000000000000074776f707764")
Gives us : '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00twopwd'
( There's our second user password! ) and this is how we access private storage variables. ( Mapping and password both were having private visibility. )
You may wonder how to add 1 to Hexadical number ( Here is a simple guide ) :
Hexadecimal number count is as follows :
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
After F, it goes :
10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F
After 1F it goes :
20,21,22,23,24,25,26,27,28,29,2A,2B,2C,2D,2E,2F
After 2F it goes :
30,31,32,33,34,35,36,37,38,39,3A,3B,3C,3D,3E,3F and so on...
Hope you get the pattern.
Now you shall try to add 1 to 0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f
as we did in line 62
.
Check from last, it's f
which is last digic of hex so it becomes 0
and digit before it increases by 1 so 3
becomes 4
and we get
0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40
Simple right!