Provably-fair betting game where players choose their own odds. The owner settles bets with a commit-reveal random seed. Includes a 2-day emergency refund.
Key Facts
Description
Deployed September 20, 2015 in block 263291 by Vitalik Buterin (0x1Db3439a222C519ab44bb1144fC28167b4Fa6EE6). Written in Serpent, an early Ethereum high-level language. The runtime (1264 bytes) and the full creation bytecode (1286 bytes) both reproduce byte-for-byte from the reconstructed source using the ethereum/serpent compiler at commit f0b4128.
How it works:
bet(guess, odds): payable. A player sends ETH and picks their own odds, a win chance in per-mille from 0 to 1000. The contract records a payout of msg.value * 1000 / odds, a fair line with no house edge, along with the player's bytes32 guess used as draw entropy. The bet is rejected if 100 bets are already open (returns -1) or if the bank cannot cover the payout (returns -2), and the stake is refunded in both cases. It emits Bet(sender, value, odds).
set_curseed(a, b): owner only. Settles the round. It requires sha3(curseed) == a, or curseed == 0 on the first run. For each open bet it computes rand = sha3([a, guess]) / (2^256 / 1000), giving a number from 0 to 999, and pays the player the recorded payout if rand < odds. It then clears all bets, stores the new seed commitment b, resets a 2-day deadline, and emits NewSeed.
emergency_withdraw(): callable by anyone once the 2-day deadline passes without a settlement. It refunds every open bet its original stake (payout * odds / 1000) and then self-destructs.
withdraw(): sends the bank's free balance (this.balance minus reserved payouts) to the owner.
get_curseed(), get_num_bets(), get_bet(id): read-only views.
The seed mechanism is a commit-reveal scheme. Each round the owner publishes a value and later reveals its hash to drive the per-bet randomness, so the draw cannot be chosen after bets are placed. The 2-day deadline and emergency_withdraw path protect bettors if the owner stops settling.
On-chain history shows the contract was only ever exercised by its deployer: 14 set_curseed reveals and no external bettors. It holds no balance today.
Source Verified
Runtime bytecode (1264 bytes) and full creation bytecode (1286 bytes, including the init constructor that sets the owner) both reproduce byte-for-byte from the reconstructed Serpent source. Compiled with ethereum/serpent at commit f0b4128; commit 146cc8a, dated 2015-09-20, produces an identical result. runtime sha256 96fc31b95c65b4110a4c25de8e01c1b6abd3094b972f16ccf1d91d64d9fe7ca0, creation sha256 22efde675afdfa05b2bb6335ff2a9d5ff3411ce49786fac6c5ed2e98f37e03e1.
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 and exact bytecode matching.
View Verification ProofShow source code (Serpent)
# Verified by EthereumHistory (ethereumhistory.com)
#
# Vitalik Buterin's first deployed contract: a provably-fair betting game
# 0x034dF87052894BbE35CBd4546fD1d3Bdf7200E2F (block 263291, 2015-09-20)
# Serpent (ethereum/serpent @ f0b4128). Runtime + creation bytecode EXACT match.
event Bet(sender:address, value:uint256, odds:uint256)
event NewSeed()
data owner
data curseed
data deadline
data bets[2^100](sender, guess, payout, odds)
data numbets
data reserved
def init():
self.owner = msg.sender
def get_curseed():
return(self.curseed)
def set_curseed(a:bytes32, b:bytes32):
if msg.sender != self.owner:
return(0)
if a != sha3(self.curseed) and self.curseed != 0:
return(0)
i = 0
n = self.numbets
seed = 115792089237316195423570985008687907853269984665640564039457584007913129639
while i < n:
rand = div(sha3([a, self.bets[i].guess]:arr), seed)
if rand < self.bets[i].odds:
send(self.bets[i].sender, self.bets[i].payout)
self.bets[i].sender = 0
i += 1
self.numbets = 0
self.curseed = b
self.deadline = block.timestamp + 172800
log(type=NewSeed)
return(1)
def emergency_withdraw():
if block.timestamp <= self.deadline:
return(0)
i = 0
n = self.numbets
while i < n:
send(self.bets[i].sender, self.bets[i].payout * self.bets[i].odds / 1000)
self.bets[i].sender = 0
i += 1
suicide(0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae)
def bet(guess:bytes32, odds):
if self.numbets >= 100:
send(msg.sender, msg.value)
return(-1)
payout = msg.value * 1000 / odds
if self.balance - self.reserved < payout:
send(msg.sender, msg.value)
return(-2)
self.reserved += payout
id = self.numbets
self.bets[id].sender = msg.sender
self.bets[id].guess = guess
self.bets[id].payout = payout
self.bets[id].odds = odds
self.numbets = id + 1
log(type=Bet, msg.sender, msg.value, odds)
return(id)
def withdraw():
send(self.owner, self.balance - self.reserved)
def get_num_bets():
return(self.numbets)
def get_bet(id):
return([self.bets[id].sender, self.bets[id].payout, self.bets[id].odds]:arr)External Links
Related contracts
SerpentGamble
Same deployerSibling of 0x034dF870 (SerpentGamble). Provably-fair Serpent betting game; players choose their own odds, owner settles via commit-reveal seed, 2-day refund.
0x9ca7e9...fa8bb4September 21, 2015SerpentGamble
Same deployerSibling of 0x034dF870 (SerpentGamble). Provably-fair Serpent betting game; players choose their own odds, owner settles via commit-reveal seed, 2-day refund.
0x75649a...176028September 21, 2015SerpentGamble
Same deployerIntermediate build of serpent_gamble, a provably-fair betting dapp (Bet/Win/Loss/NewSeed), related to verified sibling 0x59375871. Source not yet reconstructed.
0xe1a99f...0d2457September 21, 2015SerpentGamble
Same deployerIntermediate build of serpent_gamble, a provably-fair betting dapp (Bet/Win/Loss/NewSeed), related to verified sibling 0x59375871. Source not yet reconstructed.
0xdc00a9...15861fSeptember 21, 2015SerpentGamble
Same deployerIntermediate build of serpent_gamble, a provably-fair betting dapp (Bet/Win/Loss/NewSeed), related to verified sibling 0x59375871. Source not yet reconstructed.
0xd0ed09...300b48September 21, 2015SerpentGamble
Same deployerIntermediate build of serpent_gamble, a provably-fair betting dapp (Bet/Win/Loss/NewSeed), related to verified sibling 0x59375871. Source not yet reconstructed.
0x3fb587...bb9815September 23, 2015