Bytecode verified via sibling
This contract shares identical runtime bytecode with SerpentGamble (0x59375871...) which has been verified through compiler archaeology.
Sibling of 0x59375871 (SerpentGamble). The full serpent_gamble provably-fair betting dapp from ethereum/dapp-bin.
Key Facts
Description
Deployed 2015-09-24 by Vitalik Buterin. This contract has identical bytecode to 0x59375871ab51e8ffdf8d894071b330a3fa55b7d0, which was verified as SerpentGamble. The full serpent_gamble provably-fair betting dapp (canonical source serpent_gamble/gamble.se in ethereum/dapp-bin): bettors pick their own odds, the owner settles rounds via a commit-reveal seed emitting Win/Loss, and unrevealed rounds can be force-refunded after two days.
Source Verified
Source is serpent_gamble/gamble.se from ethereum/dapp-bin. Deployed runtime (2387 bytes) and creation code (2426 bytes) reproduce byte-for-byte using ethereum/serpent commit f0b4128. runtime sha256 f19b4b3bf158be5ee2905ffea48a5631d62d78aae72b2ed7c2acd766681a3664; creation sha256 e4e0e66d8071ffdcab2bb8321641231ba6770322033abb6bcb8b0628dcc55350.
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)
data owner
data curseed
data curseedExpiry
data bets[2**100](bettor, bettor_key, potential_winnings, prob_milli)
data numBets
data depositLocked
data canAdministerAfter
data feeMillis
data minProbMilli
event Bet(bettor:address, value:uint256, prob_milli:uint256)
event Win(index:uint256, bettor:address, potentialWinnings:uint256, prob_milli:uint256)
event Loss(index:uint256, bettor:address, potentialWinnings:uint256, prob_milli:uint256)
event UnlockForAdministration()
event LockForAdministration()
event NewSeed()
NOT_UNLOCKED = 2**100
def init():
self.owner = msg.sender
# Minimum 1% winning chance
self.minProbMilli = 10
def const get_curseed():
return(self.curseed:bytes32)
def const get_available_funds():
return(self.balance - self.depositLocked)
def const get_administration_status():
if self.canAdministerAfter == NOT_UNLOCKED:
return(-1)
elif self.canAdministerAfter > block.number:
return(self.canAdministerAfter - block.number)
else:
return(0)
def unlock_for_administration():
# Only owner can do this
if msg.sender != self.owner:
return(0:bool)
# 5 block waiting period to change the current seed
self.canAdministerAfter = block.number + 5
log(type=UnlockForAdministration)
# Administrator method: supply the value for the old seed, process
# winnings and add a new seed
def set_curseed(old_value:bytes32, new_seed:bytes32):
# Only owner can do this
if msg.sender != self.owner:
return(0:bool)
# Must have precommitted and passed the waiting period
if self.canAdministerAfter > block.number:
return(0:bool)
# Must supply result for previous sha3
if sha3(old_value) != self.curseed and self.curseed != 0:
return(0:bool)
i = 0
numBets = self.numBets
# 2**256 divided by 1000
DIVCONST = 115792089237316195423570985008687907853269984665640564039457584007913129639
# Run through bets, process payouts
while i < numBets:
rnd = ~div(sha3([old_value, self.bets[i].bettor_key]:arr), DIVCONST)
if rnd < self.bets[i].prob_milli:
send(self.bets[i].bettor, self.bets[i].potential_winnings)
log(type=Win, i, self.bets[i].bettor, self.bets[i].potential_winnings, self.bets[i].prob_milli)
else:
log(type=Loss, i, self.bets[i].bettor, self.bets[i].potential_winnings, self.bets[i].prob_milli)
self.bets[i].bettor = 0
i += 1
self.numBets = 0
# Set the new seed hash, and a 2-day deadline for providing the next value
self.curseed = new_seed
self.curseedExpiry = block.timestamp + 86400 * 2
# Reset the locked deposits
self.depositLocked = 0
# Reset the precommitment for administrative actions
self.canAdministerAfter = NOT_UNLOCKED
log(type=LockForAdministration)
log(type=NewSeed)
return(1:bool)
# If the value behind the curseed hash has not been revealed within 2 days
def emergency_withdraw():
if block.timestamp <= self.curseedExpiry:
return(0:bool)
i = 0
numBets = self.numBets
while i < numBets:
send(self.bets[i].bettor, self.bets[i].potential_winnings * self.bets[i].prob_milli / 1000)
self.bets[i].bettor = 0
i += 1
# Donate all remaining funds to the Ethereum Foundation
suicide(0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae)
# Make a bet
def bet(bettor_key:bytes32, prob_milli):
# Maximum 100 bets to save on gas
if self.numBets >= 100:
send(msg.sender, msg.value)
return(-1)
potential_winnings = msg.value * (1000 - self.feeMillis) / prob_milli
# Do we have enough to pay for the winnings?
if self.balance - self.depositLocked < potential_winnings:
send(msg.sender, msg.value)
return(-2)
# Is the prob_milli value too low?
if prob_milli < self.minProbMilli:
return(-3)
# Lock up the deposit which would be used to pay winnings
self.depositLocked += potential_winnings
# Register the bet
betIndex = self.numBets
self.bets[betIndex].bettor = msg.sender
self.bets[betIndex].bettor_key = bettor_key
self.bets[betIndex].potential_winnings = potential_winnings
self.bets[betIndex].prob_milli = prob_milli
self.numBets = betIndex + 1
log(type=Bet, msg.sender, msg.value, prob_milli)
return(betIndex)
# Owner withdraw profits (deposit simply by sending ether to the contract)
def withdraw(amount):
# Must be the owner
if msg.sender != self.owner:
return(0:bool)
# Must have precommitted and passed the waiting period
if self.canAdministerAfter > block.number:
return(0:bool)
# Maximum withdrawal
if amount > self.balance - self.depositLocked:
return(0:bool)
send(self.owner, amount)
# Reset the precommitment for administrative actions
self.canAdministerAfter = NOT_UNLOCKED
log(type=LockForAdministration)
return(1:bool)
# Set fee
def set_fee_millis(millis):
# Must be the owner
if msg.sender != self.owner:
return(0:bool)
# Must have precommitted and passed the waiting period
if self.canAdministerAfter > block.number:
return(0:bool)
# Obvious restrictions
if millis < 0 or millis > 999:
return(0:bool)
self.feeMillis = millis
# Reset the precommitment for administrative actions
self.canAdministerAfter = NOT_UNLOCKED
log(type=LockForAdministration)
return(1:bool)
# Get fee
def const get_fee_millis():
return(self.feeMillis)
# Get the number of bets that have currently been made
def const get_num_bets():
return(self.numBets)
# Get the data about a bet at a particular index
def const get_bet(betIndex):
return([self.bets[betIndex].bettor, self.bets[betIndex].potential_winnings, self.bets[betIndex].prob_milli]:arr)External Links
Related contracts
SerpentGamble
Same deployerProvably-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.
0x034df8...200e2fSeptember 20, 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.
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, 2015