Skip to content

Latest commit

 

History

History
204 lines (164 loc) · 11 KB

README.md

File metadata and controls

204 lines (164 loc) · 11 KB

Deployments

manifest.json is the single machine-readable record of every Wraith deployment on EVM, Stellar, Solana and CKB. Read contract addresses, start heights, artifact hashes and ABIs from it rather than from other files or docs.

deployments/
  schema/v1.json             JSON Schema (draft 2020-12) for the manifest and records
  manifest.json              generated: every record, sorted by chain then network
  evm/horizen-testnet.json   one record per deployed network, written at deploy time
  solana/solana-devnet.json
  ckb/ckb-testnet.json
  stellar/                   written by stellar/deploy.sh on first deployment

Do not edit manifest.json by hand. It is built from the records, and CI fails if the two disagree.

Schema (version 1)

{
  "schemaVersion": 1,
  "deployments": [
    {
      "chain": "evm", // evm | stellar | solana | ckb
      "network": "horizen-testnet", // slug; also the record's file name
      "networkId": "2651420", // see "Network identity" below
      "rpcUrl": "https://…", // public endpoint used by `verify`
      "recordedBy": "chain-query", // deploy-script | chain-query
      "contracts": [
        {
          "name": "ERC5564Announcer", // contract, crate or Anchor program name
          "id": "0x8AE6…", // address / contract ID / program ID / code hash
          "version": "0.1.0", // package or crate version, null if unknown
          "sourceCommit": "…", // full 40-hex git commit; null only when unverifiable
          "provenance": { "status": "source-verified" }, // or { "status": "unverifiable", "reason": "…" }
          "artifactHash": { "algorithm": "keccak256", "value": "0x…" },
          "abi": { "path": "evm/subgraph/abis/ERC5564Announcer.json", "sha256": "0x…" },
          "deployment": {
            "height": 14202900,
            "txHash": "0x…",
            "deployer": "0x…",
            "timestamp": "…Z",
          },
        },
      ],
    },
  ],
}

A change that breaks existing readers bumps schemaVersion and adds schema/v2.json. Adding an optional field does not.

Per-chain meaning

Chain networkId id deployment.height artifactHash
EVM decimal chain ID contract address block of the creation tx keccak256 of runtime bytecode (EXTCODEHASH)
Stellar network passphrase contract ID (C…) ledger that created the instance sha256 of the wasm (the on-chain wasm hash)
Solana genesis hash program ID slot of the last (re)deploy sha256 of the program ELF without zero padding (solana-verify get-program-hash)
CKB genesis block hash script code hash block of the cell dep tx CKB blake2b-256 of the cell data

Every value can be checked against the chain: npm run verify (below) does exactly that. Chain-specific extras: EVM contracts carry abi (hash over the canonical ABI, so formatting does not matter). Solana programs carry solana.programData and solana.upgradeAuthority. CKB scripts carry ckb.hashType and ckb.cellDep, and external: true marks third-party scripts Wraith depends on (ckb-auth).

Every supported contract needs an explicit record

For EVM, a network's record must account for every contract the repository supports (ERC5564Announcer, ERC6538Registry, WraithSender, WraithNames, WraithWithdrawer; the list is EXPECTED_CONTRACTS in catalogue.ts). Each one is either:

  • in contracts, with its deployment transaction (deployment.txHash), block (deployment.height), artifactHash and abi (path and canonical hash), or
  • in undeployed, with a reason:
"undeployed": [
  { "name": "WraithSender", "reason": "Not deployed on horizen-testnet yet." }
]

A name in both lists, a name that is not a supported contract, or a supported contract in neither list fails npm run check, npm run build and npm run verify. Recording a contract removes it from undeployed.

recordedBy: "chain-query" means the record was reconstructed from chain state after the fact.

Source provenance

Every first-party contract carries provenance:

  • source-verified: sourceCommit is a full 40-hex commit and building it reproduces artifactHash. npm run verify-source rebuilds and checks this (EVM via Hardhat, Stellar via the stellar/deploy.sh build; contracts with Solidity immutables are compared against the deployed code everywhere except the immutable slots).
  • unverifiable: a historical record. sourceCommit is null and reason says why. The current EVM, Solana and CKB records are of this kind, because they predate the manifest and no build has been shown to reproduce them. Solana and CKB have no reproducible build yet, so they cannot be source-verified.

