Может ли контракт получить доступ к коду другого контракта?

Используя web3.js, EVM (байт-код) контракта можно получить с помощью web3.eth.getCode(addressOfContract). Может ли это быть выполнено контрактом с использованием адреса другого контракта? Если да, то как? address.codeнет в Solidity.

Ответы (2)

Обновление для Solidity v0.8

Вам больше не нужно использовать встроенный ассемблер для получения кода другого контракта. Вы можете просто сделать это так:

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

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

В Yellow Paper упоминается код операции EVM, EXTCODECOPYкоторый копирует код учетной записи в память. Похоже, что да: контракт может получить доступ к коду другого контракта.

Solidity 0.3.1теперь предоставляет extcodecopyи другие коды операций как часть встроенной функции сборки :

В следующем примере приведен код библиотеки для доступа к коду другого контракта и его загрузки в переменную bytes. Это вообще невозможно с «простым Solidity», и идея состоит в том, что библиотеки сборки будут использоваться для улучшения языка таким образом.

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)
    }
  }
}