# Reproducible compilation

> The solc 0.8.37 recipe, exact input hash and checks for relating sources, artifacts and deployed code.

Source: https://docs.botradix.com/reproducible-build/

A reproducible compilation checks that specific sources and settings produce the expected artifacts. It establishes correspondence; **it is not a security audit** and does not prove that an implementation is still active. That requires [reading proxy routes](https://docs.botradix.com/proxies/) at a specific block.

## Compiler and settings

The v2.2 reference recipe uses:

| Setting | Value |
|---|---|
| Solidity | `solc 0.8.37+commit.f401782d` |
| Input language | `Solidity`, Standard JSON format |
| Optimizer | `enabled: true`, `runs: 200` |
| Compilation through IR | `viaIR: true` |
| EVM target | `evmVersion: "paris"` |
| Metadata hash in bytecode | `metadata.bytecodeHash: "none"` |
| Reference input dependencies | OpenZeppelin `5.6.1`, included with their original source unit names |

This settings fragment describes the recipe. Compile with the complete input, including sources and `outputSelection`, rather than reconstructing it from the fragment:

```json
{
  "optimizer": { "enabled": true, "runs": 200 },
  "viaIR": true,
  "evmVersion": "paris",
  "metadata": { "bytecodeHash": "none" }
}
```

## Identify the exact input

The Standard JSON input collects source and dependency content under their original paths. Preserve filenames, imported source unit names, settings and versions. Do not replace dependencies with the latest release or mix sources from different releases.

**Documentation reference: 11 October 2026.** The `v22.standard-input.json` input in reference package `20261011-145007` contains 54 source units. Its SHA-256, calculated over the file bytes, is:

```text
54a204b3dd61ceb7196f84c7337927fbf5b3af5c721e6eac1319487da050ddf6
```

This hash identifies that specific input, not a final package yet to be published. Changing comments or JSON formatting changes the file hash even if bytecode remains identical. Publication must identify its own input and SHA-256 along with the bytecode comparison result.

**Publication status:** verified sources will be published jointly on BaseScan near closure. Public download of the final input and artifacts is pending; no unavailable download URL is presented here.

## Reproduce without publishing

With the exact compiler already installed and the complete input available, work in a local directory. These commands do not send transactions or publish code:

```bash
solc --version
sha256sum v22.standard-input.json
solc --standard-json < v22.standard-input.json > v22.compiler-output.json
```

Check that the version includes `0.8.37+commit.f401782d` and the hash matches the file from the release being verified. The hash above applies only to the stated reference input. An input embedding all sources does not need network import resolution.

Also check errors in the output JSON: the process exit code alone does not prove that Solidity compiled successfully.

```python
import json
from pathlib import Path

result = json.loads(Path("v22.compiler-output.json").read_text())
errors = [item for item in result.get("errors", []) if item.get("severity") == "error"]
for item in errors:
    print(item.get("formattedMessage", item.get("message", "")))
assert not errors, "Solidity compilation failed"
assert result.get("contracts"), "No contract output"
print("Compilation completed; compare artifacts next")
```

Review warnings too, and retain the compiler, input, output and hashes. This local compilation requires no wallet, private key or API key.

## Compare artifacts and deployment

Compare by **source unit name and contract name**, not just output filename. For identical sources, compare both `evm.bytecode.object` (creation) and `evm.deployedBytecode.object` (runtime), together with ABI and storage layout when evaluating an upgrade.

Compiler runtime can contain locations for `immutable` values set by the constructor at deployment. Checking an address requires resolving `immutableReferences`, constructor arguments and any linked-library references. Creation code and constructor arguments are also different things. Do not discard arbitrary differences to force a match.

`bytecodeHash: "none"` omits the metadata hash from bytecode; it does not mean that every source change is harmless or that all metadata information disappears. A comment-only change can preserve generated code, but recompilation and comparison are required to demonstrate it. Changing logic, literals or names used to compute identifiers can change the result.

Comparison with on-chain code must identify the network, address and block, and handle the host, implementations and modules separately. A proxy match does not establish the logic it delegates to. See [Security and contracts](https://docs.botradix.com/security-contracts/) for review scope and possible changes while components remain OPEN.
