Skip to content

Latest commit

Β 

History

49 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Bitcoin Federated Time (BFT)

Prefer your time with tea? There is a second telling of this clock β€” the Hatter's, down in Degen Wonderland. Same math, more madness. Follow the white rabbit. πŸŽ©πŸ‡

A block height is a timestamp no authority can edit. This is a tiny, dependency-free Python library that reads a Bitcoin block height as time β€” three honest ways, plus one sidebar:

  1. The clock β€” the hh:mm block-beat: a BFT day is 144 blocks on a 24-hour face, 6 blocks an hour, ten "minutes" a block β€” and yes, seconds: they ride the Pac ring. seconds = time since the last block, mod 60 β€” Pac laps once a minute, so his angle Γ· 6Β° is the seconds hand (a live ~estimate, like all sub-block time). The face people read.
  2. A calendar β€” 13 perfect 28-day months, counted purely in blocks: 0018.04.20 aβ‚Ώ.
  3. The countdowns β€” the inverse of the block count: blocks remaining to the next difficulty retarget, the next halving, the next cycle, and the last satoshi (~year 2140).
  4. (sidebar) The ordinal degree notation AΒ°Bβ€²Cβ€³D‴, which ordinal theory labels hour/minute/second/third β€” real sat-collector lore, honestly framed as indices, not clock time.

And a bridge from the calendar you were handed: enter any Gregorian date and time and get it back in Bitcoin time β€” with dates before the 2009 genesis block winding the clock backward into Before Bitcoin.

BFT also reads as Byzantine Fault Tolerance β€” which is the point. The network agrees on the height, so it agrees on the time. No almanac, no leap-second committee, no pope deleting ten days. The longest chain is the clock.

The hidden reading of "BTC" β†’ Bitcoin Time Clock

The ticker is, and only is, Bitcoin. But every block is a tick, and the chain keeps a steadier count than any wall clock β€” so we gave the count a face. Call it the Bitcoin Time Clock if you like; that's a lens, not a claim about the ticker.

Install

Zero dependencies, Python 3.9+.

pip install bitcoin-federated-time      # once published
# or vendor it right now: copy the bft/ folder into your project

Quick start

python -m bft 958346     # the whole clock in your terminal β€” plus today's feast days
python -m bft 1983-06-13 # a birthday (bβ‚Ώ before genesis)
import bft

bft.block_beat(958_346)["hhmm"]  # '04:20'                (the canonical hh:mm face)
bft.format_date(958_346)         # '0018.04.20 aβ‚Ώ'        (the β‚Ώ-marked bitcoin date)
bft.halving(958_346)             # {'epoch': 4, 'subsidy_btc': 3.125, 'blocks_to_next_halving': 91654}
bft.countdown(958_346)           # {'to_halving': 91654, 'to_last_satoshi': 5971654, ...}
bft.holidays.next_holidays(958_346, 3)   # the chain's coming feast days (docs/bitcoin-holidays.md)

print("\n".join(bft.format_clock(958_346)))
# Bitcoin Time Clock β€” block 958,346
#   Clock (hh:mm):    04:20   (beat 26/144 Β· 6 blocks an hour Β· ten minutes a block)
#   Date (BFT):       0018.04.20 aβ‚Ώ   (AB 18 Β· M04 Β· D20)
#   Level:            475  Β·  re-tunes in 1,270 blocks
#   Halving epoch:    4  Β·  subsidy 3.125 BTC  Β·  56.4% through
#   Cycle:            0  Β·  76.1% through  Β·  301,654 blocks to the next conjunction
#   Counting down:    1,270 β†’ retarget  Β·  91,654 β†’ halving  Β·  5,971,654 β†’ the last sat
#   Ordinal sidebar:  0Β°118346β€²746β€³0‴   (degree notation, for the sat collectors β€” ordinal
#                     indices, not clock time; first sat: uncommon)

Your birthday in Bitcoin time

bft.from_gregorian(1995, 6, 15, 12, 0)   # a Gregorian UTC birthday β†’ the full clock
# {'height': -712982, 'before_bitcoin': True, 'estimate': True, 'calendar': {...}}
bft.format_date(bft.height_at(1995, 6, 15))   # '0013.08.24 bβ‚Ώ'  β€” before genesis, same format
bft.format_date(bft.height_at(2015, 7, 20))   # '0006.08.09 aβ‚Ώ'

Born before 2009-01-03? Your height is negative and the clock runs in reverse β€” Before Bitcoin. Born after? You get an aβ‚Ώ date and your place on the clock. It's an estimate (see honesty notes) β€” the model dates you at a steady 10-minute block.

The readings

1. The clock β€” hh:mm block-beat

