Files
carrotcoin/docs/blockchain.md
Lukas Fürderer e1fe8b0958 Reorder field in the block
Miners should choose a transaction from the network based on its reward,
not as part of the mining variability.
That's why it's a bad idea to place the transaction as last block element.

Reorder the fields to make less room for harmful mining optimization.
2024-03-17 09:54:00 +01:00

5.1 KiB

Protocol of the carrotcoin cryptocurrency

The carrotcoin cryptocurrency is a bitcoin-like currency with proof-of-work, created just for learning purposes.

Blockchain

The network should stabilize at around 1 block every 5 minutes.

Blocks are hashed with SHA256 and this hash needs to start with a certain number of zeros (or, more precise, be below a given value depending on the difficulty)

ed25519 keys are used to validate transactions.

block datastructure

content size (bytes)
transaction (optional) 148
message (arbitrary) 32
miner pubkey 32
previous hash 32
timestamp (unix time in seconds, BE) 8
difficulty sum (BE) 32
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.

transaction datastructure

1 carrotcoin (cc) consists of 100 cents

content size (bytes)
id (arbitrary) 4
sender (pubkey) 32
receiver (pubkey) 32
amount (BE, in cents) 8
transaction fee (BE, in cents, can be zero) 8
signature (signed by sender, over transaction fields before signature) 64

transactions

For every block, the miner gets a reward of 1,00 cc. (100 cents)

If a transaction is included, the following happens additionally:

  • The sender needs to pay "amount" + "transaction fee"
  • The receiver gets "amount"
  • The miner gets "transaction fee" on top of the reward.

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 block difficulty value is not directly stated in each block but can be calculated by subtracting the "difficulty sum" of the previous block from the "difficulty sum" of the current block.

To calculate the block difficulty value, the following blocks are relevant:

  • The current block for which to calculate the difficulty: [B-0]
  • The previous block: [B-1]
  • The block that is 10 steps back in the chain: [B-10]

Then apply the following formula: (The slash / means integer division)

D = [B-1].difficulty_sum - [B-10].difficulty_sum
T = [B-0].timestamp      - [B-10].timestamp
calculated_difficulty = D * 3000 / 9 / T

block_difficulty = max(calculated_difficulty, 2^28)

[B-0].difficulty_sum = [B-1].difficulty_sum + block_difficulty

Note the max() operation: A difficulty can never be lower than 2^28 (=268435456). This is a strict lower bound.

For the first block, the "difficulty sum" value is set to 2^29 but its actual difficulty value is only 2^28.

Early in the chain, for calculating the "difficulty sum" of the first 10 blocks, we make assumptions for blocks "before" the first block:

  • Each of these "before" blocks had a block difficulty of exactly 2^28
  • The timestamp difference between each two blocks before the first block is exactly 300 seconds.

validity

transaction

A transaction is valid if its signature is valid and it contains an 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.

transaction in a block

A transaction that is stored in a block must fulfill the following criteria (in addition to the valid signature):

  • There was never another transaction with the same ("id", "sender") pair anywhere in the block chain before.
  • 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.
    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.

block

A block is valid if all of the following criteria are fulfilled:

  • The "previous hash" field contains a SHA256 hash value of a previous valid block. (Or is completely filled with nullbytes, in case of the first block.)
  • The first block has a public key with the following SHA256 hash value:
    88023d392db35f2d3936abd0532003ae0a38b4d35e4d123a0fa28c568c7e3e2f
    The public key that matches this stated hash value will be kept secret until the launch day. Then it will be released along with the first block.
  • 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 "difficulty sum" must be precisely calculated, as specified in calculating difficulty
  • The "transaction" is either:
    • 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.
    See calculating difficulty what "block difficulty" means. (which is not directly given in the block.)