Commit-reveal lottery prototype deployed on 8 August 2015, the earlier draft of the EarlyLottery contract by the same developer.
Historical Significance
A commit-reveal lottery written in Solidity and deployed on 8 August 2015 by 0xfd2605a2bf58fdbb90db1da55df61628b47f9e8c, who deployed the larger EarlyLottery contract the following day. Play runs on an 88 block cycle read off block.number. buyTicket(bytes32) accepts a hash commitment in the first 40 blocks of the cycle and credits the sent ether. submitSecret(uint64) reveals the preimage between blocks 48 and 68. payout() picks a winner once block.number modulo 88 passes 68 and at least 68 blocks have elapsed since the previous draw, xors the revealed secrets together for the index into the ticket array, and sends the pot minus 25000 times tx.gasprice. Two flaws are visible in the compiled code. The reveal writes secrets[secrets.length], which is out of bounds and always throws, so no secret could ever be recorded, and payout() clears the ticket array before the loop that was meant to walk it and clear each entrant's commitment and balance. The later EarlyLottery contract rewrites both. Source recovered by exact bytecode match: solc v0.1.1+commit.6ff4cd6 with the optimizer on reproduces all 986 bytes of the creation transaction.
Context
Deployed 8 August 2015, the second day of the Ethereum Frontier network.
Key Facts
Description
A commit-reveal lottery written in Solidity and deployed on 8 August 2015 by 0xfd2605a2bf58fdbb90db1da55df61628b47f9e8c, who deployed the larger EarlyLottery contract the following day. Play runs on an 88 block cycle read off block.number. buyTicket(bytes32) accepts a hash commitment in the first 40 blocks of the cycle and credits the sent ether. submitSecret(uint64) reveals the preimage between blocks 48 and 68. payout() picks a winner once block.number modulo 88 passes 68 and at least 68 blocks have elapsed since the previous draw, xors the revealed secrets together for the index into the ticket array, and sends the pot minus 25000 times tx.gasprice. Two flaws are visible in the compiled code. The reveal writes secrets[secrets.length], which is out of bounds and always throws, so no secret could ever be recorded, and payout() clears the ticket array before the loop that was meant to walk it and clear each entrant's commitment and balance. The later EarlyLottery contract rewrites both. Source recovered by exact bytecode match: solc v0.1.1+commit.6ff4cd6 with the optimizer on reproduces all 986 bytes of the creation transaction.
Source Verified
963 bytes. Source reconstructed: commit-reveal lottery by same developer as EarlyLottery (0x7af6af3d). 5 functions: submitSecret(bytes32), random(), payout(), payoutReady(), buyTicket(bytes32). Correct size match and all selectors confirmed with v0.1.5 optimizer ON. 935 diffs in optimizer layout -- exact compiler snapshot not found. 0.300 ETH remains locked since Aug 8 2015.
Historian Categories
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Frontier Era
The initial release of Ethereum. A bare-bones implementation for technical users.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology (near-exact bytecode match).
View Verification ProofShow source code (Solidity)
contract Lottery {
uint startBlock;
uint numParticipants;
address[] participants;
uint64[] secrets;
mapping (address => bytes32) hashes;
mapping (address => uint) amounts;
function Lottery() { startBlock = block.number; }
function submitSecret(uint64 secret) {
if (!(block.number % 88 < 0x44 && block.number % 88 >= 0x30)) return;
if (sha3(bytes8(secret)) != hashes[msg.sender]) return;
participants.length++;
participants[participants.length - 1] = msg.sender;
secrets.length++;
secrets[secrets.length - 1] = secret;
}
function random() returns (uint64 r) {
for (uint i = 0; i < secrets.length; i++) {
r ^= secrets[i];
}
}
function payout() {
if (!payoutReady()) return;
uint winner = random() % participants.length;
participants[winner].call.value(this.balance - tx.gasprice * 25000)();
startBlock = block.number;
participants.length = 0;
secrets.length = 0;
numParticipants = 0;
}
function payoutReady() returns (bool) {
return block.number % 88 > 0x44 && block.number - startBlock > 0x44;
}
function buyTicket(bytes32 hash) {
if (block.number % 88 >= 0x28) return;
hashes[msg.sender] = hash;
amounts[msg.sender] += msg.value;
numParticipants++;
}
}External Links
Related contracts
Lottery
Same deployerThe first draft of the EarlyLottery commit-reveal lottery, deployed on 8 August 2015 a few hours before its rewrite.
0xf6bf0e...ec3b5cAugust 8, 2015Sha3
Same deployerA tiny utility contract that returns the SHA3 hash of a uint256 input.
0xb179a8...4bf09dAugust 9, 2015Sha3
Same deployerA tiny utility contract that returns the SHA3 hash of a uint256 input.
0x82000e...b0690aAugust 9, 2015Sha3
Same deployerA tiny utility contract that returns the SHA3 hash of a uint256 input.
0x627a6e...25bce8August 9, 2015LotteryPrototype
Same deployerThe first lottery contract deployed on Ethereum mainnet, created August 9, 2015 by one of the earliest recorded Ethereum users. Built, tested with two participa
0xcdd192...1b622cAugust 9, 2015EarlyLottery
Same deployerA commit-reveal lottery on an 88-block cycle, deployed August 9, 2015, ten days after genesis. Players commit a hashed secret, reveal it to earn one ticket per 0.1 ETH, and the winner is drawn from the XOR of all revealed secrets. Source recovered by exact bytecode match (solc v0.1.1).
0x7af6af...fbb992August 9, 2015