Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save andreafspeziale/557fa432e9929ccf049459972e322bdf to your computer and use it in GitHub Desktop.
Save andreafspeziale/557fa432e9929ccf049459972e322bdf to your computer and use it in GitHub Desktop.
# Get Smart Contract instance bytecode and hashed bytecode

Get Smart Contract instance bytecode and hashed bytecode

Minimal SC sample exposing a way to get the bytecode and the hashed bytecode of a deployed smart contract.
This without the new OPCODE of EIP1052

pragma solidity ^0.4.24;

contract SomeContractInstance {
    constructor () public {}
}

library GetCode {
    function atReturningHash(address _addr) public view returns (bytes32 hash) {
        bytes memory 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)
        }
        hash = keccak256(o_code);
    }
    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)
        }
    }
}

contract Checker {
    constructor () public {}
    
    function getCodeHashed(address _contractAddress) public view returns (bytes32) {
        return GetCode.atReturningHash(_contractAddress);
    }
    
    function getCode(address _contractAddress) public view returns (bytes) {
        return GetCode.at(_contractAddress);
    }
}

As soon as you try to perform a compilation, e.g with Truffle, of the SomeContractInstance SC you will have at your disposal in the build folder the deployedBytecode key with the following value:

const truffleBytecode = "0x6080604052600080fd00a165627a7a7230582036e3d8f01ac39ad1d768c6a9262d6deb6b92c810dd909bea9b68716f3ded6ca50029"

This value will be the same value you can get by actually deploying SomeContractInstance and making a transactionCall to the Checker getCode method passing the SomeContractInstance address.

Passing instead the SomeContractInstance address to the Checker getCodeHashed method you will retrieve the hash of the SomeContractInstance bytecode.
The hashed value would be: 0x7fa374a961dedb32a7f0411a09663ed9887240911c24d700b63e0cb6f0003854.

const ethereumUtil = require('ethereumjs-util')

const bytecodeFromTransactionCall = "0x6080604052600080fd00a165627a7a7230582036e3d8f01ac39ad1d768c6a9262d6deb6b92c810dd909bea9b68716f3ded6ca50029"
const bufferedBytecode = ethereumUtil.toBuffer(bytecodeFromTransactionCall)

const hashedBytecode = ethereumUtil.keccak256(bufferedBytecode)
// <Buffer 7f a3 74 a9 61 de db 32 a7 f0 41 1a 09 66 3e d9 88 72 40 91 1c 24 d7 00 b6 3e 0c b6 f0 00 38 54>

ethereumUtil.addHexPrefix(hashedBytecode.toString('hex'))
// '0x7fa374a961dedb32a7f0411a09663ed9887240911c24d700b63e0cb6f0003854'

What I'm trying to highlight is that it could be useful understand / filter smart contracts interactions based on their instance.

@rjcryptocoin
Copy link

EIP1052

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment