Ethernaut. Задача 12. Privacy
В этой задаче нам нужно получить доступ к ключу в массиве data.
Ссылка на задачу
В чем суть?
Мне нравятся такие задачи на работу с памятью. Этот пример очень похож на один из предыдущих - Vault, но с большим количеством переменных.
Тут нужно знать несколько моментов о работе с памятью. Пройдемся по переменным в задаче.
bool public locked - булевы переменные в Solidity занимают весь слот памяти в 32 байта.
uint256 public ID - 256 и есть те же 32 байта, поэтому занимается еще один целый слот памяти.
Далее немного интереснее. Тут сразу три переменные (uint8 private flattening, uint8 private denomination, uint16 private awkwardness) занимают весь слот на 32 байта. Это происходит потому, что они идут друг за другом.
Если, например, один unit8 лежал бы где-нибудь после массива, то в слот поместились бы только один uin8 и uint16, которые находятся вместе. Поэтому при написании смарт контрактов, вам стоит обращать на это внимание и располагать небольшие переменные рядом друг с другом.
Затем идет нужный нам массив с фиксированной длиной bytes32[3] private data. Из функции unlock() нам становится понятно, что ключ лежит в последнем значении массива.
Если разбить все по слотам памяти, то получается:
bool public locked - 0 слот;
uint256 public ID - 1 слот;
uint8 private flattening, uint8 private denomination, uint16 private awkwardness - 2 слот;
1 элемент массива data - 3 слот;
2 элемент массива data - 4 слот;
3 элемент массива data - 5 слот;
А дальше, все как в примере с Vault: разворачиваем контракт в hardhat и достаем значение из 5 слота при помощи ethers.provider.getStorageAt().
#ethernaut
Post #398
166
- 👍 1