Fee Accounting
During execution
Every transaction pays gasUsed × effectiveGasPrice, where effectiveGasPrice = baseFee + min(tip, feeCap − baseFee). On Ethereum the base fee part is burned and only the tip goes to the coinbase. On NetZero Chain both parts go to the coinbase, and the coinbase of every block is the fee sink 0x0000000000000000000000000000000000001006.
At the end of the block
The consensus engine's Finalize step:
- Reads the fee sink balance
Fand sets it to zero. - Credits
F × 50%to the Carbon Fund0x…1001. - Puts
F × 40%into the miner pool. - Credits the remainder (10%) to the proposing validator's address (seat from
extraData). - If the Incentive Pool
0x…1002holds at least 0.05 USDn, moves 0.05 USDn from it into the miner pool. - Splits the miner pool equally over the block's mining shares and credits each miner directly; rounding dust, and the whole pool when the block carries no shares, goes to the proposer.
Percentages are basis points in the chain config (5000 / 4000 / 1000). Integer division rounds down at each step; the proposer receives every rounding remainder so no wei is lost. nzc_shares(blockNumber) reports the per-share amount a block paid.
Reproducing a block's Carbon Fund credit
from web3 import Web3
w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))
CARBON = "0x0000000000000000000000000000000000001001"
def fees_of(block_number):
b = w3.eth.get_block(block_number, full_transactions=True)
total = 0
for tx in b.transactions:
r = w3.eth.get_transaction_receipt(tx.hash)
total += r.gasUsed * r.effectiveGasPrice
return total
n = 74
fees = fees_of(n)
before = w3.eth.get_balance(CARBON, n - 1)
after = w3.eth.get_balance(CARBON, n)
assert after - before == fees * 5000 // 10000
print("block", n, "fees", fees / 1e18, "USDn → carbon", (after - before) / 1e18)On the testnet, a block with 300 transfers at the base fee floor carries 6.3063 USDn in fees and credits 3.15315 USDn to the Carbon Fund. Because the fee sink is swept every block, its balance is always zero at block boundaries; an intermediate non-zero balance is never observable through RPC.
Why the split is in the engine, not a contract
A contract can be paused, upgraded, or simply not called. Finalize runs on every node for every block; a block whose state root does not reflect the split is rejected by everyone. The split therefore has the same strength as the block validity rules themselves. Changing it means a hard fork that every operator adopts knowingly.
Incentive Pool accounting
The pool is a plain balance funded at genesis on the testnet (1,000,000 test-USDn, 0.05 per block, about 69 days at full production). On mainnet it is a contract the company tops up; its balance and burn rate are the public measure of how much mining is subsidised.
What the explorer shows
The explorer's Climate impact panel uses only public on-chain data:
| Figure | Source |
|---|---|
| CO₂ removed from the atmosphere | CDRT.totalRetired(): tonnes whose credits were retired in the vault after a burn |
| Removals in custody | CDRT.totalSupply(): tonnes currently backed in the vault (totalMinted() shows the lifetime total) |
| Carbon Fund balance | eth_getBalance(0x…1001) |
| Removals this can fund | fund balance × 60 % ÷ $25/t (business-case assumptions; an estimate, labelled as such) |
| Per block "→ carbon" | gasUsed × baseFeePerGas ÷ 2 (tips excluded, so it slightly understates) |
Until the CDRT contract is deployed on the testnet, the first two show "—". Testnet USDn is test money; nothing is purchased or retired on the testnet.
