¿Cómo podemos obtener el valor de estado de una variable del número de bloque anterior usando web3?

Tengo una cadena privada y ejecuto mi propio nodo de archivo. El nodo conectado con la --fast cache=1024opción.

Por ejemplo, tengo una función establecida en mi contrato inteligente.

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

}

Esta función se llama en el bloque número 100 y 200.

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

En este punto. si nuestra cadena de bloques está sincronizada, como sabemos, cuando la llamamos smartContract.get()devuelve 20.

Aquí se menciona que el contacto inteligente solo puede ver el estado actual.

Un contrato solo puede ver el estado actual cuando se ejecuta, no los estados anteriores. Esta restricción permite que los nodos de validación funcionen solo con el estado actual, en lugar de tener que almacenar y poder acceder a todos los estados anteriores.

Aquí podemos obtener datos de bloques anteriores. Como podemos obtener datos de bloques anteriores, podríamos obtener los estados anteriores.

[P] ¿Podría web3 recuperar el estado de un valor de los números de bloque anteriores en lugar de devolver su último valor de estado?

Si proporcionamos el número de bloque como 100 smartContract.get() at 100,; ¿de alguna manera web3 puede devolver valueel valor en el bloque número 100 en lugar de en latest?

¿Cómo? No pude encontrar el ejemplo específico en el enlace que compartes. ¿Qué tal web3.py? @Henk
Una alternativa podría ser disparar un evento cuando se cambia la variable de estado.
Eso es posible, pero quiero sacar el evento de la tabla, ya que ya se ha almacenado en la memoria, y no quiero consumir gas adicional para el evento. @Jesse Busman
@Alper Cuando realiza una consulta , puede pasar un parámetro adicional con el número de bloque, el valor predeterminado es 'más reciente', pero puede pasar 'pendiente' o un número/hash de bloque explícito. El problema es que los clientes que no son de archivo solo tendrán los 256 estados más recientes, consultar un bloque más allá de ese rango devolverá un error.
¿Qué significa que no puedo obtener el estado anterior de las variables a través de web3 y, en cambio, mi única opción es usar eventos? @Ismael
@Alper No tiene la garantía de recuperar estados antiguos, a menos que ejecute su propio nodo de archivo o guarde explícitamente todos los cambios en el almacenamiento de su contrato.
Si estoy ejecutando mi propio nodo archivado, ¿cómo podría lograrlo? @Ismael

Respuestas (1)

[P] ¿Podría web3 recuperar el estado de un valor de los números de bloque anteriores en lugar de devolver su último valor de estado?

Sí, en web3.py v4.0+.

Al realizar una llamada de contrato, puede especificar un número de bloque (o hash). Estos ejemplos son de los documentos 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')