Protocol documentationSource snapshot: 0.1.0 alphaNetwork: testnet / devnet

Core protocol

PoW, difficulty & emission

Proof-of-work comparison, compact target arithmetic, 480-block retargets, miner interruption, subsidy halvings, fees, and permanent tail emission.

Consensus-critical arithmetic · alpha economicsReviewed August 31, 2026
Specification status

This page documents the implemented alpha. Executable source, interoperability vectors, and tests remain authoritative if prose and code ever diverge.

Proof-of-work rule

Luracoin uses double SHA-256 proof of work over the canonical block-ID preimage. A candidate is valid when:

target = compact_to_target(block.bits)
target > 0
integer(block.id, big_endian) <= target

The block ID already commits to version, predecessor, height, miner, timestamp, bits, nonce, transaction count, and every complete transaction. Changing any of these fields requires new work.

Equality is accepted. Treating the comparison as strict < creates an interoperability bug at the boundary.

Compact bits representation

bits is exactly four bytes:

bits = exponent_u8 || coefficient_be_u24

Expansion is:

if exponent <= 3:
    target = coefficient >> (8 × (3 - exponent))
else:
    target = coefficient << (8 × (exponent - 3))

The expanded target must fit in 256 bits. A zero target is never a valid proof. The current starting value is:

1dffffff

The easiest permitted retarget target is derived from:

1fffffff

These bytes are protocol constants, not human-readable floating-point “difficulty.” Explorers should display the compact value exactly and may derive presentation metrics separately.

Compact encoding of a new target

After integer retarget arithmetic, the implementation converts a positive target back to four bytes by:

  1. encoding the integer as the shortest unsigned big-endian byte string;
  2. setting the exponent to that byte length;
  3. using the first three bytes as coefficient when the length is at least three;
  4. right-padding with zero bytes when it is shorter;
  5. discarding lower-order bytes beyond the leading three.

This is the implemented canonicalization. Independent nodes must reproduce its truncation behavior exactly; importing another cryptocurrency’s signed-mantissa edge rules without testing is unsafe.

Expected bits by height

Difficulty is derived from local canonical history:

height 0                    -> STARTING_DIFFICULTY
height not divisible by 480 -> previous.bits
height divisible by 480     -> retarget(previous.bits, interval timestamps)

At a retarget height H, the time span is:

actual_time   = block[H - 1].timestamp - block[H - 480].timestamp
expected_time = 480 × 180 = 86,400 seconds

Notice that the endpoints are H - 480 and H - 1, as implemented. Do not silently substitute a 480-edge or median-time window.

If the previous block or the interval’s first block is unavailable, expected-difficulty calculation fails closed. The node never guesses a target from a peer advertisement.

Retarget equation

The time span is clamped before scaling:

minimum = expected_time / 4 = 21,600 seconds
maximum = expected_time × 4 = 345,600 seconds

clamped_time = min(max(actual_time, minimum), maximum)
new_target   = old_target × clamped_time // expected_time
new_target   = min(new_target, maximum_target)

Integer floor division is consensus-critical. No floating-point arithmetic is used.

Interpretation:

  • blocks four times faster than expected can make the target at most four times smaller in one adjustment;
  • blocks four times slower can make it at most four times larger;
  • more extreme spans are clamped to the same boundaries;
  • the maximum target prevents retargeting beyond the easiest permitted work.

The block’s bits must byte-for-byte equal the locally calculated value. A target that is numerically similar but has a different compact representation is rejected.

Timestamp influence and limits

Every accepted non-genesis block timestamp must be:

timestamp > predecessor.timestamp
timestamp <= validating_node_clock + 500 seconds

Difficulty uses those accepted timestamps directly. There is no median-time-past calculation in the alpha. The strict-monotonic rule and future limit constrain individual values but do not eliminate miner influence over interval timing.

Operators should synchronize system time. Protocol designers should treat timestamp manipulation and the absence of robust fork choice as unresolved public-network risks.

Mining loop

The reference miner creates a template, sets nonce zero, and increments the 32-bit nonce until the block ID meets the target:

nonce = starting_at
while block_id(nonce) > target:
    nonce += 1

The search returns -1 when:

  • an optional stop event is observed;
  • nonce reaches 0xffffffff without a valid result.

The stop event is checked every 1,000 iterations. This lets a newly accepted peer block interrupt stale work without paying synchronization overhead on every hash.

