Closed arthurgousset closed 2 months ago
As a quick solution, I used ChatGPT to help me put together a shell script that calculates the size of each currently deployed core contract.
It uses:
network:contracts
) to get all core contracts and their implementation addresses, cast code
) to get the bytecode deployed at each core contract implementation address, andRequirements:
Steps to reproduce:
get_contract_bytecode_size.sh
scriptchmod +x get_contract_bytecode_size.sh
./get_contract_bytecode_size.sh
Current script:
#!/bin/bash
# Get the current date and time for the filename
timestamp=$(date +"%Y%m%d_%H%M%S")
OUTPUT_FILE="bytecode_sizes_$timestamp.txt"
# Set the RPC URL for the blockchain
RPC_URL="https://forno.celo.org"
# Fetch the contracts from celocli and process the output
celocli network:contracts --node $RPC_URL | grep -E '0x[a-fA-F0-9]{40}' | while IFS=" " read -ra line
do
# Extract contract name and implementation address from the output
contract="${line[0]}"
implementation_address="${line[2]}"
# Ensure address is not empty or undefined
if [ -z "$implementation_address" ] || [ "$implementation_address" == "NONE" ]; then
echo "No implementation address available for $contract"
echo "$contract,NONE,0 KB" >> $OUTPUT_FILE
continue
fi
# Fetch bytecode using cast with the specified flag order
bytecode=$(cast code $implementation_address --rpc-url $RPC_URL 2>/dev/null) # Redirect stderr to null to handle any errors gracefully
# Check if bytecode was successfully fetched; handle cases where the contract might not have bytecode (e.g., non-contract addresses)
if [[ -z "$bytecode" || "$bytecode" == "0x" ]]; then
echo "No bytecode found for $contract at $implementation_address"
echo "$contract,$implementation_address,0 KB" >> $OUTPUT_FILE
continue
fi
# Calculate size in bytes (hex chars / 2)
size_bytes=$(((${#bytecode} - 2) / 2))
# Calculate size in kilobytes
size_kb=$(echo "scale=3; $size_bytes / 1024" | bc)
# Output result with contract name
echo "Contract: $contract, Address: $implementation_address, Size: $size_kb KB" | tee -a $OUTPUT_FILE
done
Example output:
$ ./get_contract_bytecode_size.sh
Contract: Accounts, Address: 0x75Ec00c4B09574945F7d407797f8b61ca5AD9Cef, Size: 35.713 KB
Contract: Attestations, Address: 0x5729126891355E3C2626338151Dd50Cc0415E071, Size: 22.639 KB
Contract: BlockchainParameters, Address: 0x34FE128561A54F8d4185cd24d78634300B119725, Size: 10.877 KB
Contract: DoubleSigningSlasher, Address: 0x4Bb82B5862Beb483Fdb762EC4A6cB60953568A12, Size: 16.540 KB
Contract: DowntimeSlasher, Address: 0x9ebB6A46149a43C9D1B12EfdC068b969eCA7246F, Size: 20.266 KB
Contract: Election, Address: 0xCdE5039e3AcB3483aEebEBd59Cf6936056c455D4, Size: 43.262 KB
Contract: EpochRewards, Address: 0x563BA8Ed56bd32a964831aB6AfF1E53238177eDA, Size: 23.583 KB
Contract: Escrow, Address: 0xcC4E6caBe88EBb7FCCB40d862bf1C3a89f88e835, Size: 17.457 KB
Contract: FederatedAttestations, Address: 0x76A4daaC43912A443f098D413DED2Cb7A153EA85, Size: 13.846 KB
Contract: FeeCurrencyWhitelist, Address: 0xbC75342726648c4798543bac986c529f54220953, Size: 3.149 KB
Contract: FeeHandler, Address: 0x90eD9a893bC7be80F2D0E68650a8780A4E7373a5, Size: 20.698 KB
Contract: Freezer, Address: 0xa79cDb272799175A118A4Ce49ceCBF3eC86649e6, Size: 2.198 KB
Contract: GasPriceMinimum, Address: 0x52737f41EA463226af071933c823c2D550Bd6610, Size: 9.732 KB
Contract: GoldToken, Address: 0xcB8710e072aC4700eE7eD0C63B2f2102366a7a39, Size: 9.563 KB
Contract: Governance, Address: 0x19F78d207493Bf6f7E8D54900d01bb387F211b28, Size: 52.737 KB
Contract: LockedGold, Address: 0xbc518666F0827F4736220aC11c9a2cF37B1DE5aD, Size: 32.160 KB
Contract: MentoFeeHandlerSeller, Address: 0xBCF2374Fe8D582aB31840Ac08Fbc6bCD073d8c09, Size: 9.353 KB
Contract: OdisPayments, Address: 0x9Ea5E9b9B48a72325D59B3EBA147F42b1b14BF78, Size: 3.594 KB
Contract: Random, Address: 0xE43ea9C641a2af9959CaEEe54aDB089F65457028, Size: 12.037 KB
Contract: Registry, Address: 0x203fdf86A00999107Df531fa00b4bA81d674cb66, Size: 4.096 KB
Contract: Reserve, Address: 0xfD9651862Bc1965349E92073152112289393b57d, Size: 21.888 KB
Contract: SortedOracles, Address: 0x35a4f0C8C0B48769F036b79F9d428BeA286f6ab5, Size: 18.915 KB
Contract: StableToken, Address: 0x434563B0604BE100F04B7Ae485BcafE3c9D8850E, Size: 9.180 KB
Contract: StableTokenBRL, Address: 0x434563B0604BE100F04B7Ae485BcafE3c9D8850E, Size: 9.180 KB
Contract: StableTokenEUR, Address: 0x434563B0604BE100F04B7Ae485BcafE3c9D8850E, Size: 9.180 KB
Contract: UniswapFeeHandlerSeller, Address: 0xb851A5f1dbC743FdCe3009a3410df317cb33e24b, Size: 13.628 KB
Contract: Validators, Address: 0xe52EaC18fB3C1e1713e73d4A5b7dCb12a2f2C697, Size: 58.228 KB
Next I'll compare this to the bytecode generated during the build process.
I compared the contract sizes from the build artefacts, with the contract size from the deployed contracts. I pasted the results here for a quick comparison to a Google Sheet: Contract sizes.
Most core contracts yield about the same size (comparing the on-chain calculation and the build artefact calculation).
Closing the loop here:
I calculated contract sizes in two ways (to double-check that there is no hidden optimization or other inconsistency):
The scripts used for the calculations are in this PR:
The contract sizes are ordered and pasted here for ease of reference: Contract sizes
Current max is
MaxCodeSize = 65536 // Maximum bytecode to permit for a contract (2^16)
Source: protocol_params.go
(for future reference) CEL2 size limit is set in this configuration file:
grep MaxCodeSize params/protocol_params.go
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
MaxInitCodeSize = 2 * MaxCodeSize // Maximum initcode to permit in a creation transaction and create instructions
Source: celo-org/op-geth > params/protocol_params.go
PR to modify it:
Context
Discussion and context
References:
The goal is to know the size of every core contract to see which is above the bytecode limit.