Spaces:
Running
Running
| // deploy.js β compile and deploy ListingNFT.sol to 0G testnet | |
| // | |
| // Usage: | |
| // cd contract | |
| // echo "PRIVATE_KEY=0x..." > .env | |
| // npm install | |
| // node deploy.js | |
| // | |
| // Prints the deployed address β paste into ../shared.js OG_CHAIN.listingNFT | |
| import { readFileSync, writeFileSync } from 'fs'; | |
| import { fileURLToPath } from 'url'; | |
| import { dirname, resolve } from 'path'; | |
| import { ethers } from 'ethers'; | |
| import solc from 'solc'; | |
| import 'dotenv/config'; | |
| const __dirname = dirname(fileURLToPath(import.meta.url)); | |
| const OG_RPC = 'https://evmrpc-testnet.0g.ai'; | |
| const OG_CHAIN_ID = 16602; | |
| function compile() { | |
| console.log('Compiling ListingNFT.solβ¦'); | |
| const source = readFileSync(resolve(__dirname, 'ListingNFT.sol'), 'utf8'); | |
| const input = { | |
| language: 'Solidity', | |
| sources: { 'ListingNFT.sol': { content: source } }, | |
| settings: { | |
| outputSelection: { '*': { '*': ['abi', 'evm.bytecode.object'] } }, | |
| optimizer: { enabled: true, runs: 200 }, | |
| }, | |
| }; | |
| const output = JSON.parse(solc.compile(JSON.stringify(input))); | |
| if (output.errors) { | |
| for (const err of output.errors) { | |
| if (err.severity === 'error') { | |
| console.error(err.formattedMessage); | |
| process.exit(1); | |
| } | |
| } | |
| } | |
| const contract = output.contracts['ListingNFT.sol']['ListingNFT']; | |
| const abi = contract.abi; | |
| const bytecode = contract.evm.bytecode.object; | |
| // Save artifacts for the frontend | |
| writeFileSync(resolve(__dirname, 'ListingNFT.abi.json'), JSON.stringify(abi, null, 2)); | |
| writeFileSync(resolve(__dirname, 'ListingNFT.bytecode'), bytecode); | |
| console.log('Compiled. ABI + bytecode written to contract/.'); | |
| return { abi, bytecode }; | |
| } | |
| async function deploy() { | |
| const privateKey = process.env.PRIVATE_KEY; | |
| if (!privateKey) { | |
| console.error('Missing PRIVATE_KEY in contract/.env'); | |
| console.error('Create one: echo "PRIVATE_KEY=0x..." > .env'); | |
| process.exit(1); | |
| } | |
| const { abi, bytecode } = compile(); | |
| console.log('Connecting to 0G testnetβ¦'); | |
| const provider = new ethers.JsonRpcProvider(OG_RPC); | |
| const wallet = new ethers.Wallet(privateKey, provider); | |
| const network = await provider.getNetwork(); | |
| if (Number(network.chainId) !== OG_CHAIN_ID) { | |
| console.warn(`Warning: chainId is ${network.chainId}, expected ${OG_CHAIN_ID}`); | |
| } | |
| const balance = await provider.getBalance(wallet.address); | |
| console.log(`Wallet: ${wallet.address}`); | |
| console.log(`Balance: ${ethers.formatEther(balance)} 0G`); | |
| if (balance === 0n) { | |
| console.error('Wallet has 0 balance. Get testnet tokens at https://faucet.0g.ai'); | |
| process.exit(1); | |
| } | |
| console.log('Deploying ListingNFTβ¦'); | |
| const factory = new ethers.ContractFactory(abi, '0x' + bytecode, wallet); | |
| const contract = await factory.deploy(); | |
| console.log(`Tx submitted: ${contract.deploymentTransaction().hash}`); | |
| console.log('Waiting for confirmationβ¦'); | |
| await contract.waitForDeployment(); | |
| const addr = await contract.getAddress(); | |
| console.log(''); | |
| console.log('ββββββββββββββββββββββββββββββββββββββββββββββββββ'); | |
| console.log('β Deployed!'); | |
| console.log(''); | |
| console.log(`Address: ${addr}`); | |
| console.log(`Explorer: https://chainscan-galileo.0g.ai/address/${addr}`); | |
| console.log(''); | |
| console.log('Next step:'); | |
| console.log(' Edit ../shared.js and set:'); | |
| console.log(` OG_CHAIN.listingNFT = '${addr}'`); | |
| console.log('ββββββββββββββββββββββββββββββββββββββββββββββββββ'); | |
| } | |
| deploy().catch(e => { | |
| console.error('Deploy failed:', e); | |
| process.exit(1); | |
| }); | |