ethereum / solidity

Solidity, the Smart Contract Programming Language
https://soliditylang.org
GNU General Public License v3.0
22.67k stars 5.62k forks source link

AST import cause memory difference with metadata-hash #15091

Closed Subway2023 closed 1 month ago

Subway2023 commented 1 month ago

Description

When I compile a specific Solidity program and execute it using --import-ast, there is a situation of inconsistent memory. However, if I add --metadata-hash none, this issue does not occur.

Why does metadata-hash affect memory? I understand that metadata-hash can affect the length of the generated bytecode 14986

Environment

Steps to Reproduce

contract D {
  function test0() external pure {}
}

contract C {
  function test0() external pure {}
  function test1() external returns(bytes memory){
      function() external x=(new D()).test0;
      bytes memory a = abi.encodeCall(this.test0, ());
      bytes memory b = abi.encodeCall(this.test0, ());
      return b;

  }
}

1. Compile from external AST

solc C.sol --combined-json ast >> C.json

solc  --bin-runtime --import-ast C.json
608060405234801561000f575f80fd5b5060043610610034575f3560e01c80636b59084d1461003857806377ff24f414610056575b5f80fd5b610040610060565b60405161004d91906101ff565b60405180910390f35b61005e610181565b005b60605f8060405161007090610183565b604051809103905ff080158015610089573d5f803e3d5ffd5b5073ffffffffffffffffffffffffffffffffffffffff166377ff24f4915091505f3073ffffffffffffffffffffffffffffffffffffffff166377ff24f4604051602401604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090505f3073ffffffffffffffffffffffffffffffffffffffff166377ff24f4604051602401604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090508094505050505090565b565b60848061022083390190565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6101d18261018f565b6101db8185610199565b93506101eb8185602086016101a9565b6101f4816101b7565b840191505092915050565b5f6020820190508181035f83015261021781846101c7565b90509291505056fe6080604052348015600e575f80fd5b50606a80601a5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806377ff24f414602a575b5f80fd5b60306032565b005b56fea26469706673582212204b8c026b1795a1c7c31033b9444c28b6196210edbbfc81e3ed4b40636d3fb34764736f6c63430008190033a264697066735822122065925bf38bb1e1dba92583de7df6ef487adf74d09ebe20a8452fdad0cf1601ec64736f6c63430008190033

2. Compile from external AST without metadata-hash

solc C.sol --combined-json ast >> C.json

solc  --bin-runtime --import-ast C.json --metadata-hash none
608060405234801561000f575f80fd5b5060043610610034575f3560e01c80636b59084d1461003857806377ff24f414610056575b5f80fd5b610040610060565b60405161004d91906101ff565b60405180910390f35b61005e610181565b005b60605f8060405161007090610183565b604051809103905ff080158015610089573d5f803e3d5ffd5b5073ffffffffffffffffffffffffffffffffffffffff166377ff24f4915091505f3073ffffffffffffffffffffffffffffffffffffffff166377ff24f4604051602401604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090505f3073ffffffffffffffffffffffffffffffffffffffff166377ff24f4604051602401604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090508094505050505090565b565b605b8061022083390190565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6101d18261018f565b6101db8185610199565b93506101eb8185602086016101a9565b6101f4816101b7565b840191505092915050565b5f6020820190508181035f83015261021781846101c7565b90509291505056fe6080604052348015600e575f80fd5b50604180601a5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806377ff24f414602a575b5f80fd5b60306032565b005b56fea164736f6c6343000819000aa164736f6c6343000819000a

3. Compile normaly

solc  --bin-runtime C.sol 
608060405234801561000f575f80fd5b5060043610610034575f3560e01c80636b59084d1461003857806377ff24f414610056575b5f80fd5b610040610060565b60405161004d91906101ff565b60405180910390f35b61005e610181565b005b60605f8060405161007090610183565b604051809103905ff080158015610089573d5f803e3d5ffd5b5073ffffffffffffffffffffffffffffffffffffffff166377ff24f4915091505f3073ffffffffffffffffffffffffffffffffffffffff166377ff24f4604051602401604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090505f3073ffffffffffffffffffffffffffffffffffffffff166377ff24f4604051602401604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090508094505050505090565b565b605b8061022083390190565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6101d18261018f565b6101db8185610199565b93506101eb8185602086016101a9565b6101f4816101b7565b840191505092915050565b5f6020820190508181035f83015261021781846101c7565b90509291505056fe6080604052348015600e575f80fd5b50604180601a5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806377ff24f414602a575b5f80fd5b60306032565b005b56fea164736f6c6343000819000aa164736f6c6343000819000a

The bytecode is the same as in 2.

4. Run in EVM

go-ethereum-1.13.11/build/bin/evm --debug --json --code **codeFrom123**   --input 6b59084d run

6b59084d: the selector of function test1

5. Memory result

Compile from external AST

{'268': '0', '64': '200', '128': '4', '160': '54276030033224116852338043474313948546607513718074119495684600770185440275031', '164': '4', '196': '54276030029323798630533712249253614462956987828921745670694911468889239130163', '200': '32', '232': '4'}"

Compile normally

{'200': '32', '232': '4', '268': '0', '64': '200', '128': '4', '160': '54276030033224116852338043474313948546607513718074119495684600770185440275031', '164': '4', '196': '54276030029323798630533712247792335747986101110151806616214131656497861492736'}"

Memory data in 196 are different.

cameel commented 1 month ago

3. Compile normaly

solc  --bin-runtime C.sol 

The output here does not match what I'm seeing on my machine. It's not the same as case 2 (that would definitely be a weird bug). It's still different than case 1, but has the same size. This indicates that just metadata hash differs. Indeed, without metadata hash both generate the same runtime bytecode. So this is essentially the same problem as already covered by #14986.

And yeah, the hash can affect the state of memory. Your contract C is deploying a copy of D, which means it has to copy it to memory. Since that copy of D has metadata hash embedded in it, you'll definitely see some differences if you dump memory.