The canonical face. All of it is chain-exact β€” two nodes at the same height show the same time:

Piece Formula Range
beat height mod 144 0–143 (the block within the BFT day)
hh beat // 6 0–23 (the block-hour)
mm (beat mod 6) Γ— 10 00, 10, 20, 30, 40, 50
ones of minutes floor(block-age / 60), capped at 9 how full the current block is, in tenths β€” ~
seconds the Pac-ring formula: block-age mod 60 β€” Pac laps once a "minute", so his angle Γ· 6Β° IS the seconds hand 0–59 β€” ~

Six blocks an hour, ten minutes a block, no second digits on the cards β€” the chain-exact face is calm on purpose (see "the long view"). The live column is honest about being a guess: the minute-ones digit is the current block filling in tenths, and the seconds are read off the ring β€” both estimated from wall time since the last block, both wearing the ~, because the chain hasn't vouched for that page yet.

2. The calendar

  • Epoch: the genesis block (height 0, 2009-01-03) starts the clock. Heights β‰₯ 0 are After Bitcoin (aβ‚Ώ); negatives are Before Bitcoin (bβ‚Ώ), the inverse.
  • The date: yyyy.mm.dd aβ‚Ώ, marker after, year zero-padded to four β€” the display year is bitcoin's age (genesis opens 0000). Before Bitcoin reads identically: yyyy.mm.dd bβ‚Ώ β€” one order, both epochs.
  • Units: day = 144 blocks Β· week = 1,008 Β· fortnight = 2,016 (one difficulty period) Β· month = 4,032 (two difficulty periods) = 28 days Β· year = 52,416 (26 periods) = 364 days.
  • 13 months of 28 days = 364 days. No leap hacks, no intercalary day. It drifts ~1.24 days/year against the sun β€” on purpose. It tracks the chain's heartbeat, not the earth's orbit.
  • Month names aren't baked in. Pass format_date(h, month_names=[...13...], style="short") for your own; otherwise the short style renders M01..M13. (The naming of the 13 moons is a decision the arcade makes by vote, not a constant in a library.)

3. The countdowns (the inverse)

There are no negative block heights on-chain β€” the chain starts at genesis. So "counting backward" in Bitcoin means the remaining-block countdowns: countdown(h) gives blocks to the next retarget, the next halving, the next cycle, and the last satoshi. The forward count (height, sats rising toward ~2.1 quadrillion) and the down count (subsidy shrinking toward zero, the 21M cap approaching) are mirror images of one schedule. Negative inputs are the conceptual inverse: from_height(-h) renders the bβ‚Ώ epoch.

4. The ordinal sidebar β€” for the sat collectors

Bitcoin's degree notation AΒ°Bβ€²Cβ€³D‴, straight from ordinal theory, labels the four positions hour, minute, second, third β€” that's in the handbook, not our invention. They are ordinal indices, not clock time:

Position Ordinal name Is Ticks every
AΒ° hour cycle number 1,260,000 blocks (~24 years)
Bβ€² minute block index in the halving epoch 210,000 blocks (~4 years)
Cβ€³ second block index in the difficulty period 2,016 blocks (~2 weeks)
D‴ third sat index in the block each sat

This is how ordinals and runes already work

The calendar and ordinal theory are the same skeleton, because both are built from Bitcoin's only native clock intervals β€” and each interval's first satoshi is exactly an ordinal rarity:

Interval Blocks Degree BFT unit First-sat rarity
block 1 third ‴ the tick uncommon
difficulty period 2,016 second β€³ 1 fortnight rare
halving epoch 210,000 minute β€² ~4 years epic
cycle 1,260,000 hour Β° ~24 years legendary
genesis β€” 0Β°0β€²0β€³0‴ 0000.01.01 aβ‚Ώ mythic

A BFT month is exactly two difficulty adjustments, so the calendar's page turns on the very events that mint rare and epic sats. Runes ride the same clock β€” a rune ID is literally block:tx, and open-mint terms are block-height windows. If you're numbering sats or etching runes, you're already telling Bitcoin time; this library reads it back to you.

The sky comes free (bft.sky)

There are two moons in this house, and both are honest because we label them. The calendar's moon lives here: a 28-day month is almost one trip of the real moon (~29.53 days), so BFT keeps a block-timed, symbolic lunation β€” D01 new, D15 full, D28 home β€” that drifts from the sky ~1.5 days a month on purpose, the same way the 364-day year drifts from the sun. The sky's moon is the one over your head; ask the sky, not this module. They agree at Day 0 β€” the calendar begins on a real new moon (block 983,664, ~7 Jan 2027) β€” and part ways after, ~9.6 days of phase per BFT year.

