Etherscan API – How to Retrieve Contract Creator Information

etherscan

The Etherscan web page shows the creator address of a contract, like this ("Circle: Deployer" in the image, but I'm fine with just the address):
USDC contract

Is there a way how to get this address information using the Etherscan API, similar to how the source code and ABI of a contract can be read?

Best Answer

Etherscan/Polygonscan API Solution:

I did finally find the proper endpoint for these requests. You can batch a max of 5 contracts per request. The etherscan API seems more reliable than JSON RPC method mentioned below. Additionally the etherscan API is much faster. Use npm lib node-fetch if in a node-js context. Solution also works with polygonscan:

// You can get an API key on the free-tier of etherscan/polygonscan
const APIKEY="YourApiKey" 

async function getContractCreators(
  // Array of contract-address strings (Maximum 5 per API call)
  contracts
){
  const url = `https://api.etherscan.io/api?module=contract&action=getcontractcreation&apiKey=${APIKEY}&contractaddresses=${contracts.toString()}`;
  const req = await fetch(url);
  const res = await req.json()
  // Make sure req was success
  if(res.status!='1'){
    console.warn("Handle req error here",res)
    return []
  }
  res.result.forEach(c => {
    let contract = c.contractAddress; // contract-address
    let creator  = c. contractCreator; // creator-wallet-address
    console.log("🔎 Found Creator"
    console.log("  -> contract :" + contract);
    console.log("  -> creator :" + creator)
  })
  
  return res.result
}


getContractCreators(["0xB83c27805aAcA5C7082eB45C868d955Cf04C337F","0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45","0xe4462eb568E2DFbb5b0cA2D3DbB1A35C9Aa98aad","0xdAC17F958D2ee523a2206206994597C13D831ec7","0xf5b969064b91869fBF676ecAbcCd1c5563F591d0"]);

Old Solution With EVM JSON RPC:

See this answer https://ethereum.stackexchange.com/a/65210/125787

The code looks like this and it may not work if the creator of the contract was another contract and not a wallet.

import Web3 from "web3";

// Here we use alchemy but you can use others http or websocket
const web3 = new Web3("https://eth-mainnet.alchemyapi.io/v2/<YourAPIKey>")

async function search_contract_cretion_block(contract_address) {
    var highest_block = await web3.eth.getBlockNumber();
    var lowest_block = 0;

    var contract_code = await web3.eth.getCode(contract_address, highest_block);
    if (contract_code == "0x") {
        console.error("Contract " + contract_address + " does not exist!");
        return -1;
    }

    while (lowest_block <= highest_block) {
        let search_block = parseInt((lowest_block + highest_block) / 2)
        contract_code = await web3.eth.getCode(contract_address, search_block);

        //console.log(highest_block, lowest_block, search_block, contract_code);

        if (contract_code != "0x") {
            highest_block = search_block;
        } else if (contract_code == "0x") {
            lowest_block = search_block;
        }

        if (highest_block == lowest_block + 1) {
            return highest_block;
        }
    }

}

async function search_contract_creator (contract_address, block) {
    var block = await web3.eth.getBlock(block);

    var transactions = block.transactions;

    for (let transaction in transactions) {
        let receipt = await web3.eth.getTransactionReceipt(transactions[transaction]);
        if (receipt.contractAddress?.toLowerCase() == contract_address.toLowerCase()) {
            return receipt.from
        }
    }

    return -1;
}

async function find_contract_creator (contract_address) {
    var block = await search_contract_cretion_block(contract_address);
    var creator = await search_contract_creator(contract_address, block);
    console.log(creator)
    return creator;
}

find_contract_creator("0x40e85735ff7c7230177589b4e52295b899ccc23e");
Related Topic