Как мы можем получить значение состояния переменной из предыдущего номера блока, используя web3

У меня есть частная сеть, и я использую собственный узел архивации. Узел, связанный с --fast cache=1024опцией.

Например, у меня есть заданная функция в моем смарт-контракте.

contract smartContract {
    uint  value;
    function set(uint input) returns (bool success) {
         value = input;
    }
    function getValue() public view
     returns (uint)
    {
        return value;
    } 

}

Эта функция вызывается в блоке номер 100 и 200.

smartContract.set(10) //deployed at block number 100
smartContract.set(20) //deployed at block number 200

В этот момент. если наша цепочка блоков синхронизирована, как мы знаем, когда мы вызываем ее, smartContract.get()она возвращает 20.

Здесь упоминается, что смарт-контакт может видеть только текущее состояние.

Контракт может видеть только текущее состояние, когда он выполняется, а не предыдущие состояния. Это ограничение позволяет проверяющим узлам работать только с текущим состоянием, а не хранить и иметь доступ ко всем предыдущим состояниям.

Здесь мы можем получить данные предыдущих блоков. Поскольку мы можем получить данные предыдущего блока, мы можем получить и предыдущие состояния.

[В] Может ли web3 получить состояние значения из предыдущих номеров блоков вместо того, чтобы возвращать его последнее значение состояния?

Если мы укажем номер блока, например 100, smartContract.get() at 100; каким-то образом web3 может вернуть valueзначение в блоке номер 100 вместо latest?

Как? Я не смог найти конкретный пример по ссылке, которой вы делитесь. Как насчет web3.py? @Хенк
Альтернативой может быть запуск события при изменении переменной состояния.
Это возможно, но я хочу убрать событие из таблицы, так как оно уже было сохранено в памяти, и я не хочу потреблять дополнительный газ для события. @Джесси Басман
@Alper Когда вы делаете запрос , вы можете передать дополнительный параметр с номером блока, по умолчанию «последний», но вы можете передать «ожидающий» или явный номер блока / хэш. Проблема в том, что неархивные клиенты будут иметь только самые последние 256 состояний, запрос блока за пределами этого диапазона вернет ошибку.
Это означает, что я не могу получить предыдущее состояние переменных через web3 и вместо этого могу использовать только события? @Исмаэль
@Alper Вам не гарантируется извлечение старых состояний, если вы не запустите свой собственный узел архивации или явно не сохраните все изменения в хранилище вашего контракта.
Если я запускаю свой собственный архивный узел, как я могу этого добиться? @Исмаэль

Ответы (1)

[В] Может ли web3 получить состояние значения из предыдущих номеров блоков вместо того, чтобы возвращать его последнее значение состояния?

Да, в web3.py v4.0+.

При вызове контракта вы можете указать номер блока (или хэш). Эти примеры взяты из документации web3.py :

# You can call your contract method at a block number:
>>> token_contract.functions.myBalance().call(block_identifier=10)

# or a number of blocks back from pending,
# in this case, the block just before the latest block:
>>> token_contract.functions.myBalance().call(block_identifier=-2)

# or a block hash:
>>> token_contract.functions.myBalance().call(block_identifier='0x4ff4a38b278ab49f7739d3a4ed4e12714386a9fdf72192f2e8f7da7822f10b4d')
>>> token_contract.functions.myBalance().call(block_identifier=b'O\xf4\xa3\x8b\'\x8a\xb4\x9fw9\xd3\xa4\xedN\x12qC\x86\xa9\xfd\xf7!\x92\xf2\xe8\xf7\xdax"\xf1\x0bM')

# Latest is the default, so this is redundant:
>>> token_contract.functions.myBalance().call(block_identifier='latest')

# You can check the state after your pending transactions (if supported by your node):
>>> token_contract.functions.myBalance().call(block_identifier='pending')