# Tizmo artwork registry

This contract stores a submission record. It is not ERC20, ERC721, or a collectible. There is no balance, mint, transfer, owner, admin, fee collector, proxy, withdrawal function, or payable entry point. Existing records cannot be edited or deleted. The contract makes no external calls.

## What gets recorded

`register(bytes32 fileHash, bytes32 recipeHash, bytes32 previousId, string metadataURI)` records the supplied SHA256 file digest, SHA256 recipe digest, submitting wallet, block timestamp, optional previous version, and optional metadata URI. The file itself stays outside the contract. The contract trusts the supplied digests; it does not receive or hash the artwork file.

The browser freezes the actual PNG bytes and canonical recipe before asking for a wallet transaction. `fileHash` must refer to those exact PNG bytes. Verification requires the same original file, since recompression or editing changes its digest. A record shows that a wallet submitted a hash at a time. It does not establish original authorship, exclusive ownership, copyright, or that other wallets have not registered the same file.

The same wallet cannot record the same file twice. Another wallet may record that file under its own account. A previous version must already exist and have the same registrant. Both hashes must be nonzero. Metadata is limited to 512 UTF8 bytes. Store public metadata references only; blockchain records are public.

The record ID is `keccak256(abi.encode(registrant, fileHash, block.chainid, address(this)))`. Read a record with `getRecord(id)` or find its ID with `recordFor(registrant, fileHash)`. `WorkRegistered` contains the full submission data. The SHA256 hashes are file digests; the record ID uses keccak256 for domain separation by chain and contract.

## Current deployment state

TizmoRegistry is deployed on Robinhood Chain Mainnet, chain ID4663, at [0x91a295a9feDb25619E2A6A559908d06d368498b6](https://robinhoodchain.blockscout.com/address/0x91a295a9feDb25619E2A6A559908d06d368498b6), in block 93679330. Deployment transaction: [0xde577f4468f2d8034ad3b4f33764fab7480eda54c9ce68056819444146118213](https://robinhoodchain.blockscout.com/tx/0xde577f4468f2d8034ad3b4f33764fab7480eda54c9ce68056819444146118213). The receipt, creation data, sender, chain and exact runtime code were verified. The verified deployment metadata is in `deployment.json` and the active site configuration is `dist/registry-config.json`.

The studio enables Record this work only after a fresh network and bytecode check. Editing and downloads work without a wallet. The public registry detail page does not deploy another contract.

Robinhood Chain uses ETH for fees. The official network configuration and deployment instructions are at [Connecting](https://docs.robinhood.com/chain/connecting/) and [Deploy a Contract](https://docs.robinhood.com/chain/deploy-smart-contracts/). The website uses the keyless BlockVectra public read RPC, documented at [BlockVectra Robinhood Chain](https://docs.blockvectra.com/en/guides/robinhood-chain/). Its chain ID and exact registry runtime were checked against the official RPC. The public service is limited to 3 requests per second per IP. Wallet signing stays in the visitor wallet. Use a suitable production RPC plan before relying on sustained public traffic.

## Use the live registry

1. Open the studio and create a work.
2. Open Keep a record of this work, then select Record this work.
3. Connect an Ethereum compatible wallet on Robinhood Chain Mainnet. The wallet needs a small amount of ETH for network fees.
4. Review the transaction in your wallet. It sends zero ETH to the registry and records the exact exported file and recipe fingerprints.
5. After a verified receipt, the studio saves the confirmed record with the local work. Save the original PNG and recipe to keep the exact bytes used for the fingerprints.

Keep wallet secrets outside the project, hosted files, source archive and browser forms. The existing deployer is not used for visitor registrations. Visitors sign their own submissions.

## Reproduce the build and local tests

Requires Node 20 or later and pnpm. Dependencies are pinned in `package.json` and `pnpm-lock.yaml`.

```sh
cd contracts
pnpm install --frozen-lockfile
pnpm build
pnpm test
```

The compiler is Solidity `0.8.30+commit.73712a01`. Optimizer enabled, 200 runs, EVM version `paris`, MIT license, no constructor arguments. `build.mjs` generates `artifact.json`, `standard-input.json`, the downloadable source and artifact, and the local browser bundles. Ethers is bundled into the site; there is no runtime CDN dependency.

Tests run against an ephemeral local Ganache EVM only. They cover record writes, emitted events, deterministic IDs, timestamp, versions, duplicate rejection, zero digests, UTF8 metadata limits, lookup failures, no ETH accepted, a token free ABI, bytecode verification, exact SHA256 bytes, readiness, network mismatch, unrelated contract refusal, real browser client writes, wallet rejection, and account changes. Local tests do not broadcast to Robinhood Chain.

## Optional deployment from a local CLI

The live site already uses the registry above. Deploy another instance only deliberately. An experienced operator may supply their own `TIZMO_DEPLOY_PRIVATE_KEY` through a local secret manager and `RH_RPC_URL` through their environment. Never commit either private keys or a credentialed RPC URL. Set `TIZMO_DEPLOY_CHAIN_ID=4663` for mainnet or `46630` for testnet.

```sh
node deploy.mjs
```

The command above only previews the selected wallet, network, prediction, and fee estimate. Only the operator's explicit `node deploy.mjs --broadcast` sends the deployment. A successful verified result is written to ignored `deployment.local.json`; the script does not publish or activate the site's config. `node deploy.mjs --check-address 0x...` verifies an existing address against the exact runtime and needs no private key.

## Verify source in the explorer

Use the explorer's Solidity standard JSON verification flow. Upload `standard-input.json`, choose compiler `v0.8.30+commit.73712a01`, contract `TizmoRegistry.sol:TizmoRegistry`, no constructor arguments, MIT license. The standard input fixes optimizer 200 and EVM `paris`. Compare the explorer address and chain with the downloaded deployment config. The browser additionally compares `eth_getCode` with `artifact.deployedBytecode` before allowing writes.

## Browser API

`window.TizmoRegistry` exposes:

* `sha256(Blob | Uint8Array | ArrayBuffer | string)` returns a SHA256 `0x` digest.
* `getConfig()` reads the same origin configuration. No query parameter can replace it.
* `status()` returns `{ ready, reason, chainId, chainName, address }` without asking for accounts.
* `register({ fileHash, recipeHash, previousId?, metadataURI?, onSubmitted? })` is the only method that requests accounts. Call it only from the user's explicit Record button. It checks the selected chain, exact runtime, account stability, duplicate record, transaction receipt, and matching event. It sends zero ETH, then polls for at most three minutes.
* `lookup(recordId)` performs read only contract calls through the configured RPC or wallet and returns the actual record.

`register` resolves with the record fields, transaction hash, explorer URL, chain, contract address, block number, and timestamp. An `onSubmitted` callback receives transaction info as soon as the wallet broadcasts. A pending or receipt check error retains `transactionHash`, `recordId`, and `explorerUrl`; check that transaction before trying again. A transaction included in one block can still be affected by a chain reorganization. The registry is an initial application implementation and has not received an independent security audit.

## Technical references

[Solidity contracts](https://docs.soliditylang.org/en/v0.8.30/contracts.html), [Ethereum JSON RPC](https://ethereum.org/developers/docs/apis/json-rpc/), [Ethers provider documentation](https://docs.ethers.org/v6/api/providers/).