So every BFT month begins on a calendar new moon, and every BFT new year is a new-moon new year on the calendar's moon β€” true by construction, checkable by anyone. Each year also carries one of thirteen animal signs: the traditional twelve, plus the Astronomical Cat as the thirteenth (the sign left out of the Great Race).

import bft
bft.moon_phase(920_000)          # {'emoji': 'πŸŒ’', 'name': 'Waxing Crescent', ...}
bft.year_animal(920_000)         # {'emoji': '🐍', 'name': 'Snake', ...}
bft.format_date(858_000)         # '0016.05.23 aβ‚Ώ'  β€” the β‚Ώ-marked bitcoin date

Signs and moons are for wonder, not finance β€” and the calendar's moon never pretends to be the sky's. Same house rule as the rest of BFT. If the clock's moon ever looks "wrong" for the day of the month β€” a fat gibbous on D26, say β€” read the two moons: which surface wears which moon, why they drift, and the Day-0 handshake that starts every month on a new moon from then on.

Little guides & studies

The guides/ folder has short, illustrated, ELI5 walkthroughs β€” written so a sharp five-year-old can follow and a grown-up still learns something: the block clock, the thirteen months and the moon, the two calendars side by side, and a kid-safe lesson on never sharing your keys.

The studies/ folder holds the living clock studies β€” the flagship pupil clock (two clocks, one time, PAC-MAN eats the mempool) and the bitcoin birthday converter β€” plus docs/ with the exact math grid behind every number on the clock face.

The long view β€” "the longer-living time"

A quiet idea this project is built around: Bitcoin rewards patience, and measuring your life in blocks nudges you toward a longer view. Ten minutes is a long time to a day-trader and no time at all to a forest. As we learn to think in halvings and cycles β€” and as we look out for our frens across long horizons instead of the next candle β€” a block can become the new second: the shared, unhurried heartbeat of people who plan in decades. That's the "longer-living time." It's a philosophy, not a physics claim β€” but it's why the fastest hand on this clock is a ten-minute beat, and why the network only re-tunes itself once a fortnight. Slow is the feature.

Honesty notes (please keep these if you fork)

  • This is deterministic block arithmetic, not wall-clock time. A block's timestamp is miner-set and only loosely tracks real time. height_at() dates a moment at a steady 10-minute block, so a past date won't land on the exact height it historically did (real blocks came a bit faster), and a future date is a projection. What's exact is the math; what every node agrees on is the height β€” use a real tip when you need on-chain truth.
  • The 21-million cap and the ~10-minute target are implementation constants, not lines in the Bitcoin whitepaper. The subsidy schedule (50 BTC, halving every 210,000 blocks, flooring to 0 at epoch 33 near block 6,930,000) is what fixes issuance at ~2140.
  • "Bitcoin Time Clock" is a reading, not the meaning of the ticker.

The spark β€” where this came from

This project was born around the Ordinals coding club. Pac sat in on many of those sessions β€” even got to sign off on one of the requests for some testing β€” and the idea took root there. Then, at Portland's Bitcoin is for Everyone, the auditorium screen carried the generic time clock laid out exactly as ordinal theory describes it: hour, minute, second, straight from the handbook. Watching it, one thing was plain: it could be better. Not wrong β€” just not deep enough. The notation names the positions; it doesn't take you down to the meaning.

So we went deeper β€” we're degenz; that's the job. Ordinal theory didn't break the clock down to this level. We kept digging until the hh:mm face, the 13-month calendar, the block-timed moon, the countdowns, and the lore all fell out of the same block math β€” until we hit the heart of bitcoin. And we display it the way the arcade remembers everything worth keeping: 8-bit, nostalgic, alive.

Prior art & credit

  • Ordinal theory and degree notation: Casey Rodarmor, who created it; raphjaph and the ord maintainers and contributors who carry it; and the community's Ordinal Theory Handbook. The hour/minute/second/third labels are theirs; this library keeps them, honestly labeled, as the sidebar β€” and digs on past them.
  • Block-time calculators and hardware block clocks exist, and the generic ordinal time clock has graced conference screens. What didn't exist, as far as we found, is a small library + spec unifying an hh:mm block-beat face, a block-native 13-month calendar, the halving/countdown math, and a Gregorian bridge β€” so here it is, for anyone to use.

License

MIT. Built by the Pac's Arcade non-profit β€” nobody should have to trust; everybody should get to verify. Contributions welcome.

About

A block height is a timestamp no authority can edit. Ordinal theory's clock, taken deeper - the hh:mm block-beat face, the 13x28 block calendar, halvings & countdowns: the heart of bitcoin, in 8-bit. Sparked at the Ordinals coding club. Zero dependencies. MIT.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages