10

Using web3.js, the EVM (bytecode) of a contract can be obtained by web3.eth.getCode(addressOfContract). Can this be performed by a contract using the address of another contract? If so, how? address.code isn't in Solidity.

eth
  • 85,679
  • 53
  • 285
  • 406

2 Answers2

10

The Yellow Paper mentions an EVM opcode EXTCODECOPY which copies an account's code to memory. The answer appears to be yes: a contract can access the code of another contract.

Solidity 0.3.1 now provides extcodecopy and other opcodes as part of its inline assembly feature:

The following example provides library code to access the code of another contract and load it into a bytes variable. This is not possible at all with “plain Solidity” and the idea is that assembly libraries will be used to enhance the language in such ways.

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)
    }
  }
}
Preview
  • 252
  • 1
  • 10
eth
  • 85,679
  • 53
  • 285
  • 406
1

Update for Solidity v0.8

You no longer have to use inline assembly to obtain the code of another contract. You can simply do it like this:

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

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

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143