Tengo una lista ordenada ordenada que contiene alrededor de 1000 artículos. Cuando recibo un artículo nuevo, mi objetivo es empujar el artículo a la lista manteniendo el orden ordenado. Entonces, si recibo un valor muy pequeño, debo iterar toda la lista para encontrar la cola de la lista. Sugerí que podría recuperar el índice a través de la función constante y mi función de transacción podría usar el valor del índice devuelto para empujar el elemento a la ubicación correcta sin gastar gasolina para iterar la lista.
Mi objetivo es seguir esta guía ( https://ethereum.stackexchange.com/a/13855/4575 ) para llamar a una función constante y enviar su valor de retorno a una función de transacción.
getIndex() => constant
setArray() => transaction
setArray( getIndex() );
Surge la pregunta de que: cuando llamo a una función constante en mi nodo cliente, ¿es posible verificar si el número de bloque de mi nodo cliente es el mejor número de bloque o está detrás? Si está atrasado, la función constante puede devolver información incorrecta.
Por ejemplo, el mejor bloque de blockchain es 100. Pero mi nodo se encuentra actualmente en blockNumber 90 (básicamente detrás de blockchain). Entonces, cuando el nodo del cliente obtiene el índice de la lista hasta los primeros 90 bloques y pierde los elementos generados en los 10 bloques restantes.
[P] ¿Es posible verificar que el número de bloque del nodo del cliente coincida con el mejor número de bloque de la cadena de bloques, que es el último número de bloque?
Como puede ver en la imagen de ejemplo, el número de bloque en los nodos del cliente puede variar. El mejor número de bloque es 1 002 312, pero el número de bloque es 1 002 304 en el nodo superior. Pero a veces todos los nodos están en el último número de bloque. Por lo tanto, es difícil confiar en el comportamiento del nodo.
La siguiente respuesta parece funcionar:
web3.eth.syncing; sync.highestBlock
Pero el número devuelto highestBlock
todavía parece un número de bloques más pequeño que en mi mejor número de bloque en mi cadena privada. ¿Es un caso normal?
Ethereum es un sistema probabilístico.
En mi opinión , simplemente no hay forma de estar seguro de que uno está mirando el último bloque que finalmente lo convertirá en la cadena más larga con una probabilidad mínimamente pequeña de que una reorganización de la cadena reorganice las cosas. Por lo tanto, no creo que confiar en un testigo del cliente sea una buena forma de informar un proceso de clasificación.
Creo firmemente en el principio de que un contrato inteligente debe salvaguardar la integridad del almacenamiento interno de datos. Si los datos deben ser accesibles en orden ordenado (no necesariamente una preocupación en la cadena), entonces el orden de los datos se encuentra dentro del alcance de la "integridad interna garantizada".
Por esa razón, debe desaparecer la confianza en la información correcta de lo call()
que usted describe y la necesidad de que sea actual . Es una dependencia externa inaceptable y probablemente no solucionable satisfactoriamente.
Considere tres enfoques generales
El primero puede requerir una profundidad considerable en la búsqueda interna y no escalará bien. El segundo enfoque depende de información confiable del exterior; confiabilidad que probablemente no podamos lograr. El tercer enfoque se basa en una pista sobre la eficiencia del gas, pero deja que el contrato tome la decisión final y correcta.
"Cerca" es básicamente una ventaja en el proceso de búsqueda. Es importante destacar que el contrato completará la búsqueda y llegará a sus propias conclusiones sobre dónde y cómo insertar "Bob" dado el estado actual de la lista ordenada. Cualquier lista en cualquier estado en cualquier bloque en cualquier cadena tendría que estar correctamente ordenada, debido a que no depende de una guía externa precisa.
En resumen:
Primero consideraría si el tipo realmente necesita estar en la cadena.
Si la clasificación es inevitable, organice una lista ordenada ordenada o un esquema de índice similar en el contrato. El contrato por sí solo debe determinar los puntos de inserción correctos. Una "pista" puede reducir la búsqueda interna necesaria para hacerlo, lo que reduce el costo del gas y ayuda a garantizar que el proceso funcione en una lista de cualquier tamaño.
Espero eso ayude.
Los pasos serían
La parte de la transacción de envío requiere algunos cambios en la capa central/api.
La API de RPC te respalda.
Simplemente use esta función para verificar su último bloque y el del cliente. Dependiendo de cuánto desee confiar en el cliente, puede comparar los valores del lado del cliente o asegurarse de que se le transfieran sin manipulación.
Función para obtener el último bloque:
web3.currentProvider.sendAsync({
method: "eth_blockNumber",
params: [],
jsonrpc: "2.0",
id: 83
} function (error, result) {...})
Más detalles sobre la API JSON RPC y cómo puede usarla de muchas maneras diferentes (con curl, por ejemplo): Aquí
Puede usar curl, por cierto, para verificar el bloqueo actual de los clientes de forma remota, si su configuración de nodo y firewall permite la conexión.
Por supuesto, no olvide convertir el resultado en un número decimal, parseInt(value, 16)
.
Puede encontrar un ejemplo de cómo implementar tales funciones web3 aquí.
curl --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}' -X POST localhost:8545
Esto también devuelve el número de bloque actual del nodo, no el número de bloque más alto alcanzado. Obtener el número de bloque del cliente no es el problema, pero puede estar detrás del número de bloque más alto. @NikitaFuchs
alper
Rob Hitchens
alper
web3.eth.syncing;
no funciona todo el tiempo y cuando no devuelve información válida, el último número de blockchain también puede cambiar hasta que se devuelva una información válida. Ethereum es un sistema probabilístico, como dijiste, supongo que no puedo esperar la hora exacta en que responda desde la red. perdón por tantas preguntas... @RobHitchensNeo
Rob Hitchens