Featured

Provably-Fair Jackpots

DATA AND CONTRACT TRANSPARENCY

Everyworld is committed to the highest standards of transparency and fairness in the selection of jackpot winners. The system is designed to be provably fair, utilizing blockchain technology to ensure that all participants can verify the integrity and fairness of each jackpot.A diagram is provided below to help visualize the mechanism:


1. S3 Data Storage: Drawing and calculation data relevant to Everyworld jackpots are stored in a publicly accessible S3 bucket. This allows any participant to verify the data used in the drawing process. The URLs to access this data are provided below, using the May 14, 2024 jackpot as an example:

2. Blockchain Verification: Everyworld uses a smart contract to manage and verify jackpot metadata. This contract is deployed on Base and its code is verified for transparency. Additionally, a version of the contract is also available on the Base Sepolia testnet.

3. Checksum Verification: After uploading the drawing data to the S3 bucket, Everyworld generates a SHA-256 hash of the content. This hash, along with the creation time of the document, is recorded on the blockchain via the JackpotMetadata contract, providing a timestamped and immutable record. To verify the integrity of the data, use this tool:

PUBLISHING METADATA AND WINNER SELECTION

1. Metadata Publishing: Throughout the drawing period, participants can earn tickets for various activities, such as engaging with content in the Everyworld web app or holding $EVERY tokens. At the end of the drawing period, Everyworld compiles a list of all participants, with each entry in the CSV file detailing the user ID and the total number of tickets that user has earned. This structured data ensures that every ticket has an equal chance of winning relative to the number of tickets held by each user. The finalized CSV is then uploaded to the public S3 bucket.

2. Provably Fair Winner Selection:some text

  • Data Formatting: Before selecting a winner, the data is formatted to facilitate weighted randomness in the drawing process. This means organizing the data so that the number of tickets each user holds is represented continuously in the dataset. For example, if User A has 4 tickets and User B has 2, the entries might appear as follows in the drawing data:


Javascript

{

0: User,

4: UserB,

6: UserC

...

}

3. Random Selection: A random number is generated using a seed derived from the hash of the subsequent Ethereum block after the data upload. This high-entropy method ensures the drawing is tamper-proof. The random number directly determines the winner by indexing into the structured user-ticket data, allowing each participant a fair chance based on the number of tickets held.


VERIFICATION PROCESS

Participants and observers can independently verify the winner by following these steps:

  1. Access the drawing data from the S3 URLs.
  2. Calculate the SHA-256 hash of the downloaded data.
  3. Compare the hash from the S3 upload with the one recorded on the blockchain.
  4. Review the structured ticket data and the blockchain-derived random seed to independently ascertain the winner.

REPRODUCIBLE RNG USING SEED

Everyworld provides the following sample code to assist with the verification process.

import pandas as pd

import numpy as np

import requests

WINNER_SELECTION_MANIFEST = 'https://cdn.prod.everyworld.com/jackpots/s2d6/s2d6-calculation-results-1715700712596.txt'

USER_TICKETS_MANIFEST='https://cdn.prod.everyworld.com/jackpots/s2d6/s2d6-entries-1715700664756.csv'

def get_winner_data():

# Fetch the data

response = requests.get(WINNER_SELECTION_MANIFEST)

data_dict=None

if response.status_code == 200:

data = response.text

# Parse the string to create a dictionary

data_dict = {}

for line in data.strip().split('\n'):

key, value = line.split(':', 1) # Split only at the first colon

data_dict[key.strip()] = value.strip()

return data_dict

def get_random_index_from_hash_numpy(hash_hex, array_size):

# Convert hash to an integer

seed = int(hash_hex, 16)

# Initialize the randomgen generator with the seed

rng = np.random.default_rng(seed)

# Generate a single random integer from 0 to 99

random_int = rng.integers(0, array_size)

return random_int

def getNumTickets():

data = pd.read_csv(USER_TICKETS_MANIFEST)

num_tickets = sum(data['entries'])

return num_tickets

winner_data = get_winner_data()

print("winner_data=", winner_data)

num_tickets = getNumTickets()

print("num_tickets=", num_tickets)

random_index = get_random_index_from_hash_numpy(winner_data["block_hash_used"], num_tickets)

print("ticket index from winner_data file=", winner_data["ticket_index"])

print("ticket index verified =", random_index)

if random_index == int(winner_data["ticket_index"]):

print("Winner ticket verified")

else:

print("Winner ticket not verified")

SUMMARY OF ARTIFACTS:

Wallet address that is owner of JackpotMetadata contract:

0x085F788da51D82cA8AB67D7eC269c29312e970A5

JackpotMetadata Base (verified):

https://basescan.org/address/0xdeba89f0B0606b0B26a0522b3Bd262C37B381eCa

JackpotMetadata Base Sepolia (verified):

https://sepolia.basescan.org/address/0xe8255A51c9eFC3F740895D803fFFe001812769DC

User-Ticket Manifest

https://cdn.prod.everyworld.com/jackpots/s2d6/s2d6-entries-1715700664756.csv

Winner-Selection Manifest

https://cdn.prod.everyworld.com/jackpots/s2d6/s2d6-calculation-results-1715700712596.txt