# Deployment records

Every deploy writes a JSON file to `deployments/<chainId>-<network>/<deploymentName>.json`. This folder is the product — committed to git, readable by humans and any tool.

## Layout

```text
deployments/
├─ 11155111-sepolia/
│  ├─ Token.json
│  └─ Vault.json
├─ 8453-base/
│  └─ Token.json
└─ sources/
   └─ 0x8f3a….json        ← pinned verification input, shared by every record that used it
```

The folder key is `chainId` plus a slugged chain name (e.g. viem's "Arbitrum One" → `42161-arbitrum-one`). This prevents name collisions across chains.

## Record shape

```jsonc
{
  "schemaVersion": 2,
  "contractName": "Token",
  "deploymentName": "Token",
  "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
  "chainId": 11155111,
  "networkName": "11155111-sepolia",
  "abi": [/* full ABI */],
  "bytecode": "0x60806040...",
  "constructorArgs": ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"],
  "transactionHash": "0x2c9a...d4e1",
  "deployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
  "deployedAt": 1719849600000,
  "compiler": {
    "version": "0.8.24+commit.e11b9ed9",
    "settings": { "optimizer": { "enabled": true, "runs": 200 } },
  },
  "codeHash": "0x…", // keccak of the metadata-stripped runtime bytecode
  "identityHash": "0x…", // keccak(stripped runtime ++ args ++ libraries)
  "sourcesHash": "0x…", // → deployments/sources/<hash>.json, the pinned verification input
  "history": [/* see below */],
  "kind": "standard",
}
```

* `bigint` constructor args are stored as **strings** — plain, greppable JSON
* `codeHash` is a 32-byte digest, not a second copy of the bytecode: enough to check that the code at an address is still the code you recorded, without keeping ~24KB of hex per chain in git. It is absent for a contract whose runtime bytecode still carries unlinked library placeholders, and it will not equal `keccak(eth_getCode(...))` for a contract with `immutable` variables, whose on-chain code has the values filled in. To reproduce the exact runtime bytecode, recompile the [pinned sources](#pinned-verification-sources)
* `kind: "external"` for contracts recorded via `register` (not deployed by you)
* `schemaVersion: 2` — v1 records still read; they upgrade in place on the next deploy

## History

Every real (re)deploy appends to `history` (newest last), so the record — and its git diff — shows *why* each deployment happened. `identityHash` is the [deploy identity](/concepts/idempotency); `supersededAddress` links a redeploy to the address it replaced.

```jsonc
"history": [
  {
    "at": 1719849600000,
    "address": "0x5FbD…0aa3",
    "transactionHash": "0x2c9a…d4e1",
    "deployer": "0xf39F…2266",
    "identityHash": "0x…",
    "reason": { "kind": "fresh" },
    "summary": "first deployment",
  },
  {
    "at": 1719936000000,
    "address": "0xA1b2…C3d4",
    "transactionHash": "0x77aa…12ff",
    "deployer": "0xf39F…2266",
    "identityHash": "0x…",
    "reason": { "kind": "changed", "changes": [{ "field": "args", "from": ["0x…AAAA"], "to": ["0x…BBBB"], "changedIndices": [0] }] },
    "summary": "constructor args changed from [0x…AAAA] to [0x…BBBB] (arg 1 `owner`)",
    "supersededAddress": "0x5FbD…0aa3",
  },
]
```

## Pinned verification sources

Each deploy pins the exact solc standard-json input it used (sources, settings, compiler version, fully-qualified name) to `deployments/sources/<hash>.json`, and the record points at it with `sourcesHash`. That is everything a block explorer needs, kept independent of the current source tree.

The file is named after a hash of its own contents, so one compilation input is stored **once** no matter how many chains or contracts reference it. A standard-json input is the whole compilation unit, so a per-record copy would mean a copy of your entire source tree per chain. Commit it with the records; see [version control](/concepts/version-control).

## Portability

Records are vanilla JSON with no superjson or proprietary encoding. A Python, Go, or Rust service reads them the same way TypeScript does. Your app does not need deployoor at runtime.

## Filesystem guarantees

* **Atomic writes** — records are written atomically under a coarse lock
* **Chain ID guard** — reusing a record on the wrong chain fails with a clear error