If the nonce space is exhausted, the miner must rebuild or otherwise vary a committed field such as timestamp or transaction set. Nonce wraparound is not allowed.

Template construction

For height H, the built-in miner:

  1. reads the current tip and predecessor ID;
  2. selects contextually valid transactions from Redis;
  3. sums their fees;
  4. creates a height-bound coinbase for subsidy(H) + fees;
  5. inserts coinbase at index zero;
  6. sets version 1 and the canonical predecessor;
  7. sets timestamp to the greater of current Unix time and predecessor time plus one;
  8. derives the only valid bits value from chain history;
  9. searches from nonce zero.

After solving, the miner rechecks that the template still extends the current tip. A stale result is discarded rather than appended.

Transaction selection policy—fee descending with transaction-ID tie-breaking—is deterministic for a captured mempool view, but it is not a block-validity requirement. Another miner may include a different valid order and set.

Units and initial allocation

Consensus represents money as integers:

1 LURA = 100,000,000 lurashis

The recurring initial subsidy is:

50 LURA = 5,000,000,000 lurashis

The educational genesis allocation is:

100,000 LURA = 10,000,000,000,000 lurashis

Genesis ownership material is known in the alpha networks. It has no production monetary meaning.

Halving schedule

The subsidy function is:

era      = height // 259,200
shifted  = 5,000,000,000 >> era
subsidy  = max(shifted, 100,000,000)

Representative boundaries:

Height range Era Subsidy
0–259,199 0 50 LURA
259,200–518,399 1 25 LURA
518,400–777,599 2 12.5 LURA
777,600–1,036,799 3 6.25 LURA
1,036,800–1,295,999 4 3.125 LURA
1,296,000–1,555,199 5 1.5625 LURA
1,555,200 onward 6+ 1 LURA tail floor

The exact implementation works in lurashis, so odd integer values are truncated by the right shift. The floor activates once the shifted value would fall below 100,000,000 lurashis.

The height-zero genesis amount is controlled by the manifest, not by blindly applying the first row of the recurring schedule. For all non-genesis blocks, the subsidy equation is exact.

Permanent tail emission

Unlike a capped-supply schedule, Luracoin defines a permanent minimum subsidy:

TAIL_REWARD = 1 LURA per block

Once the halving result reaches or crosses that floor, every later block continues creating at least one LURA, plus collected fees. Total supply is therefore not finite under the implemented economics.

Documentation, wallets, and explorers must not claim a fixed maximum supply. Any monetary-policy change would be consensus-breaking and would require a deliberate network/version transition.

Fees and miner payment

Each normal transaction carries an explicit uint32 fee in lurashis. The valid coinbase value is:

subsidy(height) + Σ(normal_transaction.fee)

Fees are debited from senders during the ordered normal transition and credited only through coinbase afterward. A fee is not a separate output and cannot name a different recipient.

Coinbase value, fee sums, account debits, and credits are checked against integer domains. Overflow invalidates the block; arithmetic must never wrap.

What difficulty does not provide yet

Valid proof demonstrates that a candidate ID is under its target. In the current alpha it does not supply a complete decentralized consensus system because nodes do not compare cumulative work across branches.

Missing pieces include:

  • chain-work accumulation;
  • competing-header validation and storage;
  • fork-choice rules;
  • reorganization-safe state transitions;
  • stale-block and orphan handling;
  • adversarial time-warp analysis;
  • production-calibrated starting difficulty and network hashrate policy.

Do not derive “security,” “finality,” or economic value solely from the presence of a proof-of-work loop.

Conformance tests

Cross-language implementations should test:

  • expansion for exponents below, equal to, and above three;
  • zero, overflow, and maximum targets;
  • id == target acceptance;
  • exact non-boundary carry-forward of bits;
  • retarget at height multiples of 480;
  • both clamp boundaries and exact boundary values;
  • integer truncation during target scaling and compact re-encoding;
  • missing-history failure;
  • nonce 0xffffffff exhaustion;
  • stop-event interruption;
  • every subsidy boundary and the permanent one-LURA floor;
  • coinbase equality to subsidy plus all included fees.

The reference tests are part of the protocol evidence. A prose-equivalent formula is not enough if it serializes a different four-byte result.

Source anchors

Primary implementation files used for this chapter: