Back to Home

FinneyDonationGamble

program
0x233820087a75...e0b7c546d3f6
FrontierContract #7,015Source VerifiedEdit this contract
Deployed January 24, 2016 (10 years ago)Block 896,743

A gambling contract where players bet at least 1 finney for a chance to win 10% of the balance. Wins also donate to the Ethereum Foundation.

Key Facts

Deployment Block
896,743
Deployment Date
Jan 24, 2016, 10:36 AM
Code Size
748.0 B
Gas at Deploy
229,180
Transactions by Year
201626

Description

A gambling contract created by forum user FrankHold as a self-described first Solidity contract. Players send at least 1 finney (0.001 ETH) to the fallback function, triggering a pseudo-random check. If the result modulo a difficulty value equals zero, the player wins 10% of the contract balance. On every win, 4.5% of the balance is also sent to the Ethereum Foundation multisig (0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae) as a donation.

The randomness is derived from block.timestamp, block.blockhash, block.difficulty, and block.number, mixed with a large prime-like modulus constant. The difficulty scales inversely with bet size: larger bets have better odds.

The contract provides three view functions: Basics() shows the next potential payout and donation amounts, History() returns full statistics including total bets, payouts, and high scores, and Under_the_Hood() exposes the internal random state.

FrankHold posted the contract on the Ethereum forum on January 24, 2016, with source code on GitHub Gist and a challenge: "If someone can crack it he/she can keep the 10 Ether." The deployer seeded the contract with about 20 ETH and was the only player across 27 transactions over 3 days (Jan 24-27, 2016). Total payouts were approximately 14 ETH to the deployer and 6.2 ETH donated to the Ethereum Foundation. The contract still holds 0.049 ETH.

Source Verified

Solidityauthor_published
Compiler: soljson

Author FrankHold published source code, compiler version, and bytecode on the Ethereum forum (forum.ethereum.org/discussion/4258) and GitHub Gist (gist.github.com/FrankHold/bda693def28e40fb30a4). Runtime bytecode matches on-chain code exactly (691 bytes). Compiled with browser-solidity using v0.2.0 nightly from January 20, 2016.

Heuristic Analysis

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

Detected Type: program

Frontier Era

The initial release of Ethereum. A bare-bones implementation for technical users.

Block span: 01,149,999
July 30, 2015March 14, 2016

Bytecode Overview

Opcodes748
Unique Opcodes118
Jump Instructions26
Storage Operations53

Verified Source Available

Source code published by the original contract author.

View Verification Proof
Show source code (Solidity)
contract FinneyDonationGamble {
    // Basics
    address foundation = 0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae;
    // History
    uint256 Bets_total_number;    // Number of bets
    uint256 Bets_since_last_win;  // Number of bets since last win
    uint256 Sum_of_Payouts;       // Sum pay out
    uint256 Sum_of_Donations;     // Sum donations
    uint256 Last_Block_Number;    // Last block
    uint256 Last_Bet_Size;        // Message value
    address Last_Player;          // Last player address
    uint256 Last_Win_Size;        // Last amount won
    uint256 Last_Winner_Bet;      // Last bet amount won
    address Last_Winner;          // Last Winner
    uint256 Highest_Donation_Bet; // Highest donation bet
    address Highest_Donator;      // Donator address
    uint256 Highest_Payout;       // Highest payout
    address Highest_Winner;       // Winner address
    // Under_the_Hood
    uint256 UtH_res;              // Reslut
    uint256 UtH_a;                // 'Random' value
    uint256 UtH_m;                // Modulus

    function Basics()
      constant returns (
                    uint256 Next_Payout_, // Next payout
                    uint256 Next_Donation_,
                    address foundation_)
    {
                  Next_Payout_   = this.balance/10/1000000000000000;
                    Next_Donation_ = this.balance*9/200/1000000000000000;
                    foundation_    = foundation;
    }

    function History()
     constant returns (
            uint256 Bets_total_number_,    // Number of bets
            uint256 Bets_since_last_win_,  // Number of bets since last win
            uint256 Sum_of_Payouts_,       // Sum pay out
            uint256 Sum_of_Donations_,     // Sum donations
            uint256 Last_Block_Number_,    // Last block
            uint256 Last_Bet_Size_,        // Message value
            address Last_Player_,          // Last player address
            uint256 Last_Win_Size_,        // Last amount won
        uint256 Last_Winner_Bet_,      // Last bet amount won
            address Last_Winner_,          // Last Winner
            uint256 Highest_Donation_Bet_, // Highest donation bet
            address Highest_Donator_,      // Donator address
            uint256 Highest_Payout_,       // Highest payout
            address Highest_Winner_)       // Winner address
    {
        Bets_total_number_   = Bets_total_number;
            Bets_since_last_win_ = Bets_since_last_win;
            Sum_of_Payouts_      = Sum_of_Payouts/1000000000000000;
            Sum_of_Donations_    = Sum_of_Donations/1000000000000000;
            Last_Block_Number_   = Last_Block_Number;
            Last_Bet_Size_       = Last_Bet_Size/1000000000000000;
            Last_Player_         = Last_Player;
            Last_Win_Size_       = Last_Win_Size/1000000000000000;
        Last_Winner_Bet_     = Last_Winner_Bet/1000000000000000;
            Last_Winner_         = Last_Winner;
            Highest_Donation_Bet_= Highest_Donation_Bet/1000000000000000;
            Highest_Donator_     = Highest_Donator;
            Highest_Payout_      = Highest_Payout/1000000000000000;
            Highest_Winner_      = Highest_Winner;
    }

    function Under_the_Hood()
    constant returns (
            uint256 UtH_res_,                  // Reslut
            uint256 UtH_a_,                    // 'Random' value
            uint256 UtH_m_)                    // Modulus
           {
            UtH_res_ = UtH_res;                // Reslut
            UtH_a_   = UtH_a;                  // 'Random' value
            UtH_m_   = UtH_m;                  // Modulus
    }

    function () {

      if (msg.value > 1000000000000000-1) {

      Bets_total_number    += 1;
      Bets_since_last_win  += 1;
      Last_Block_Number     = block.number;
      Last_Bet_Size         = msg.value;
      Last_Player           = msg.sender;

      if (msg.value > Highest_Donation_Bet){
          Highest_Donation_Bet = msg.value;
          Highest_Donator      = msg.sender;
      }

      UtH_a = UtH_a % block.timestamp + uint256(block.blockhash(block.number - 1));
      UtH_a = UtH_a + block.timestamp * block.difficulty * block.number + 1;
      UtH_a = UtH_a % 80100011001110010011000010110111001101011011110018;
      UtH_m = 10 + 10*1000000000000000000/msg.value;

      UtH_res = UtH_a % UtH_m;

      if (UtH_res == 0) {
        Bets_since_last_win = 0;
        Last_Win_Size    = this.balance/10;
        Last_Winner_Bet  = msg.value;
        Last_Winner      = msg.sender;
        if (this.balance/10 > Highest_Payout){
          Highest_Payout = this.balance/10;
          Highest_Winner = msg.sender;
        }

        Sum_of_Payouts += this.balance/10;
        msg.sender.send(this.balance/10);
        Sum_of_Donations += this.balance/20;
        foundation.send(this.balance/20);
      }
      }
    }
}

External Links