The Oraclize SimpleDice example, a one wei dice game that asks WolframAlpha for a number between 1 and 6.
Context
Deployed 28 November 2015, during the Frontier era.
Key Facts
Description
The SimpleDice example from oraclize/ethereum-examples, whose contract is named Lottery, deployed with the Oraclize API of the day inlined above it. bet throws unless exactly one wei is sent and the contract already holds at least two, then rollDice sends an Oraclize query for a WolframAlpha random number between 1 and 6 and records the caller against the query id. __callback rejects any caller that is not the Oraclize callback address, reads the first character of the returned string, subtracts 48 to turn it into a digit, and sends two wei to the bettor if it is above 3. The payout uses send and ignores its result, and nothing clears the recorded bet, so a bettor whose send fails has no way to retry. kill lets the deployer self destruct the contract at any time. Its Oraclize resolver is the address resolver at 0x1d11e5eae3112dbd44f99266872ff1d07c77dce8.
Source Verified
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 (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
// <ORACLIZE_API>
/*
Copyright (c) 2015 Oraclize srl, Thomas Bertani
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
contract OraclizeI {
address public cbAddress;
function query(uint _timestamp, string _datasource, string _arg) returns (bytes32 _id);
function query_withGasLimit(uint _timestamp, string _datasource, string _arg, uint _gaslimit) returns (bytes32 _id);
function query2(uint _timestamp, string _datasource, string _arg1, string _arg2) returns (bytes32 _id);
function query2_withGasLimit(uint _timestamp, string _datasource, string _arg1, string _arg2, uint _gaslimit) returns (bytes32 _id);
function getPrice(string _datasource) returns (uint _dsprice);
function getPrice(string _datasource, uint gaslimit) returns (uint _dsprice);
function useCoupon(string _coupon);
function setProofType(byte _proofType);
}
contract OraclizeAddrResolverI {
function getAddress() returns (address _addr);
}
contract usingOraclize {
uint constant day = 60*60*24;
uint constant week = 60*60*24*7;
uint constant month = 60*60*24*30;
byte constant proofType_NONE = 0x00;
byte constant proofType_TLSNotary = 0x10;
byte constant proofStorage_IPFS = 0x01;
OraclizeI oraclize;
modifier oraclizeAPI {
OraclizeAddrResolverI OAR = OraclizeAddrResolverI(0x1d11e5eae3112dbd44f99266872ff1d07c77dce8);
oraclize = OraclizeI(OAR.getAddress());
_
}
modifier coupon(string code){
OraclizeAddrResolverI OAR = OraclizeAddrResolverI(0x1d11e5eae3112dbd44f99266872ff1d07c77dce8);
oraclize = OraclizeI(OAR.getAddress());
oraclize.useCoupon(code);
_
}
function oraclize_query(string datasource, string arg) oraclizeAPI internal returns (bytes32 id){
return oraclize.query.value(oraclize.getPrice(datasource))(0, datasource, arg);
}
function oraclize_query(uint timestamp, string datasource, string arg) oraclizeAPI internal returns (bytes32 id){
return oraclize.query.value(oraclize.getPrice(datasource))(timestamp, datasource, arg);
}
function oraclize_query(uint timestamp, string datasource, string arg, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
return oraclize.query_withGasLimit.value(oraclize.getPrice(datasource, gaslimit))(timestamp, datasource, arg, gaslimit);
}
function oraclize_query(string datasource, string arg, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
return oraclize.query_withGasLimit.value(oraclize.getPrice(datasource, gaslimit))(0, datasource, arg, gaslimit);
}
function oraclize_query(string datasource, string arg1, string arg2) oraclizeAPI internal returns (bytes32 id){
return oraclize.query2.value(oraclize.getPrice(datasource))(0, datasource, arg1, arg2);
}
function oraclize_query(uint timestamp, string datasource, string arg1, string arg2) oraclizeAPI internal returns (bytes32 id){
return oraclize.query2.value(oraclize.getPrice(datasource))(timestamp, datasource, arg1, arg2);
}
function oraclize_query(uint timestamp, string datasource, string arg1, string arg2, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
return oraclize.query2_withGasLimit.value(oraclize.getPrice(datasource, gaslimit))(timestamp, datasource, arg1, arg2, gaslimit);
}
function oraclize_query(string datasource, string arg1, string arg2, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
return oraclize.query2_withGasLimit.value(oraclize.getPrice(datasource, gaslimit))(0, datasource, arg1, arg2, gaslimit);
}
function oraclize_cbAddress() oraclizeAPI internal returns (address){
return oraclize.cbAddress();
}
function oraclize_setProof(byte proofP) oraclizeAPI {
return oraclize.setProofType(proofP);
}
function parseAddr(string _a) internal returns (address){
bytes memory tmp = bytes(_a);
uint160 iaddr = 0;
uint160 b1;
uint160 b2;
for (uint i=2; i<2+2*20; i+=2){
iaddr *= 256;
b1 = uint160(tmp[i]);
b2 = uint160(tmp[i+1]);
if ((b1 >= 97)&&(b1 <= 102)) b1 -= 87;
else if ((b1 >= 48)&&(b1 <= 57)) b1 -= 48;
if ((b2 >= 97)&&(b2 <= 102)) b2 -= 87;
else if ((b2 >= 48)&&(b2 <= 57)) b2 -= 48;
iaddr += (b1*16+b2);
}
return address(iaddr);
}
function strCompare(string _a, string _b) internal returns (int) {
bytes memory a = bytes(_a);
bytes memory b = bytes(_b);
uint minLength = a.length;
if (b.length < minLength) minLength = b.length;
for (uint i = 0; i < minLength; i ++)
if (a[i] < b[i])
return -1;
else if (a[i] > b[i])
return 1;
if (a.length < b.length)
return -1;
else if (a.length > b.length)
return 1;
else
return 0;
}
function indexOf(string _haystack, string _needle) internal returns (int)
{
bytes memory h = bytes(_haystack);
bytes memory n = bytes(_needle);
if(h.length < 1 || n.length < 1 || (n.length > h.length))
return -1;
else if(h.length > (2**128 -1))
return -1;
else
{
uint subindex = 0;
for (uint i = 0; i < h.length; i ++)
{
if (h[i] == n[0])
{
subindex = 1;
while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex])
{
subindex++;
}
if(subindex == n.length)
return int(i);
}
}
return -1;
}
}
function strConcat(string _a, string _b) internal returns (string) {
bytes memory ba = bytes(_a);
bytes memory bb = bytes(_b);
bytes memory bc = " ";
uint k = 0;
for (uint i = 0; i < ba.length; i ++){
bc[k] = ba[i];
k++;
}
for (i = 0; i < bb.length; i ++){
bc[k] = bb[i];
k++;
}
for (i = k; i < bc.length; i ++){
bc[i] = 0;
}
return string(bc);
}
// parseInt
function parseInt(string _a) internal returns (uint) {
bytes memory bresult = bytes(_a);
uint mint = 0;
for (uint i=0; i<bresult.length; i++){
if ((bresult[i] >= 48)&&(bresult[i] <= 57)){
mint *= 10;
mint += uint(bresult[i]) - 48;
} else break;
}
return mint;
}
// parseInt(parseFloat*10^_b)
function parseInt(string _a, uint _b) internal returns (uint) {
bytes memory bresult = bytes(_a);
uint mint = 0;
bool decimals = false;
for (uint i=0; i<bresult.length; i++){
if ((bresult[i] >= 48)&&(bresult[i] <= 57)){
if (decimals){
if (_b == 0) break;
else _b--;
}
mint *= 10;
mint += uint(bresult[i]) - 48;
} else if (bresult[i] == 46) decimals = true;
}
return mint;
}
}
// </ORACLIZE_API>
contract Lottery is usingOraclize {
address owner;
mapping (bytes32 => address) bets;
function Lottery(){
owner = msg.sender;
}
function __callback(bytes32 myid, string result) {
if (msg.sender != oraclize_cbAddress()) throw;
if (uint(bytes(result)[0]) - 48 > 3) bets[myid].send(2);
}
function bet(){
if ((msg.value != 1)||(this.balance < 2)) throw;
rollDice();
}
function rollDice() {
bytes32 myid = oraclize_query(0, "WolframAlpha", "random number between 1 and 6");
bets[myid] = msg.sender;
}
function kill(){
if (msg.sender == owner) suicide(msg.sender);
}
}External Links
Related contracts
ITABIT_EUR
Same deployerEuro denominated ledger token at two decimals, issued to a separate minter account.
0x95ec93...3bb35dDecember 15, 2015Contract 0x177283...4664aa
Same eraAn early on-chain lottery contract deployed on Frontier by the prolific 0xFD2605 deployer cluster.
0x177283...4664aaAugust 10, 2015Roulette
Same eraAn early Ethereum roulette contract from August 2015, notable for a critical randomness vulnerability: its 'private' seed is hardcoded to 1 in the constructor.
0x5fe5b7...25a4fdAugust 10, 2015Prediction Market
Same eraLMSR prediction market (Aug 2015 – Jun 2016, 662 ETH). 11/25 selectors byte-exact, 14/25 semantic reconstructions.
0x2935aa...7a9085August 23, 2015