0

The following code works - after changing uint to unit16 - and I find now after running it, that getStorageAt does not show the actual values. Are the values stored outside that access to that method or in memory?

pragma solidity ^0.4.18;

contract CA3 {

struct Student {
        uint16 age;
    uint16 income;
    uint16 score;
    uint16 attendance;
}
Student[] public students;

function setStudent (uint16 _age, uint16 _income, uint16 _score, uint16 _attendan
ce) public {
   Student memory tempStudent = Student({age: _age, income: _income, score: _scor
e, attendance: _attendance});
        students.push(tempStudent);
//students.push(Student({age: _age, income: _income, score: _score, attendance: _
attendance}));


}

}

> con.setStudent(8,1,1,1)
"0x9886c2de6ace867efedc4c06d2fa79d7148807287a827d2f31a6f01956d6b4ca"

> con.students(0)
[8, 1, 1, 1]

> eth.getStorageAt(con.address,0)
"0x0000000000000000000000000000000000000000000000000000000000000001"

The 1 appears to be somekind of index.

When I run -

> eth.getStorageAt(con.address,0)
"0x0000000000000000000000000000000000000000000000000000000000000001"
> con.setStudent(8,10,10,15)
"0x2e9ad070deaa4cd044ae3d1b4673a676efde828faf5043bc1b62fdb746efb583"
> eth.pendingTransactions.length
0
> con.students(1)
[8, 10, 10, 15]
> eth.getStorageAt(con.address,1)
"0x0000000000000000000000000000000000000000000000000000000000000000"
> eth.getStorageAt(con.address,2)
"0x0000000000000000000000000000000000000000000000000000000000000000"
> eth.getStorageAt(con.address,0)
"0x0000000000000000000000000000000000000000000000000000000000000002"

After the second run, storage shows 2. But where is the students array stored?

I just exited the geth and entered again to find the same results. So students are not held in memory. The values are in storage. But where? Also why does getStorageAt not show them? Is there an equivalent method to show them?

1

This should help:

https://solidity.readthedocs.io/en/develop/miscellaneous.html#layout-of-state-variables-in-storage

In your case, I think the first array element is at slot keccak256(uint256(0)).

The value at slot 0 is the length of the array.

EDIT

web3.js 0.2x.x code to do it:

web3.eth.getStorageAt(contractAddress,
  web3.sha3(web3.padLeft("0", 64), { encoding: 'hex' }),
  function (err, result) {
    console.log(result);
  }
);

Here's code to read an arbitrary index of the array:

var n = 1;
var startSlot = web3.toBigNumber(
    web3.sha3(web3.padLeft("0", 64), { encoding: 'hex' }));
var slot = "0x" + startSlot.add(n).toString(16);

web3.eth.getStorageAt(contractAddress, slot, function (err, result) {
  console.log(result);
});
| improve this answer | |
  • Do we use web3.sha to find out the location? How can we check the actual storage values for that array in geth? – Trevor Lee Oakley Feb 28 '18 at 2:36
  • Yes. See my edit. – user19510 Feb 28 '18 at 2:49
  • Brilliant. I tested the code and had this - 0x0000000000000000000000000000000000000000000000000001000100010008 for "0" and when I entered "1" I had just all zeros. How would we get the elements of students(0,1,...). BTW - a brilliant answer. I just saw code ver #2 in your answer - I will test that. – Trevor Lee Oakley Feb 28 '18 at 3:13
  • This all works now. Now I have to try and understand why it works. – Trevor Lee Oakley Feb 28 '18 at 3:19
  • so is students stored in the contract storage? startslot is all 0s for one slot size (32 bytes) but why is that the start position? Is there is a link to explain this? – Trevor Lee Oakley Feb 28 '18 at 4:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.