Skip to main content

Transformations (JSON)

A "transformation" on bytecode is a necessary change in the bytecode string to achieve the exact (on-chain) bytecode from a base bytecode. These changes are on the non-executional parts of the bytecode and do not affect how the contract works. It includes:

  • Constructor Arguments (only creation code)
  • Immutable Variables (only runtime code)
  • Libraries
  • CBOR Auxdata
  • Call Protection (only runtime code)

The transformations in the Verifier Alliance schema are stored in the verified_contracts table under the following columns:

  • creation_transformations
  • creation_values
  • runtime_transformations
  • runtime_values

The rules to the format and content of the transformations are implemented in the contraints of the PostgreSQL Schema.

Example:

runtime_transformations:

[
{
"id": "20",
"type": "replace",
"offset": 137, // in bytes
"reason": "immutable"
},
{
"id": "0",
"type": "replace",
"offset": 1002,
"reason": "auxdata"
}
]

runtime_values:

{
"immutables": {
"20": "0x000000000000000000000000b5d83c2436ad54046d57cd48c00d619d702f3814"
},
"cborAuxdata": {
"0": "0xa26469706673582212205817b060c918294cc8107069c4fd0a74dbfc35b0617214043887fe9d4e17a4a864736f6c634300081a0033"
}
}

Transformations on Creation Bytecode

creation_transformations

This object contains the transformation that will be applied to the creation bytecode.

The creation transformation can only contain these as "reason"s and "type"s:

  • { "reason": "constructorArguments", "type": "insert", "offset": 999 }
  • { "reason": "cborAuxdata", "type": "replace", "offset": 123, id: "0" }
  • { "reason": "library", "type": "replace", "offset": 123, id: "sources/lib/MyLib.sol:MyLib" }

Example:

[
{
"id": "sources/lib/MyLib.sol:MyLib",
"type": "replace",
"offset": 582,
"reason": "library"
},
{
"id": "0",
"type": "replace",
"offset": 1269,
"reason": "cborAuxdata"
},
{
"type": "insert",
"offset": 1322,
"reason": "constructorArguments"
}
]

creation_values

This object contains the values that will be inserted/replaced in the creation bytecode.

The values can be "cborAuxdata", "library", "constructorArguments".

{
"libraries": {
"sources/lib/MyLib.sol:MyLib": "0x40b70a4904fad0ff86f8c901b231eac759a0ebb0"
},
"constructorArguments": "0x00000000000000000000000085fe79b998509b77bf10a8bd4001d58475d29386",
"cborAuxdata": {
"0": "0xa26469706673582212201c37bb166aa1bc4777a7471cda1bbba7ef75600cd859180fa30d503673b99f0264736f6c63430008190033"
}
}

Transformations on Runtime Bytecode

runtime_transformation

Similar to creation_transformation. But runtime code does not contain constructor arguments but can have immutable variables and call protection.

The runtime transformations can only contain these as "reason"s and "type"s:

  • { "reason": "cborAuxdata", "type": "replace", "offset": 123, id: "0" }
  • { "reason": "library", "type": "replace", "offset": 123, id: "contracts/order/OrderUtils.sol:OrderUtilsLib" }
  • { "reason": "immutable", "type": "replace", "offset": 999, id: "2473" }
    • Solidity contracts have "replace" type, while Vyper ones have "insert" because they are appended to the runtime bytecode.
  • { "reason": "callProtection", "type": "replace", "offset": 1 }

Example 1:

[
{
"id": "contracts/order/OrderUtils.sol:OrderUtilsLib",
"type": "replace",
"offset": 449,
"reason": "library"
},
{
"id": "2473",
"type": "replace",
"offset": 4339,
"reason": "immutable"
}
{
"id": "1",
"type": "replace",
"offset": 4682,
"reason": "cborAuxdata"
}
]

Example 2:

[
{
"type": "replace",
"offset": 1, // does not include the PUSH20 opcode 0x73 in the beginning
"reason": "callProtection"
}
]

runtime_values

Example 1:

{
"libraries": {
"contracts/order/OrderUtils.sol:OrderUtilsLib": "0x40b70a4904fad0ff86f8c901b231eac759a0ebb0"
},
"immutables": {
"2473": "0x000000000000000000000000000000007f56768de3133034fa730a909003a165"
},
"cborAuxdata": {
"1": "0xa26469706673582212201c37bb166aa1bc4777a7471cda1bbba7ef75600cd859180fa30d503673b99f0264736f6c63430008190033"
}
}

Example 2:

{
"callProtection": "0x9deba23b95205127e906108f191a26f5d520896a" // just the 20 byte address without the 0x73 PUSH20 opcode in the beginning
}