Este guia mostra deploy na BrightCity Chain Testnet com Hardhat , usando o contrato de exemplo HelloWorld (não é ERC-20).
A rede está no fork Berlin . Compile com evmVersion: "berlin" para evitar opcodes de forks posteriores (por exemplo PUSH0 do Shanghai), que causam Invalid opcode: 0x5f na execução.
Pré-requisitos
Node.js 20+
Carteira deployer com saldo nativo ETH na testnet
RPC: https://rpc.fmartns.dev
Chain ID: 20260520
Use uma chave de deployer dedicada . Nunca use chave de validador QBFT como deployer.
Contrato de exemplo
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28 ;
contract HelloWorld {
string private message;
event MessageChanged ( string oldMessage , string newMessage );
constructor ( string memory initialMessage ) {
message = initialMessage;
}
function hello () external view returns ( string memory ) {
return message;
}
function setMessage ( string memory newMessage ) external {
string memory oldMessage = message;
message = newMessage;
emit MessageChanged (oldMessage, newMessage);
}
}
Salve em contracts/HelloWorld.sol.
Configuração do projeto
Instalar dependências
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox dotenv
npx hardhat init
Variáveis de ambiente
Crie .env a partir do exemplo abaixo. Não commite .env com chave real.
hardhat.config.ts
Defina rede, chain ID, evmVersion: "berlin" e conta deployer.
# .env.example
BRIGHTCITY_RPC_URL = https://rpc.fmartns.dev
BRIGHTCITY_CHAIN_ID = 20260520
DEPLOYER_PRIVATE_KEY = 0xSUA_CHAVE_PRIVADA_DE_DEPLOYER
import { HardhatUserConfig } from 'hardhat/config' ;
import '@nomicfoundation/hardhat-toolbox' ;
import * as dotenv from 'dotenv' ;
dotenv . config ();
const config : HardhatUserConfig = {
solidity: {
version: '0.8.28' ,
settings: {
evmVersion: 'berlin' ,
},
},
networks: {
brightcityTestnet: {
url: process . env . BRIGHTCITY_RPC_URL ?? 'https://rpc.fmartns.dev' ,
chainId: Number ( process . env . BRIGHTCITY_CHAIN_ID ?? 20260520 ),
accounts: process . env . DEPLOYER_PRIVATE_KEY
? [ process . env . DEPLOYER_PRIVATE_KEY ]
: [],
},
},
};
export default config ;
Script de deploy
Crie scripts/deploy-hello-world.ts:
import { ethers } from 'hardhat' ;
async function main () {
const HelloWorld = await ethers . getContractFactory ( 'HelloWorld' );
const contract = await HelloWorld . deploy ( 'Olá, BrightCity Chain Testnet' );
await contract . waitForDeployment ();
const address = await contract . getAddress ();
console . log ( 'HelloWorld deployed to:' , address );
}
main (). catch (( error ) => {
console . error ( error );
process . exitCode = 1 ;
});
Execute:
npx hardhat compile
npx hardhat run scripts/deploy-hello-world.ts --network brightcityTestnet
Validar o deploy
eth_getCode
curl -s https://rpc.fmartns.dev \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getCode","params":["0xENDERECO_DO_CONTRATO","latest"],"id":1}'
Resposta diferente de 0x indica código implantado.
Chamada read-only
npx hardhat console --network brightcityTestnet
const c = await ethers . getContractAt ( 'HelloWorld' , '0xENDERECO_DO_CONTRATO' );
await c . hello ();
Erros comuns
Erro Causa provável Solução Invalid opcode: 0x5fBytecode com PUSH0 (Shanghai+) evmVersion: "berlin" no HardhatSaldo insuficiente Deployer sem ETH nativo Obter saldo na testnet para a conta deployer Chain ID errado Rede configurada incorretamente 20260520 no Hardhat e na carteiraRPC inacessível Endpoint ou rede indisponível Verificar https://rpc.fmartns.dev
Próximos passos
Contratos de ativos ERC-721, ERC-1155 e ERC-20
Consultar no explorer Blocos, transações e contratos
Diferenças vs Ethereum Fork Berlin e limitações EVM
Boas práticas RPC, indexação e chaves