Можно ли получить доступ к истории хранения из контракта в солидности?

С помощью web3 я могу получить доступ к истории блокчейна следующим образом:

web3.eth.getBalance('0x1234') // returns current balance at address 0x1234
web3.eth.getBalance('0x1234', 1000) // returns balance at block 1000

См. https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethdefaultblock

Я не смог найти ничего подобного в Solidity. Есть ли соответствующий паттерн в Solidity? Или в байт-коде EVM? Или фундаментальные причины, почему это невозможно сделать?

Ответы (2)

Нет, код Solidity (и код EVM в целом) может считывать текущее состояние только в том блоке, в котором он вызывается. Если бы он мог считывать состояние в предыдущих блоках, вам понадобилась бы вся история блокчейна для проверки блока. Не допустив этого, разработчики Ethereum сделали возможным проверку блока только с текущим состоянием, что является гораздо менее строгим требованием.

Теоретически должно быть возможно построить доказательство Меркла того, что адрес имеет определенное состояние в конкретном блоке, и передать необходимые данные, чтобы позволить контракту проверить это доказательство. Таким образом, вызывающая сторона контракта могла получить старые данные, как вы делаете в своем примере с Web3, а код Solidity мог получить эти данные в качестве параметра, убедиться, что они реальны, и действовать соответствующим образом. Тем не менее, это, вероятно, не тривиальная вещь, и я не знаю ни одного примера того, как это делается.

Если вам нужна история состояния в предыдущих блоках, обычным решением является явное сохранение этой истории в хранилище контрактов и добавление к вашим данным истории каждый раз, когда вы вносите изменения.

Я вижу смысл в том, что желательно иметь возможность проверять блок только с текущим состоянием. Но если цена/скорость является проблемой, не лучше ли было бы добавить код операции и сделать его (очень) дорогим, вместо того, чтобы ограничивать EVM таким фундаментальным образом?
Дело не только в том, что обременительно считывать набор всех предыдущих состояний, но и в том, что на самом деле требуется иметь его в первую очередь, поэтому его удорожание не решит проблему.
Насколько я понимаю, каждый полный узел уже «имеет» всю историю в том смысле, что он может восстановить ее из генезисного блока и истории транзакций (у моего локального узла нет проблем с восстановлением промежуточных состояний, если я запрашиваю его с помощью web3). (Возможно, я сейчас спрашиваю о мотивах разработчиков EVM, и, возможно, это не то место, где нужно спрашивать :-)
Полный узел работает, а легкий узел — нет. Также при шардинге полные узлы одного шарда будут легкими узлами другого.

Да, это возможно с Web3 в любом заданном блоке.

Если в вашем договоре есть:

контракт ValueStore {
    функция getValue(uint param) возвращает константу (uint returnValue);
}

Затем, после создания экземпляра вашего контракта Web3, вы можете сделать:

valueStoreInstance.getValue.call (параметр, blockNumber, функция (ошибка, возвращаемое значение) {});
Пожалуйста, ответьте, возможно это или нет?
Я дал вам код для Web3. Этот код работает. Так что да, это возможно для Web3.
спасибо, но я не об этом спрашивал. у меня вопрос можно ли сделать подобное в солидности (т.е. в ЭВМ)