Records written by a deploy script must be source-verified: record rejects a missing or malformed --source-commit (only HEAD or a full hash), a working tree with uncommitted changes, and a commit whose build does not reproduce the artifact hash. Re-recording unchanged bytecode keeps its existing provenance; changed bytecode resets it to unverifiable unless a commit is supplied.

To upgrade a historical record, prove the commit offline:

npm run attest -- evm --network horizen-testnet --contract ERC5564Announcer --search
npm run attest -- evm --network horizen-testnet --contract ERC5564Announcer --commit <full sha>

A record is only changed when a build reproduces the recorded hash.

Consumers

npm run check fails if any of these disagree with the manifest:

File Checked Generated by build
evm/subgraph/subgraph.template.yaml each source.abi is an EVM contract; no network, address or startBlock no
evm/subgraph/<network>/instant-config.json address, chain, startBlock yes
evm/subgraph/abis/*.json, evm/subgraph/<network>/abis/*.json canonical ABI hash no
evm/hardhat.config.ts chainId of the matching network no
solana/Anchor.toml, solana/programs/*/src/lib.rs [programs.<cluster>] and declare_id! no
ckb/<network>.toml code hashes and cell deps no
stellar/contract-ids.json IDs from stellar-testnet (used by the TS bindings) yes
README.md (between deployments:begin/end) deployed addresses tables yes

Recording a deployment

The tool lives in scripts/deployment-manifest:

cd scripts/deployment-manifest
npm ci
  • EVM: evm/scripts/deploy.ts records automatically on any non-local network, using each contract's deployment receipt. Then regenerate the subgraph manifest from the record (see Subgraph manifest).
  • Stellar: stellar/deploy.sh records automatically, before init.
  • Solana, CKB, or anything deployed by hand: record from the chain.
npm run record -- solana --network solana-devnet --rpc https://api.devnet.solana.com \
  --public-rpc https://api.devnet.solana.com \
  --program wraith_announcer=<program id> \
  --recorded-by deploy-script --source-commit HEAD --version 0.1.0

npm run record -- ckb --network ckb-testnet --rpc https://testnet.ckbapp.dev \
  --public-rpc https://testnet.ckbapp.dev \
  --script wraith-stealth-lock=<cell dep tx hash>:0:data2

npm run record -- evm --network horizen-testnet --rpc <rpc> \
  --contract WraithSender=<address>@<deploy tx hash>

# a supported contract that is not deployed on this network
npm run record -- evm --network horizen-testnet --rpc <rpc> \
  --undeployed WraithNames="Not deployed on horizen-testnet yet."

record reads heights and artifact hashes from the chain, merges into the existing record for that network, and runs build. --rpc is only used for queries, so it may contain an API key; only --public-rpc is written to the record. Commit the record, manifest.json and every file build regenerated.

Subgraph manifest

evm/subgraph/subgraph.yaml is not checked in. It is generated for one network from evm/subgraph/subgraph.template.yaml and deployments/evm/<network>.json:

npm run subgraph -- --network horizen-testnet

Each data source gets network, source.address and source.startBlock from the contract its source.abi names. If any contract is not recorded, has no start block (or start block 0), or has the placeholder address 0x…dead, nothing is written and every such contract is listed. npm run subgraph -- --check fails unless the existing subgraph.yaml is exactly what --network would write now for the network it names; npm run deploy and npm run deploy-local in evm/subgraph run it before graph deploy.

Commands

Command What it does
npm run build Validate records, write manifest.json, regenerate the generated consumers.
npm run check Offline validation of records, manifest and consumers. Runs in CI.
npm run verify-source Rebuild each source-verified contract from its commit and compare artifact hashes.
npm run attest Backfill: mark a historical record source-verified once a commit reproduces it.
npm run verify Re-read every deployment from its chain and compare IDs, heights and hashes. Runs weekly in CI.
npm run subgraph Write evm/subgraph/subgraph.yaml for --network <slug>; --check verifies it.
npm test Unit and end-to-end tests for the tool.