Мое сомнение связано с приведенным ниже кодом:
contract RandomNumber{
uint number;
function get_random() public{
bytes32 ramdonNumber = keccak256(abi.encodePacked(block.timestamp,blockhash(block.number-1)));
number = uint(ramdonNumber);
}
}
Мы присваиваем переменной number случайное число, но если я не установлю общедоступный номер или не создам другую общедоступную функцию для извлечения значения, то никто не узнает точное значение через Etherscan. А как же шахтеры? Могут ли они каким-то образом получить эти нераскрытые данные?
Я пытался: Google, технический документ Ethereum, документация Solidity





Если предположить, что контракт развернут в общедоступной сети (например, Ethereum), значение всегда доступно для чтения.
Не напрямую через автоматически сгенерированную функцию получения (она доступна только для свойств public), что означает, что она недоступна в цепочке.
Но любой (включая майнеров) может создать автономное приложение (например, на JavaScript), которое запрашивает конкретный слот хранилища, где хранится значение — в данном случае это слот номер 0. И оно возвращает «секретное» значение.
Код JS с использованием библиотеки ethers, оболочки для RPC API узлов Ethereum:
const number = await provider.getStorageAt(CONTRACT_ADDRESS, SLOT_NUMBER);
Документы: https://docs.ethers.org/v5/api/providers/provider/#Provider-getStorageAt
И собственно метод RPC API: https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getstorageat
В этом случае переменная хранится только в памяти, а не в хранилище, и получить ее методом getStorageAt не получится... Но - производитель блока (майнер на PoW, валидатор на PoS) знает block.number , block.timestamp и blockhash перед публикацией блока. И после того, как блок был опубликован, значение также можно получить, отладив транзакцию. Например geth.ethereum.org/docs/interacting-with-geth/rpc/…
То есть, если я не использую block.number, block.timestamp в качестве параметров хэш-функции keccak256, то майнеры/валидаторы не смогут получить значение?
@Gap Они все еще могут получить значение до того, как транзакция будет включена в блок. Но они также могут повлиять на эти block.number и другие значения, упомянутые в вашем фрагменте.
Спасибо! Я хорошо понимаю, как данные хранятся в слотах с вашей ссылкой, прикрепленной ниже. Но как насчет этого:
function get_random() public view returns(uint num){ bytes32 ramdonNumber = keccak256(abi.encodePacked(block.timestamp,blockhash(block.number-1))); num = uint(ramdonNumber); return num; }Переменная num все еще хранится в определенном слоте?