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.
Asked
Active
Viewed 1,738 times
10
eth
- 85,679
- 53
- 285
- 406
2 Answers
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)
}
}
}
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