¿Qué es este código evm producido por solc en esta verificación de matriz pública y por qué?

Cuando solc crea código para matrices cuando se declaran public. En particular, contiene una verificación de la longitud de la matriz. Por ejemplo, esto:

contract OutOfBoundsException {
    uint256[8] public array;
}

compilado con solc --optimizeproduce:

...
tag_3:
  pop
    /* "contracts/oobtest.sol":46:68  uint256[8] public array */
  tag_4
  calldataload(0x4)
  jump(tag_5)
tag_4:
 # dead code
tag_5:
  0x0
  dup1
  sload
  dup3
  swap1
  dup2
  lt
  tag_6
  jumpi
  invalid
tag6
 # ...

La --optimizebandera se usó para eliminar parte de la basura y simplificar algo de lo anterior.

¿Qué está pasando en el bloque básico que comienza tag_5y por qué es necesario?

Respuestas (1)

La respuesta corta: ese código se usaría si el contrato hubiera intentado acceder arrayusando una función de acceso. Pero solcno es lo suficientemente inteligente como para darse cuenta de que eso no puede suceder aquí y en muchas otras situaciones como esta.

Aquí hay una situación en la que se necesita esta verificación:

contract PublicArray {
   uint256[8] public array;
}

contract InvalidAccess {  
    PublicArray array_contract;
    constructor() {
         array_contract = PublicArray.at(0x(...))
    }

    function go() {
       return array_contract.array[1000];
    }
}

Esta información y el código anterior son del famoso Bernhard Mueller .

Dado que arrayes público, solccrea una función de acceso para él.

tag3es el comienzo de esa función. calldataload(0x4)carga el índice de calldata, luego tag_5hay una verificación de que calldataload(0x4)< array.length.