Deploying Solidity smart contracts can be expensive because the code needs to be stored on the shared storage of a decentralized peer to peer blockchain network.
The dollar cost of deploying Solidity smart contracts is dependent on a number of variables:
- Bytecode size of the contract(s)
- Gas price which is based on network congestion and varies every block
- ETH/USD price as we need native ETH to deploy contracts on mainnet and many L2’s
I’ve previously provided code to analyze the bytecode size of contracts, you can also check this on remix.
You can check the current gas price here: https://etherscan.io/gastracker
And the price of ETH can be found with a quick google search.
Wouldn’t it be great if there was a script to automate this process…
You’ll need NodeJS installed and then install the dependencies and run it on a Solidity file.
npm install ethers axios
node estimate.js ./contracts/MyToken.json
Here is the code for estimate.js, it’s also available in the Github repo at: https://github.com/jamesbachini/Estimate-Deployment-Cost
const fs = require('fs');
const ethers = require('ethers');
const axios = require('axios');
const solc = require('solc');
const provider = new ethers.JsonRpcProvider('https://cloudflare-eth.com');
async function getEthPrice() {
const response = await axios.get('https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd');
return response.data.ethereum.usd;
}
async function estimateDeploymentCost(contractPath) {
const source = fs.readFileSync(contractPath, 'utf8');
const input = { language: 'Solidity', sources: { 'contract.sol': { content: source, }, }, settings: { outputSelection: { '*': { '*': ['*'], }, }, }, };
const output = JSON.parse(solc.compile(JSON.stringify(input)));
const contract = output.contracts['contract.sol'][Object.keys(output.contracts['contract.sol'])[0]];
const bytecode = contract.evm.bytecode.object;
const deployTransaction = { data: '0x' + bytecode };
const estimatedGasUnits = await provider.estimateGas(deployTransaction);
const feeData = await provider.getFeeData();
const gasPrice = feeData.gasPrice;
const priorityFee = feeData.maxPriorityFeePerGas;
const ethPriceUsd = await getEthPrice();
const effectiveGasPrice = gasPrice + priorityFee;
const gasCost = effectiveGasPrice * estimatedGasUnits;
const estimatedCostEth = ethers.formatEther(gasCost);
const estimatedCostUsd = parseFloat(estimatedCostEth) * ethPriceUsd;
console.log(`Estimated Gas Units: ${estimatedGasUnits.toString()}`);
console.log(`Gas Price: ${ethers.formatUnits(gasPrice, 'gwei')} gwei`);
console.log(`Priority Fee: ${ethers.formatUnits(priorityFee, 'gwei')} gwei`);
console.log(`ETH Price: $${ethPriceUsd} USD`);
console.log(`Estimated Deployment Cost: ${estimatedCostEth} ETH (~$${estimatedCostUsd.toFixed(2)} USD)`);
}
const contractPath = process.argv[2];
if (!contractPath) throw new Error('No path to the compiled contract file');
estimateDeploymentCost(contractPath);
I hope this script is useful and it helps plan out those mainnet deployment budgets if/when gas prices get extortionate once again.