Describe the advanced blockchain that supports gambling

This commit is contained in:
2025-07-04 21:21:24 +02:00
parent 38c204cab2
commit fd6b5019ac

View File

@@ -2,6 +2,14 @@
The carrotcoin cryptocurrency is a bitcoin-like currency with proof-of-work, created just for learning purposes. The carrotcoin cryptocurrency is a bitcoin-like currency with proof-of-work, created just for learning purposes.
# The currency
One carrotcoin (abbreviated cc) consists of 100 cents. Internally, only cent amounts are processed using integer fields. The recommended notation for an amount is like in this example:
42.00 cc
(This would be processed internally as 4200 cents.)
# Blockchain # Blockchain
The network should stabilize at around 1 block every 5 minutes. The network should stabilize at around 1 block every 5 minutes.
@@ -14,7 +22,7 @@ ed25519 keys are used to validate transactions.
| content | size (bytes) | | content | size (bytes) |
|---|---| |---|---|
| transaction (optional) | 148 | | transaction | 149 |
| message (arbitrary) | 32 | | message (arbitrary) | 32 |
| miner pubkey | 32 | | miner pubkey | 32 |
| previous hash | 32 | | previous hash | 32 |
@@ -22,16 +30,28 @@ ed25519 keys are used to validate transactions.
| difficulty sum (BE) | 32 | | difficulty sum (BE) | 32 |
| nonce | 8 | | nonce | 8 |
If no transaction is included, its 148 bytes are all null.
The first block has a "previous hash" value of 32 null bytes. The first block has a "previous hash" value of 32 null bytes.
## transaction datastructure ## transaction datastructure
1 carrotcoin (cc) consists of 100 cents The first byte of a transaction describes the transaction type. The content of the following 148 bytes depend on the transaction type. The following transaction types are specified:
| transaction type | meaning |
|---|---|
| 0x00 | no transaction |
| 0x01 | payment transaction |
| 0x02 | gambling transaction |
| 0x03 | gambling reveal transaction |
### no transaction
All 149 bytes of the transaction field must be nullbytes. Nothing special happens.
### payment transaction
| content | size (bytes) | | content | size (bytes) |
|---|---| |---|---|
| transaction type (= 0x01) | 1 |
| id (arbitrary) | 4 | | id (arbitrary) | 4 |
| sender (pubkey) | 32 | | sender (pubkey) | 32 |
| receiver (pubkey) | 32 | | receiver (pubkey) | 32 |
@@ -39,16 +59,49 @@ The first block has a "previous hash" value of 32 null bytes.
| transaction fee (BE, in cents, can be zero) | 8 | | transaction fee (BE, in cents, can be zero) | 8 |
| signature (signed by sender, over transaction fields before signature) | 64 | | signature (signed by sender, over transaction fields before signature) | 64 |
## transactions ### gambling transaction
For every block, the miner gets a reward of 1,00 cc. (100 cents) | content | size (bytes) |
|---|---|
| transaction type (= 0x02) | 1 |
| id (arbitrary) | 4 |
| player (pubkey) | 32 |
| gambling amount (BE, in cents) | 8 |
| transaction fee (BE, in cents, can be zero) | 8 |
| signature (signed by player, over transaction fields before signature) | 64 |
| padding (nullbytes) | 32 |
If a transaction is included, the following happens additionally: ### gambling reveal transaction
| content | size (bytes) |
|---|---|
| transaction type (= 0x03) | 1 |
| revealer (pubkey) | 32 |
| associated revealing proof (hash) | 32 |
| padding (nullbytes) | 84 |
## impacts of blocks and transactions
For every block, the miner gets a reward of 1.00 cc. (100 cents)
If a payment transaction is included, the following happens additionally:
- The sender needs to pay "amount" + "transaction fee" - The sender needs to pay "amount" + "transaction fee"
- The receiver gets "amount" - The receiver gets "amount"
- The miner gets "transaction fee" on top of the reward. - The miner gets "transaction fee" on top of the reward.
If a gambling transaction is included, the following happens additionally:
- The player needs to pay "gambling amount" + "transaction fee"
If a gambling reveal transaction is included, the following happens additionally:
- The miner gets an additional reward of 1.00 cc (So together with the general block reward, he will get 2.00 cc)
- The revealer gets 15.00 cc
- Each winning player gets twice the gambling amount he played.
You find more technical details below in the section Gambling.
## calculating difficulty ## calculating difficulty
The "difficulty sum" field (included in each block) is the cumulative sum of all block difficulty values. The first block has a "difficulty sum" value of 2^29. The "difficulty sum" field (included in each block) is the cumulative sum of all block difficulty values. The first block has a "difficulty sum" value of 2^29.
@@ -82,18 +135,22 @@ Early in the chain, for calculating the "difficulty sum" of the first 10 blocks,
## validity ## validity
### transaction ### payment / gambling transaction
A transaction is valid if its signature is valid and it contains an amount of at least 1 cent (0,01 cc). A transaction is valid if its signature is valid and it contains an "amount" or "gambling amount" of at least 1 cent (0.01 cc).
The "signature" field must be an ed25519 signature over the concatenation of all previous fields (id + sender pubkey + receiver pubkey + amount + transaction fee), and must be valid when validated with the "sender" pubkey. The "signature" field must be an ed25519 signature over the concatenation of all fields before the signature and must be valid when validated with the "sender" or "player" pubkey.
### transaction in a block ### payment / gambling transaction in a block
A transaction that is stored in a block must fulfill the following criteria (in addition to the valid signature): A transaction that is stored in a block must also fulfill the following criteria:
- There was never another transaction with the same ("id", "sender") pair anywhere in the block chain before. - There was never another transaction with the same ("id", "sender") pair anywhere in the block chain before. This counts across both types, so if a tuple was used for a payment transaction for example, it can not be used again, neither for another payment nor for a gambling transaction.
- Following the balances in the block chain, the "sender" key has enough money for both payments (amount + transaction fee) before the mining reward (1,00 cc + transaction fee) is counted. - Following the balances in the block chain, the "sender" or "player" key has enough money for both payments ("amount" or "playing amount" + "transaction fee") before the mining reward (1.00 cc + transaction fee) is counted.
This means: A miner cannot create a block that mines money and at the same time contains a transaction that relies on this 1,00 cc reward being available. After mining money in one block, the following block is the earliest possibility to pay this fresh mined money. This means: A miner cannot create a block that mines money and at the same time contains a transaction that relies on this 1.00 cc reward being available. After mining money in one block, the following block is the earliest possibility to pay this fresh mined money.
### gambling reveal transaction
A gambling reveal transaction is only valid with a valid associated proof that needs to fulfill a few more conditions. More details in the section Gambling.
### block ### block
@@ -106,8 +163,144 @@ A block is valid if all of the following criteria are fulfilled:
- The "timestamp" field is greater than the timestamp of the previous block (if there is any). Equal timestamps are not allowed. - The "timestamp" field is greater than the timestamp of the previous block (if there is any). Equal timestamps are not allowed.
- The "timestamp" field is less than or equal to the current time. This needs to be decided by each node based on the local clock. - The "timestamp" field is less than or equal to the current time. This needs to be decided by each node based on the local clock.
- The "difficulty sum" must be precisely calculated, as specified in `calculating difficulty` - The "difficulty sum" must be precisely calculated, as specified in `calculating difficulty`
- The "transaction" is either: - The "transaction" must be valid as described above.
- Completely empty (148 nullbytes)
- or: A valid `transaction in a block` as described above.
- The SHA256 hash of the entire block, when interpreted as an BE integer, multiplied by the block difficulty, is less than 2^256. - The SHA256 hash of the entire block, when interpreted as an BE integer, multiplied by the block difficulty, is less than 2^256.
See `calculating difficulty` what "block difficulty" means. (which is not directly given in the block.) See `calculating difficulty` what "block difficulty" means. (which is not directly given in the block.)
# Gambling
The carrotcoin cryptocurrency has a built-in gambling feature where you play against the currency, not against a bank or casino. This means that lost money disappears while winnings are created from nowhere.
Technically, gambling happens in the following steps:
1. A user places a bet by investing an arbitrary amount of money. There is a 50/50 chance of either losing it completely or doubling the amount.
2. The gambling instruction is placed on the blockchain. The gambling amount is taken from the player's wallet for now.
3. About once a day (more precisely every 256 blocks) there is a gambling commitment block. It mathematically defines the outcomes of all gambling bets since the last gambling commitment block. But these outcomes are not known at this point in time, they need to be revealed first by evaluating a delay-function.
4. Miners can choose to perform a special "reveal mining" which means calculating the delay-function and generating a proof for the result.
5. Once a reveal miner finished his calculation, the reveal information is sent to the network along with the generated proof.
6. The reveal information is placed on the blockchain, the revealer gets a reward and every winning player gets his winnings.
## Gambling transaction
A user can create a gambling transaction at any time to participate in the gambling process. Such transactions are described above in the section "Blockchain" / "transaction datastructure" / "gambling transaction". The id and player fields (along with other information) will be used to calculate, if the player wins.
## Gambling commitment blocks
To find out which block is a gambling commitment block, you need to number all blocks of the blockchain. The first block (this is the one with 32 nullbytes in the "previous hash" field) gets block number 0. From there on, just count up. (The block number of a block is the block number of its previous block plus one.)
Every block with a block number of 255 (modulo 256) is a gambling commitment block. Its hash value will also be relevant to calculate, if a player wins.
## Decision of winning / losing
To calculate if a player wins or loses, you first need to evaluate a delay-function based on the hash value H of the corresponding gambling commitment block. The hash value is interpreted as a 32-byte integer, big endian. The delay function to produce the reveal value R is the following where "^" means exponentiation:
```
R = H ^ 2 ^ 2 ^ 30 % n
```
The number n is the RSA modulus of the DNSSEC root signing key KSK-2024 with the following value:
```
n = 22152137184697602751949152182712806144286735269755991212091578018969267364854563246965161398309375840488156997640625085213985729183180764348127989435514689722834129288342499703533613231239853168289771769536412763137391054558055082146752229593979328251181647873233949602834141648160681711983351545692646009424518816069561938917629523175464947983950548802679152115205735609960641453864298194702935993896839374645356040490091081577992299773430144650589605043643969140352237968606446474316247592579560197155686719175897498255683642121505357781103123719079205647707696181709515150954235402701095586525936356219917713227143
```
All values modulo n that are stored, hashed, transmitted or compared need to be less than n/2. If a calculated value is greater than n/2, it must be subtracted from n to produce a value less than n/2. This is relevant for the value R above, for example.
Once the reveal value R is known, it is converted to a 256-byte datablock, big endian, and for each player the following block is hashed with SHA256:
| content | size (bytes) |
|---|---|
| id (from gambling transaction) | 4 |
| player (from gambling transaction) | 32 |
| R | 256 |
If the hash value starts with bit "0" (the first byte is something in the range 0x00 - 0x7f), the player loses. If the hash value start with bit "1" (the first byte is something in the range 0x80 - 0xff), the player wins. Winning means, twice the amount played is put back onto the players wallet. Example:
A player has 20.00 cc.
He plays 10.00 cc with a transaction fee of 0.20 cc.
The player now has 9.80 cc left.
It is later revealed that the player won this gambling round.
The player now has a balance of 29.80 cc. (The transaction fee is always lost.)
## Revealing process
Reveal transactions need to be placed on the blockchain in their correct order. There is no field to indicate which gambling commitment block a reveal transaction is meant for. It must always be for the oldest not yet revealed gambling commitment block.
The following proof was taken from [A Survey of Two Verifiable Delay Functions](https://eprint.iacr.org/2018/712), a paper by Dan Boneh, Benedikt Bünz, and Ben Fisch. They call it "Pietrzaks succinct argument". On page 10, the reason is given why every number must be less than n/2.
Krzysztof Pietrzak describes the proof first in [Simple Verifiable Delay Functions](https://eprint.iacr.org/2018/627).
## Validating a reveal transaction
A gambling reveal transaction contains a hash value of an "associated revealing proof". This proof is a 5376 byte datastructure that needs to be transmitted along the block to be verified as part of the blockchain. It contains the following fields:
| content | size (bytes) |
|---|---|
| R (BE) | 256 |
| I_0 to I_19 (20 values, each BE) | 20 * 256 = 5120 |
Remember that every stored number modulo n must be less than n/2. This is also true for the values I_0 to I_19.
The values I_0 to I_19 are intermediate values that represent an interactive proof that was made non-interactive by using a hash functions. It works in the following way:
The prover wants to show that H, squared 2^i times, modulo n, results in the value R. For example with i=30, we write this in the following way:
```
H -> square[2^30] -> R
```
To prove that, he needs to provide the intermediate value I, that was the result after half the number of squaring steps. (In this example 2^29 steps.)
```
H -> square[2^29] -> I -> square[2^29] -> R
```
The four parameters H, I, R, i are now put into one datastructure and hashed using SHA256:
| content | size (bytes) |
|---|---|
| revealer (pubkey) | 32 |
| H (BE) | 256 |
| I (BE) | 256 |
| R (BE) | 256 |
| i | 1 |
The resulting hash value is then interpreted as a 256-bit number e, big endian.
The prover divided his claim into two sub-claims:
```
H -> square[2^29] -> I
I -> square[2^29] -> R
```
They are now combined into one claim using a combination function:
```
(H * I^e % n) -> square[2^29] -> (I * R^e % n)
```
You can see that this reduction step produced new start and end values H' and R':
```
H' = H * I^e % n
R' = I * R^e % n
```
This reduction step is done 20 times in total as summarized in the following table:
| i value | claim | reduced claim | I value to use |
|---|---|---|---|
| 30 | H -> square[2^30] -> R | H_1 -> square[2^29] -> R_1 | I_0 |
| 29 | H_1 -> square[2^29] -> R_1 | H_2 -> square[2^28] -> R_2 | I_1 |
| ... | ... | ... | ... |
| 12 | H_18 -> square[2^12] -> R_18 | H_19 -> square[2^11] -> R_19 | I_18 |
| 11 | H_19 -> square[2^11] -> R_19 | H_20 -> square[2^10] -> R_20 | I_19 |
The final claim (that H_20 squared 2^10 (= 1024) times results in R_20) can be verified by each node directly.
To sum it up, a node needs to verify the following for each gambling reveal transaction:
1. The hash in the transaction must be the correct hash value for the associated proof block.
2. The value R and each value I_0 to I_19 must be greater than zero and less than n/2.
3. The final claim (H_20 -> square[2^10] -> R_20) must be true.