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:
- from the transformations list read the offset of the auxdata transformation
- from the transformationValues object read the length of the onchain auxdata
- 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
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:
auxdata.offsettoauxdata.offset + transformationValues.auxdata.lengththetransformationValues.auxdataobtaining the onchain bytecodeThe same process cannot be followed if there is a discrepancy between the auxdata length. This happens when
appendCborormetadataHashvalues 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
replacedoesn'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 thedeletetype 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.
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_offsetvalue.E.g. These are the first bytes of the creation bytecode of the same contract with a different
bytecodehashsetting, notice how the final bytes are different because of the different runtime bytecode's position in the creation bytecodeRight now these contracts are not supported on Sourcify