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

1

Instalar dependências

npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox dotenv
npx hardhat init
2

Variáveis de ambiente

Crie .env a partir do exemplo abaixo. Não commite .env com chave real.
3

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

1

Explorer

Abra o endereço do contrato em explorer.fmartns.dev e confira bytecode e transações de criação.
2

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.
3

Chamada read-only

npx hardhat console --network brightcityTestnet
const c = await ethers.getContractAt('HelloWorld', '0xENDERECO_DO_CONTRATO');
await c.hello();

Erros comuns

ErroCausa provávelSolução
Invalid opcode: 0x5fBytecode com PUSH0 (Shanghai+)evmVersion: "berlin" no Hardhat
Saldo insuficienteDeployer sem ETH nativoObter saldo na testnet para a conta deployer
Chain ID erradoRede configurada incorretamente20260520 no Hardhat e na carteira
RPC inacessívelEndpoint ou rede indisponívelVerificar 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