Contract Code

Overview

Every deployed contract has associated bytecode that can be retrieved from the network. This functionality is useful for contract verification, security analysis, and debugging purposes.

Using getCode()

The provider's getCode() method retrieves contract data from the network. Depending on the parameters, it returns either the full contract data or only the bytecode for improved efficiency.

getCode() Method Signature
typescript
async getCode(
    address: string | Address,
    onlyBytecode?: boolean
): Promise<ContractData | Buffer>

The table below describes the method parameters:

Parameter Type Required Description
address string | Address Yes The contract address to fetch code from
onlyBytecode boolean No When true, returns only the bytecode as a Buffer; otherwise returns full ContractData

Returns a ContractData object containing the contract's bytecode and metadata, or a Buffer containing only the bytecode when onlyBytecode is set to true.

Example

The following examples demonstrate how to fetch contract code:

typescript
// Fetch full contract data
const contractData = await provider.getCode(contractAddress);

// Fetch only bytecode (more efficient)
const bytecodeOnly = await provider.getCode(contractAddress, true);

ContractData Class

The ContractData class encapsulates contract bytecode and associated metadata:

typescript
interface ContractData {
    bytecode: Uint8Array;       // Contract WASM bytecode
    contractAddress: Address;   // Contract address
}

Examples

Fetch Full Contract Data

typescript
const address = Address.fromString('0x...');
const contractData = await provider.getCode(address, false);

console.log('Contract address:', contractData.contractAddress.toHex());
console.log('Bytecode size:', contractData.bytecode.length, 'bytes');

Fetch Bytecode Only

When only the bytecode is required, setting onlyBytecode to true provides a more efficient response:

typescript
import { toHex } from '@btc-vision/bitcoin';

const contractData = await provider.getCode(contractAddress, true);

const bytecode = contractData.bytecode;
console.log('Bytecode:', toHex(bytecode).slice(0, 100), '...');

Verify Contract Deployment

Check whether a contract has been deployed at a specific address:

typescript
async function isContractDeployed(
    provider: AbstractRpcProvider,
    address: string | Address
): Promise<boolean> {
    try {
        const code = await provider.getCode(address, true);
        return code.bytecode.length > 0;
    } catch {
        return false;
    }
}

// Usage
const deployed = await isContractDeployed(provider, contractAddress);
console.log('Contract deployed:', deployed);

Compare Contract Code

Determine whether two contracts have identical bytecode:

typescript
import { toHex } from '@btc-vision/bitcoin';

async function compareContracts(
    provider: AbstractRpcProvider,
    address1: Address,
    address2: Address
): Promise<boolean> {
    const [code1, code2] = await Promise.all([
        provider.getCode(address1, true),
        provider.getCode(address2, true),
    ]);

    return toHex(code1.bytecode) === toHex(code2.bytecode);
}

// Check if two contracts have the same code
const sameCode = await compareContracts(provider, addr1, addr2);
console.log('Same bytecode:', sameCode);

Calculate Code Hash

Generate a unique identifier for contract code using a cryptographic hash:

typescript
import { toHex } from '@btc-vision/bitcoin';
import { sha256 } from '@noble/hashes/sha256';

async function getCodeHash(
    provider: AbstractRpcProvider,
    address: Address
): Promise<string> {
    const contractData = await provider.getCode(address, true);
    const hash = sha256(contractData.bytecode);
    return toHex(hash);
}

// Get unique identifier for contract code
const codeHash = await getCodeHash(provider, contractAddress);
console.log('Code hash:', codeHash);

Use Cases

Contract Verification

Verify that a deployed contract matches the expected bytecode:

typescript
import { toHex } from '@btc-vision/bitcoin';

async function verifyContract(
    provider: AbstractRpcProvider,
    address: Address,
    expectedBytecode: Uint8Array
): Promise<boolean> {
    const contractData = await provider.getCode(address, true);
    return toHex(contractData.bytecode) === toHex(expectedBytecode);
}

Security Analysis

Analyze contract size and bytecode characteristics:

typescript
import { toHex } from '@btc-vision/bitcoin';

async function analyzeContract(
    provider: AbstractRpcProvider,
    address: Address
) {
    const contractData = await provider.getCode(address, false);

    console.log('Contract Analysis:');
    console.log('  Address:', contractData.contractAddress.toHex());
    console.log('  Bytecode size:', contractData.bytecode.length, 'bytes');

    return {
        address: contractData.contractAddress.toHex(),
        size: contractData.bytecode.length,
    };
}

Contract Discovery

Identify contracts matching a specific code hash:

typescript
async function findContractsWithCode(
    provider: AbstractRpcProvider,
    addresses: Address[],
    targetCodeHash: string
): Promise<Address[]> {
    const matches: Address[] = [];

    for (const address of addresses) {
        try {
            const codeHash = await getCodeHash(provider, address);
            if (codeHash === targetCodeHash) {
                matches.push(address);
            }
        } catch {
            // Contract doesn't exist or error occurred
        }
    }

    return matches;
}