Docs

eth_getCode - Celo RPC Method

Get contract bytecode on Celo. Essential for verifying smart contracts for mobile stablecoin payments (MiniPay 10M+ wallets), remittances, humanitarian aid, and local currency stablecoins (cUSD, cNGN, cEUR).

Returns the bytecode at a given address on Celo.

Why Celo? Build on the mobile-first L2 powering 500K+ daily active users and $2B+ monthly stablecoin volume with phone number-based addressing, sub-cent fees, 150+ country adoption, Nightfall privacy layer, and Opera browser integration.

When to Use This Method

eth_getCode is essential for mobile payment developers, fintech builders, and teams targeting emerging markets:

  • Contract Verification -- Verify that the bytecode deployed at an address matches the expected source code compilation output on Celo
  • EOA vs Contract Detection -- Determine whether an address is an externally owned account (returns 0x) or a deployed smart contract (returns bytecode)
  • Proxy Pattern Detection -- Check if a proxy contract has been initialized by examining whether its implementation slot contains code
  • Security Auditing -- Validate contract deployments before interacting with them on mobile stablecoin payments (MiniPay 10M+ wallets), remittances, humanitarian aid, and local currency stablecoins (cUSD, cNGN, cEUR)

Common Use Cases

1. Detect Contract vs EOA

Determine if an address is a smart contract or a regular wallet on Celo:

JavaScript
import { JsonRpcProvider } from 'ethers';

const provider = new JsonRpcProvider('https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY');

async function isContract(address) {
  const code = await provider.getCode(address);
  return code !== '0x' && code !== '0x0';
}

async function classifyAddress(address) {
  if (await isContract(address)) {
    const balance = await provider.getBalance(address);
    console.log('Contract at', address, '- balance:', balance.toString());
    return 'contract';
  }
  console.log('EOA at', address);
  return 'eoa';
}

2. Verify Proxy Implementation Initialization

Check whether a proxy contract has been initialized with an implementation on Celo:

JavaScript
import { JsonRpcProvider } from 'ethers';

const provider = new JsonRpcProvider('https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY');

async function checkProxyInitialized(proxyAddress) {
  // EIP-1967 implementation slot
  const IMPL_SLOT = '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc';
  
  const slotValue = await provider.getStorage(proxyAddress, IMPL_SLOT);
  const implAddress = '0x' + slotValue.slice(26);
  
  const implCode = await provider.getCode(implAddress);
  const hasCode = implCode !== '0x' && implCode !== '0x0';
  
  console.log(`Proxy: ${proxyAddress}`);
  console.log(`Implementation: ${implAddress} (has code: ${hasCode})`);
  
  return hasCode;
}

3. Batch Contract Detection

Scan multiple addresses to classify them efficiently:

JavaScript
async function scanAddresses(provider, addresses) {
  const results = [];
  
  for (const address of addresses) {
    try {
      const code = await provider.getCode(address);
      const type = (code === '0x' || code === '0x0') ? 'EOA' : 'Contract';
      results.push({ address, type, bytecodeSize: code.length });
    } catch (error) {
      results.push({ address, type: 'Error', error: error.message });
    }
  }
  
  const summary = {
    total: results.length,
    contracts: results.filter(r => r.type === 'Contract').length,
    eoas: results.filter(r => r.type === 'EOA').length,
    errors: results.filter(r => r.type === 'Error').length
  };
  
  console.log('Scan results:', summary);
  return { results, summary };
}

Best Practices

  • Check both 0x and 0x0 return values -- different client implementations return one or the other for EOAs
  • Use historical block numbers with eth_getCode to verify contract state at a specific point in time
  • For proxy pattern detection, combine eth_getCode with eth_getStorageAt to fully verify initialization
  • Cache bytecode by address, as deployed contract code is immutable
  • The return value length is roughly 2x the deployment bytecode size (hex encoding doubles the byte count)

Code Examples