Back to Home

Lotto

utility
0x539f29128311...d37b219587f9
FrontierContract #475Exact Bytecode MatchEdit this contract
Deployed August 25, 2015 (10 years ago)Block 141,391

The public EtherPot lottery, an August 2015 Frontier contract whose blockhash-based winner selection became an early cautionary tale about on-chain randomness.

Frontier EraVerified Source

Historical Significance

EtherPot is one of the earliest decentralized lotteries on Ethereum and an early, well-documented lesson in smart contract security. Two flaws surfaced within days of launch. On August 27, 2015, security researcher Andrew Miller reported that the cash function ignored the return value of send, which can silently fail, for example through a deliberately preloaded call stack at depth 1023 or through running out of gas; when that happens execution continues, the subpot is marked as cashed, and those funds are lost forever. The author, Aakil Fernandes, acknowledged the report the same day and the recommended fix was to check the return value with if (!winner.send(subpot)) return. Separately, winner selection relied on block.blockhash, which only returns a non-zero hash for the most recent 256 blocks, so any subpot cashed more than 256 blocks after its decision block resolved to the first buyer rather than a fair draw. That second bug, pointed out to the author by Liana Hus, produced the launch-day anomaly of a single player holding about 8 percent of the tickets being reported as the winner of all three subpots of the first round. The contract still holds 0.1 ether that can never be released, a direct consequence of the send-failure flaw, and both issues are frequently cited in later discussions of on-chain randomness and defensive programming. The source was published by the author, and this byte-exact reproduction ties that published source to the deployed bytecode.

Context

August 2015 was the first month of the Ethereum Frontier mainnet, which launched on July 30, 2015. Tooling was minimal, the Solidity compiler was at v0.1.1, and there was no established testnet workflow, so developers commonly iterated by deploying straight to mainnet. EtherPot was part of this first wave of application experiments, alongside early registrars, wallets, and prediction markets, and was among the first contracts to put real value behind an on-chain game.

Key Facts
Deployment Block
141,391
Deployment Date
Aug 25, 2015, 02:55 PM
Code Size
2.7 KB
Gas at Deploy
732,663
Transactions by Year
201541
20221

Description

EtherPot was a decentralized lottery deployed on the Ethereum Frontier network in August 2015 by Aakil Fernandes and collaborators. Players bought tickets for 0.1 ether each by sending value to the contract. Rounds lasted 6800 blocks, roughly a day, and the winner of a round was selected from the blockhash of a block mined just after the round closed, an on-chain source of randomness with no operator. To blunt any single miner's incentive to grind that blockhash, a round's pot was split into subpots no larger than the 5 ether block reward, so the gain from manipulating a result stayed below the value of mining honestly. Each subpot was paid out independently through the cash function, which looked up the winning ticket and sent the subpot to that buyer.

This is the canonical public deployment, the version players actually used. It was deployed on August 25, 2015 from the same account that had deployed an earlier draft build four days before, and it still holds a small balance today. The source was published by the author in the etherpot/contract repository, and the runtime and creation bytecode here were reproduced byte-for-byte from that source compiled with soljson v0.1.1 (optimizer off), which confirms the published source is the one that was deployed.

The contract stored each round as a list of buyers, a running ticket count, a per-buyer ticket count, and a flag for each cashed subpot. calculateWinner mapped the blockhash-derived index back to a buyer by walking the buyers list and accumulating their ticket counts. The design depended on block.blockhash, which on Ethereum only returns a non-zero hash for the most recent 256 blocks, and that limitation is the root of the issues for which EtherPot is remembered.

Source Verified

SolidityExact bytecode match(2,728 bytes)
Compiler: soljson

Exact bytecode match (runtime + creation). Runtime: 2709 bytes. Creation: 2728 bytes (19 init + 2709 runtime payload, 0 constructor args). Runtime SHA-256 70faac9179cf23c0d3593a2fe13894f3f6687200a031a3b10fb16cfebebcb14a, creation SHA-256 fa517a5263b3f5bc73481486fe70cbc008a05ed564d03dba0e83b9d9e289ff59. Source is author-published (etherpot/contract); it compiles byte-exact with soljson v0.1.1 optimizer off.

Heuristic Analysis

The following characteristics were detected through bytecode analysis and may not be accurate.

Detected Type: utility

Bytecode Overview

Opcodes2,728
Unique Opcodes148
Jump Instructions115
Storage Operations42

External Links