¿Puede un contrato acceder al código de otro contrato?

Usando web3.js, el EVM (código de bytes) de un contrato se puede obtener mediante web3.eth.getCode(addressOfContract). ¿Se puede realizar esto mediante un contrato utilizando la dirección de otro contrato? ¿Si es así, cómo? address.codeno está en Solidity.

Respuestas (2)

Actualización para Solidez v0.8

Ya no tiene que usar el ensamblado en línea para obtener el código de otro contrato. Simplemente puedes hacerlo así:

// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;

function getCode(address a) public view returns (bytes memory) {
    return a.code;
} 

El Libro Amarillo menciona un código de operación EVM EXTCODECOPYque copia el código de una cuenta en la memoria. La respuesta parece ser sí: un contrato puede acceder al código de otro contrato.

Solidity 0.3.1ahora proporciona extcodecopyy otros códigos de operación como parte de su función de ensamblaje en línea :

El siguiente ejemplo proporciona código de biblioteca para acceder al código de otro contrato y cargarlo en una variable de bytes. Esto no es posible en absoluto con "solidity simple" y la idea es que las bibliotecas de ensamblaje se utilicen para mejorar el lenguaje de esa manera.

library GetCode {
  function at(address _addr) returns (bytes o_code) {
    assembly {
      // retrieve the size of the code, this needs assembly
      let size := extcodesize(_addr)
      // allocate output byte array - this could also be done without assembly
      // by using o_code = new bytes(size)
      o_code := mload(0x40)
      // new "memory end" including padding
      mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), bnot(0x1f))))
      // store length in memory
      mstore(o_code, size)
      // actually retrieve the code, this needs assembly
      extcodecopy(_addr, add(o_code, 0x20), 0, size)
    }
  }
}