Ethereum Classic (ETC) is the original Ethereum chain, continued by the people who refused the 2016 hard fork that reversed The DAO hack. It shares Ethereum's history up to block 1,920,000 and still runs the EVM, so Solidity contracts and Ethereum tooling mostly work on it. The differences are in what happened next: ETC stayed on proof of work, adopted a fixed supply schedule, skipped EIP-1559, and uses chain ID 61. Those choices affect fees, confirmation times and which compiler settings you can use.
The DAO and the fork
The DAO was an investment fund implemented as a smart contract, launched in April 2016. It raised about 12.7 million ETH, a large share of all ether at the time. In June 2016 an attacker used a reentrancy bug: the contract sent ether before updating the caller's balance, so the attacker's contract could call back into the withdrawal function again and again. Roughly 3.6 million ETH moved into a "child DAO", where The DAO's own rules locked it for weeks.
That delay gave the community time to argue about a response. The Ethereum Foundation and most of the ecosystem backed a hard fork at block 1,920,000 on 20 July 2016, which moved the affected ether into a refund contract. A minority rejected it. Their argument was "code is law": the contract did what its code allowed, and changing the ledger to undo an outcome, however unfair, broke the promise that a blockchain is immutable. Miners and users who kept running the old rules continued the unforked chain, and exchanges listed it as Ethereum Classic.
At first the two chains accepted the same signed transactions, so a transfer on one could be replayed on the other. EIP-155 later fixed this by including a chain ID in the signature. ETH uses chain ID 1; ETC uses 61.
Staying on proof of work
Ethereum moved to proof of stake at the Merge in September 2022. ETC stayed on proof of work and says it intends to stay there.
In November 2020 the Thanos hard fork changed ETC's mining algorithm from Ethash to Etchash. The only change was doubling the epoch length, which slows the growth of the DAG dataset that miners hold in memory. That let GPUs with 3 GB and 4 GB of memory keep mining ETC for years longer. After the Merge, a large amount of former Ethereum GPU hashrate moved to ETC, and today it is mined with both GPUs and Etchash ASICs.
A fixed monetary policy
Ethereum's issuance has no hard cap and has changed several times. ETC adopted a fixed schedule in 2017, known as 5M20 (ECIP-1017): every 5,000,000 blocks, the block reward drops by 20%.
| Era | Blocks | Block reward |
|---|---|---|
| 1 | 0 to 5M | 5 ETC |
| 2 | 5M to 10M | 4 ETC |
| 3 | 10M to 15M | 3.2 ETC |
| 4 | 15M to 20M | 2.56 ETC |
| 5 | 20M to 25M | 2.048 ETC |
With blocks roughly every 13 seconds, an era lasts about two years. The reductions form a geometric series, so total supply approaches a cap of about 210.7 million ETC. Uncle (ommer) rewards were reduced too. ETC doesn't burn a base fee, so all transaction fees go to miners.
51% attacks and the response
A proof-of-work chain is only as secure as the hashrate behind it, and before the Merge ETC had a small fraction of Ethereum's, on the same kind of hardware. That made it cheap to rent enough hashrate to rewrite recent history.
- January 2019: an attacker reorganised ETC and double-spent against exchanges, worth roughly a million dollars at the time.
- August 2020: three separate attacks, some reorganising thousands of blocks and double-spending millions of dollars' worth of ETC.
Exchanges responded by raising ETC deposit confirmation requirements sharply. The protocol response was MESS (Modified Exponential Subjective Scoring, ECBP-1100), activated in late 2020. MESS made nodes demand much more total work before accepting a reorganisation that replaced a long stretch of the chain they had already seen, which made deep private-chain attacks far more expensive. It was a subjective rule, since each node judges by when it first saw blocks, and it was later deactivated after the Merge brought far more hashrate to ETC. No attack on the 2020 scale has been reported since, but the lesson stands: confirmation counts on ETC should reflect the cost of renting its hashrate.
EVM compatibility and tooling
ETC has followed many Ethereum upgrades under its own names, adopting most execution-layer changes up to roughly Shanghai (including the PUSH0 opcode), but not EIP-1559. What that means in practice:
| Ethereum | Ethereum Classic | |
|---|---|---|
| Consensus | Proof of stake | Proof of work (Etchash) |
| Chain ID | 1 | 61 (Mordor testnet: 63) |
| Block time | 12 seconds | ~13 seconds, variable |
| Fee model | EIP-1559 base fee + tip | Legacy gasPrice |
| Transaction types | Legacy, 2930, 1559, blob, and newer | Legacy and EIP-2930 access lists |
| Latest EVM target | Current mainnet fork | About Shanghai |
| Finality | Economic finality in ~13 minutes | Probabilistic |
Proposals to add EIP-1559-style fees to ETC have been discussed; check whether any have activated before relying on the table above.
The main node client is Core-Geth, a fork of Geth. MetaMask, ethers.js, viem, Foundry and Hardhat all work once you point them at an ETC RPC endpoint. Two settings matter: compile for an EVM version ETC supports, and send legacy transactions.
# foundry.toml
[profile.default]
evm_version = "shanghai" # newer targets can emit opcodes ETC doesn't support
[rpc_endpoints]
etc = "${ETC_RPC_URL}"
mordor = "${MORDOR_RPC_URL}"
forge create src/Counter.sol:Counter \
--rpc-url etc --account deployer --legacy --broadcast
Recent Solidity versions default to an EVM version newer than Shanghai. Without the evm_version setting, a contract can compile cleanly and then fail on ETC because it uses Cancun-era opcodes such as MCOPY or transient storage.
With ethers v6, set the chain ID and transaction type explicitly:
import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider(process.env.ETC_RPC_URL, 61);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
const { gasPrice } = await provider.getFeeData();
const tx = await wallet.sendTransaction({
to: process.env.RECIPIENT!,
value: ethers.parseEther("0.5"),
type: 0, // legacy transaction
gasPrice,
});
const receipt = await tx.wait(60); // wait for 60 confirmations
console.log(receipt?.blockNumber);
When the differences matter
For a lot of Solidity code, ETC is just another EVM chain. The differences start to matter in a few places:
- Confirmations. There is no finalized checkpoint as on Ethereum. Pick a confirmation depth based on the value at risk and the cost of renting Etchash hashrate, and expect exchanges to require more blocks for ETC than for ETH.
- Chain ID. Always sign with chain ID 61 (63 on Mordor). A wallet or script that defaults to chain ID 1 will produce transactions ETC rejects.
- Fees. Code that reads
baseFeePerGas, uses theBASEFEEopcode or sends type-2 transactions needs a legacy path. - Compiler target. Pin
evmVersionto what ETC supports and redeploy tests on Mordor. - Ecosystem. Oracles, bridges, stablecoins and indexers are far thinner than on Ethereum. Check that the infrastructure you need actually runs on ETC.
- Governance. Changes go through Ethereum Classic Improvement Proposals (ECIPs), and ETC has historically been conservative about adopting Ethereum features.
Summary
| Question | Answer |
|---|---|
| Why does ETC exist? | It kept the chain unchanged after the 2016 DAO fork, on "code is law" grounds |
| How is it secured? | Proof of work (Etchash), probabilistic finality |
| What is its supply? | Fixed 5M20 schedule, capped near 210.7 million ETC |
| Can I use Solidity? | Yes, targeting about Shanghai, with legacy transactions |
| What should developers watch? | Chain ID 61, confirmation depth, no EIP-1559, thin infrastructure |
Get the weekly commit
New blockchain deep dives every week.