Skip to content

Verifying a contract compiled with appendCbor or metadataHash set to none #39

Description

@marcocastignoli

When there is a discrepancy between the deployed bytecode and the compiled bytecode regarding the appendCbor or metadataHash compiler options, the verification process actually produce Transformations that are not complete.

Normally if a contract is verified with similar source code but that produces the same bytecode a transformation is produced in which the offset and the original auxdata are stored. This transformation can be applied to the compiled bytecode to yield the onchain bytecode following this steps:

  1. from the transformations list read the offset of the auxdata transformation
  2. from the transformationValues object read the length of the onchain auxdata
  3. replace in the compiled bytecode the bytes starting from auxdata.offset to auxdata.offset + transformationValues.auxdata.length the transformationValues.auxdata obtaining the onchain bytecode

The same process cannot be followed if there is a discrepancy between the auxdata length. This happens when appendCbor or metadataHash values are different between the deployed and the compiled contract. You can read more information here argotorg/sourcify/issues/2602.

If the onchain bytecode has an auxdata, while the compiled bytecode has no auxdata the transformation usually of type replace doesn't make any sense, since we don't want to replace any value to match a non existent onchain auxdata. In this case we propose to add the delete type in the cborAuxdata transformation, storing in the transformation also the length (together with the existing offset) of the string that needs to be removed from the compiled bytecode to obtain the onchain bytecode.


Creation bytecode limitation

Creation matches are not supported with the fix proposed above because in the creation bytecode exists a byte defining the length of the runtime bytecode after the creation section. If the bytecode length changes (bytecodeHash = none or appendCbor = none) then also that byte changes, and so a match is not possible. We could potentially support it in the future with an new transformation type.

6080604052348015600f57600080fd5b5061 0127 (h0127=590 digits; length of the runtime bytecode) 8061001f6000396000f3fe (runtime bytecode starts (length 590) -> ) 608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100a1565b60405180910390f35b610073600480360381019061006e91906100ed565b61007e565b005b60008054905090565b8060008190555050565b6000819050919050565b61009b81610088565b82525050565b60006020820190506100b66000830184610092565b92915050565b600080fd5b6100ca81610088565b81146100d557600080fd5b50565b6000813590506100e7816100c1565b92915050565b600060208284031215610103576101026100bc565b5b6000610111848285016100d8565b9150509291505056fea164736f6c634300081c000a

Multiple auxdata limitation

There is also a niche case regarding contracts with multiple auxdata. If the auxdatas length is different, the position of each auxdata is different between onchain and compiled bytecode. The problem is that the position of the runtime bytecode in the creation bytecode is marked at the beginning of the creation bytecode. So different appendCbor or metadataHash options cause the executional part of creation bytecode to have a different runtime_offset value.

E.g. These are the first bytes of the creation bytecode of the same contract with a different bytecodehash setting, notice how the final bytes are different because of the different runtime bytecode's position in the creation bytecode

60a06040523060805234801561001457600080fd5b50608051612e  3e  6100d8 // 1.bytecodehash none
60a06040523060805234801561001457600080fd5b50608051612e  67  6100d8 // 2.bytecodehash ipfs

Right now these contracts are not supported on Sourcify

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions