Is it possible to get the bytecode of an already deployed contract
from another contract?
Example: get bytecode of contract A using contract B in Solidity.
Yes, this is possible using assembly, you can get the code of any contract. The code below do just that (from the docs
function at(address _addr) public view 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), not(0x1f))))
// store length in memory
mstore(o_code, size)
// actually retrieve the code, this needs assembly
extcodecopy(_addr, add(o_code, 0x20), 0, size)
}
}
It is now possible to read the code of another contract using both plain Solidity and assembly (Yul).
As per the docs on Members of Address Types
pragma solidity >=0.8.0;
contract GetCode {
function at(address _addr) public view returns (bytes memory o_code) {
return _addr.code;
}
}
Example taken from the docs:
pragma solidity >=0.4.16 <0.9.0;
library GetCode {
function at(address _addr) public view returns (bytes memory o_code) {
assembly {
// retrieve the size of the code
let size := extcodesize(_addr)
// allocate output byte array
// 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), not(0x1f))))
// store length in memory
mstore(o_code, size)
// actually retrieve the code, this needs assembly
extcodecopy(_addr, add(o_code, 0x20), 0, size)
}
}
}
This can also work:
> eth.getCode("CONTRACT ADDRESS")
"0x60806040526004361061..."
After getting the Byte code, remove the "0x" at the beginning and then use this Solidity decompiler, https://ethervm.io/decompile, to decompile the bytecode.