* Deploy the storage, the redeem extension and the renderer, and wire them. * npx hardhat run scripts/deploy.js --network sepolia * npx hardhat run scripts/deploy.js --network mainnet * CREATOR creator contract (defaults: mainnet -> CLGSM, otherwise the * one recorded by scripts/deploy-creator.js) * STORAGE reuse an existing ColorgasmStorage instead of deploying one * FIRST_ID=1 first tokenId of the original edition * EDITION=100 number of pieces * PRE_ENCODED=1 renderer expects the BASE64 of the image rather than the image * itself. The default is RAW. This is IMMUTABLE on the renderer * and must match how scripts/upload.js stores the bytes — the * upload and point scripts check it and refuse on a mismatch. * UTF8_JSON=0 serve `data:application/json;base64,` instead of UTF-8. * UTF-8 is the default and is dramatically cheaper to render. * Addresses land in deployments/<network>.json, where every other script picks * them up. Registering the extension on the creator is a separate step — * scripts/register-extension.js. import { addressFor, connect, main, saveDeployment } from "./_lib.js"; const { ethers, net, signer } = await connect(); const creator = addressFor("creator", net); const firstId = Number(process.env.FIRST_ID ?? 1); const edition = Number(process.env.EDITION ?? 100); const preEncoded = process.env.PRE_ENCODED === "1"; const utf8Json = process.env.UTF8_JSON !== "0"; const code = await ethers.provider.getCode(creator); if (code === "0x") throw new Error(`no contract at CREATOR ${creator} on ${net}`); `edition #${firstId}..#${firstId + edition - 1}\n` + `artwork stored ${preEncoded ? "pre-encoded (base64)" : "raw"}, ` + `served as ${utf8Json ? "UTF-8" : "base64"} JSON\n`, // --- storage --------------------------------------------------------- let storage = process.env.STORAGE ?? addressFor("storage", net, { required: false }); if (storage && (await ethers.provider.getCode(storage)) !== "0x") { console.log(`storage ${storage} (reused)`); const blobs = await ethers.deployContract("ColorgasmStorage"); await blobs.waitForDeployment(); storage = await blobs.getAddress(); console.log(`storage ${storage} (tx ${blobs.deploymentTransaction().hash})`); // --- extension ------------------------------------------------------- const ext = await ethers.deployContract("ColorgasmRedeemExtension", [ await ext.waitForDeployment(); console.log(`extension ${await ext.getAddress()} (tx ${ext.deploymentTransaction().hash})`); // --- renderer -------------------------------------------------------- const renderer = await ethers.deployContract("ColorgasmRendererV3", [ await renderer.waitForDeployment(); console.log(`renderer ${await renderer.getAddress()} (tx ${renderer.deploymentTransaction().hash})`); // --- wiring ---------------------------------------------------------- let tx = await ext.setBlobStorage(storage); console.log(`setBlobStorage tx ${tx.hash}`); tx = await ext.setRenderer(await renderer.getAddress()); console.log(`setRenderer tx ${tx.hash}`); tx = await renderer.setBase64Json(false); console.log(`setBase64Json(false) tx ${tx.hash}`); // Sanity: the creator core only delegates tokenURI to extensions that report // ICreatorExtensionTokenURI over ERC165. const iface = ethers.id("tokenURI(address,uint256)").slice(0, 10); if (!(await ext.supportsInterface(iface))) { throw new Error("extension does not report ICreatorExtensionTokenURI"); chainId: Number((await ethers.provider.getNetwork()).chainId), extension: await ext.getAddress(), renderer: await renderer.getAddress(), deployer: signer.address, deployedAtBlock: await ethers.provider.getBlockNumber(), ` 1. verify the source on Etherscan (give it a minute to index first)\n` + ` npx hardhat run scripts/verify.js --network ${net}\n` + ` 2. register the extension, from the creator's admin wallet\n` + ` npx hardhat run scripts/register-extension.js --network ${net}`,