Aclaración de la semántica de "palabra de 256 bits"

EVM tiene "palabras de 256 bits". Algunos casos tratan las cadenas de menos de 32 bytes (256 bits) como ASCII justificado a la izquierda (empaquetado en los bytes más significativos de la palabra).

¿Significa esto que el valor de palabra de la cadena '*' es equivalente a: 42 << 148 ?

Tenga en cuenta que la codificación RLP del único carácter ASCII '*' es de dos bytes, mientras que la codificación RLP de 42 << 148 es diferente. ¿Existen casos extremos importantes para la seguridad y la corrección donde la semántica de palabras EVM y las codificaciones RLP no coinciden del todo?

Respuestas (2)

Será más fácil de entender si hacemos estas dos definiciones ( nota: esto puede no ser del todo correcto, pero es suficiente para la siguiente explicación ):

  • el EVM es la máquina que ejecuta las instrucciones, que tiene entradas y salidas
  • el administrador del estado como el que ingresa / extrae datos de la cadena de bloques.

Muchas de las interacciones con la cadena de bloques (y el administrador de estado) ocurren a través de datos codificados en RLP . Una excepción notable es el ABI con los contratos (el datacampo en la transacción).

El EVM en sí funciona con palabras de 256 bits, lo que significa que cada pila y cada espacio de almacenamiento tiene un ancho de 256 bits y, por lo general, puede direccionarlos de esa manera (existen algunos métodos de direccionamiento de bytes). Al EVM en sí mismo realmente no le importa cómo se almacenan los datos en ese momento. Las instrucciones aritméticas esperarán un cierto formato para los datos, pero eso es todo.

El documento Contract ABI define cómo interactuar con un contrato y cómo interactúan entre sí. Hasta donde sé, Solidity como lenguaje también almacena estructuras de datos internamente de manera similar.

El contrato ABI define diferentes tipos de datos, cada uno con su propio diseño. Los números ( int*/ uint*) se almacenan con relleno a la izquierda, mientras que bytes/ stringse almacena con relleno a la derecha.

El EVM es siempre big-endian de 256 bits. Del Libro Amarillo, Apéndice H: "Al interpretar valores binarios de 256 bits como enteros, la representación es big-endian".

RLP es diferente del Contrato ABI .

Desde la wiki de RLP anterior, las codificaciones "deben representarse en forma binaria big endian sin ceros a la izquierda".

No hay (otras) reglas explícitas sobre el relleno en EVM y RLP.

Algunos casos tratan las cadenas de menos de 32 bytes (256 bits) como ASCII justificado a la izquierda (empaquetado en los bytes más significativos de la palabra).

Como menciona la respuesta de Axic: "El Contrato ABI define diferentes tipos de datos, cada uno con su propio diseño. Los números (int*/uint*) se almacenan con relleno a la izquierda, mientras que los bytes/cadena se almacenan con relleno a la derecha".

¿Significa esto que el valor de palabra de la cadena '*' es equivalente a: 42 << 148 ?

No. El valor ASCII de '*' es 42 (decimal). El valor de la palabra es 42 (0x2a en hexadecimal) y EVM lo manejaría como 42 (lo que equivale a rellenar a la izquierda los primeros 31 bytes con ceros, y el 32.º byte es 0x2a).

... la codificación RLP del único carácter ASCII '*' es de dos bytes

Falso, la codificación RLP de '*' es de 1 byte (0x2a).

¿Existen casos extremos importantes para la seguridad y la corrección donde la semántica de palabras EVM y las codificaciones RLP no coinciden del todo?

El EVM siempre es big-endian de 256 bits, por lo que cualquier codificación RLP de menos de 32 bytes que se proporcione al EVM será tratada por el EVM como si tuviera ceros a la izquierda. El ABI (separado del EVM) es lo que tiene semántica sobre el relleno, que es importante para que coincida por seguridad y corrección.

¿Puede ayudarme con la siguiente pregunta ? ethereum.stackexchange.com/q/30518/7044 No estoy seguro si lo que está escrito arriba es completamente exacto. La especificación RLP parece sugerir que todos los números enteros en Ethereum siempre se representan sin ceros a la izquierda, lo que, por supuesto, afectaría las operaciones de cambio de bits. El documento de RLP dice que RLP no tiene demandas sobre la representación de números enteros, pero que 'Ethereum' sí (sea lo que sea). ¿Es eso lo que quieres decir en la respuesta anterior?