diff options
author | Christian Cleberg <hello@cleberg.net> | 2025-07-07 09:42:46 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-07 09:42:46 -0500 |
commit | e41732049217099644482e89ea5d3bc83eac63c7 (patch) | |
tree | b014c037e61b1c16eef2efab01e7bde9f16d5b21 | |
parent | 1716be666d7b8f19f3f4fdf345c42a997cc176bd (diff) | |
parent | 444ec6a63a1ffe94c6ffb5e6aa7fc8cdcc81dbb9 (diff) | |
download | cleberg.net-e41732049217099644482e89ea5d3bc83eac63c7.tar.gz cleberg.net-e41732049217099644482e89ea5d3bc83eac63c7.tar.bz2 cleberg.net-e41732049217099644482e89ea5d3bc83eac63c7.zip |
Merge pull request #1 from ccleberg/theme-enhancements
Theme enhancements
-rw-r--r-- | build.py | 13 | ||||
-rw-r--r-- | content/blog/2025-06-27-how-blockchain-works.org | 197 | ||||
-rw-r--r-- | theme/static/styles.css | 210 | ||||
-rw-r--r-- | theme/templates/base.html | 3 |
4 files changed, 370 insertions, 53 deletions
@@ -115,6 +115,7 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): "date": re.compile(r"^#\+date:\s*<(\d{4}-\d{2}-\d{2})"), "slug": re.compile(r"^#\+slug:\s*(.+)$", re.IGNORECASE), "filetags": re.compile(r"^#\+filetags:\s*(.+)$", re.IGNORECASE), + "draft": re.compile(r"^#\+draft:\s*(.+)$", re.IGNORECASE), } for org_path in Path(content_dir).glob("*.org"): @@ -122,6 +123,7 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): date_str = None slug = None tags = [] + is_draft = False with org_path.open("r", encoding="utf-8") as f: for line in f: @@ -153,10 +155,21 @@ def get_recent_posts_html(content_dir="./content/blog", num_posts=3): tags = [t for t in raw.split(":") if t] continue + m = header_patterns["draft"].match(line) + if m: + draft_value = m.group(1).strip().lower() + if draft_value != "nil": + is_draft = True + break + continue + # Stop scanning once we have all required fields if title and date_str and slug and tags: break + if is_draft: + continue + if title and date_str and slug: try: date_obj = datetime.strptime(date_str, "%Y-%m-%d") diff --git a/content/blog/2025-06-27-how-blockchain-works.org b/content/blog/2025-06-27-how-blockchain-works.org new file mode 100644 index 0000000..c31e5a8 --- /dev/null +++ b/content/blog/2025-06-27-how-blockchain-works.org @@ -0,0 +1,197 @@ +#+date: <2025-07-07 Mon 00:00:00> +#+title: Blockchain Series #1: How Blockchain Works Under the Hood: Hashes, Keys, and Signatures Explained +#+description: Dive into blockchain's cryptographic foundations. Explore how hash functions, Merkle trees, and digital signatures secure distributed, tamper-resistant ledgers. +#+slug: how-blockchain-works +#+filetags: :blockchain:encryption: +#+draft: t + +/This is Part 1 of a series I'm writing on blockchain. Stay tuned for further +editions./ + +Blockchain is one of those technologies that seems to generate more marketing +buzz than real understanding. Everywhere you look, people talk about +decentralization, trustless systems, and the next big disruption. But beneath +the hype, blockchain systems rely on well-understood cryptographic building +blocks to do something very specific: maintain a secure, tamper-resistant ledger +without needing a central authority. + +If you're serious about understanding blockchain, it's critical to understand +the cryptographic primitives that make it work. Hash functions, digital +signatures, and public-key cryptography aren't just jargon—they're the core +mechanisms that let a distributed network agree on a shared history no one can +easily rewrite. + +This post is Part 1 of a multi-part series on blockchain. Here, we'll focus on +these fundamental building blocks—how they work, why they're used, and how they +fit together to provide the security and trust that blockchain promises. + +* What is Blockchain? + +At its core, a blockchain is a distributed, append-only ledger shared among +participants in a network. + +What does this mean? Essentially, we can think of a standard, non-technical +ledger (book of accounts where transactions are recorded against accounts). When +introductin the idea of a blockchain, let's extend the idea of a standard ledger +and make a few connections: + +- Each block of transactions is connected cryptographically to the block before + it, via a [[https://en.wikipedia.org/wiki/Cryptographic_hash_function][cryptographic hash]]. This is what forms a =chain= of blocks, or + records. +- Each block consists of: + - A list of validated transactions + - A timestamp + - A cryptographic hash of the previous block (ensuring immutability) +- Each transaction within a block is initiated between addresses, signed with + cryptographic keys, and sent to the blockchain for validation (e.g., + proof-of-work, proof-of-staking, etc.). +- The blockchain is shared amongst nodes in the network, who agree on the state + of the blockchain through consensus mechanisms. + +As we can see, the decentralized nature and cryptographic linking of +transactions and blocks ensures that modifying the history is infeasible. + +If you're more of a visual person, here's a very basic diagram of a standard +blockchain structure. + +#+begin_example ++------------+ +------------+ +------------+ +| Block 1 | -> | Block 2 | -> | Block 3 | +|------------| |------------| |------------| +| Data | | Data | | Data | +| Prev Hash: | | Prev Hash: | | Prev Hash: | +| 00000000 | | <hash1> | | <hash2> | +| Hash: | | Hash: | | Hash: | +| <hash1> | | <hash2> | | <hash3> | ++------------+ +------------+ +------------+ +#+end_example + +* What Problems is Blockchain Trying to Solve? + +I will be diving into the technical details of blockchains later in this post, +but what exactly is the reason blockchain exists? + +You may know of cryptocurrencies, such as Bitcoin, but that is only one of many +use cases for blockchains. + +As we learned in the section above, a blockchain can be equated to a ledger. +With this in mind, let's dive into a few interesting use cases: + +** Immutable record-keeping + +If you simply need a ledger that cannot be modified easily and can establish a +decentralized network to support that, blockchain is a great technology. + +** Trust without central authority + +The use of a decentralized system means that we do not need to rely on a +centralized authority (e.g., Social Security, a bank, etc.) to store and provide +access to information you need to record. + +Think of the US Social Security Number (SSN) system. Each time you want to +perform actions that require verifying your identify (e.g., opening bank +accounts, investment accounts, child birth, etc.), you are currently required to +provide your SSN. + +However, this is a singular number - which means that if someone learns it, they +can (essentially) now act as you. + +Now imagine a scenario where the SSN system is a blockchain where you have both +your private key for providing evidence to people that you are you. For example, +you open a bank account and sign your form with your private key. Now, the bank +can take that and use your public key to decrypt the message and verify that you +are you, without needing to know your private key. + +Another scenario is that, during a background check, a company could use your +public key and consult the related blockchain to validate specific pieces of +information. For example, if your identity alone is in one block, you could +provide that information to your employer without providing your full SSN and +all related personal information for as long as they keep your SSN on file. + +** Double-spending problem + +With the introduction of digital assets, such as cryptocurrencies and +non-fungible tokens, a new risk is introduced: without control, these assets +could be copied and reused at-will. + +To solve this problem, digital assets are transacted on a blockchain to ensure +that the decentralized system of nodes provide consensus on validating +transactions, transactions are recorded in a transparent and tamper-resistant +manner, and cryptographic functions are performed to order the transactions +logically on chain. + +* The Role of Cryptography in Blockchain +- Why cryptography matters +- Confidentiality vs. integrity/authenticity +- Core goals: + - Tamper-evidence + - Secure identification + - Non-repudiation + +* Hash Functions +- What is a cryptographic hash? +- Properties: + - Collision resistance + - Pre-image resistance +- How blockchain uses hashes: + - Chaining blocks together + - Block headers + - Transactions +- Example command: + #+begin_src bash + echo -n "Hello, Blockchain" | sha256sum + #+end_src +- Optional diagram: chain of blocks with hashes + +* Merkle Trees +- Summarizing many transactions in a single root hash +- Use case: efficient inclusion proofs +- Example diagram (ASCII art if desired) +- Why Merkle roots are in block headers + +* Public Key Cryptography +- Quick refresher +- Public/private keypairs +- Addresses derived from public keys +- Importance of keeping private keys secret + +* Digital Signatures +- Purpose: proving authorship without revealing private key +- Mention ECDSA / EdDSA +- How transactions are signed +- Example snippet: + #+begin_example + Alice signs transaction with her private key + → Anyone can verify with her public key + #+end_example +- Why signatures prevent forgery + +* Bringing it All Together: Blockchain Data Structures +- Block structure: + - Block header with previous block's hash + - Merkle root + - Timestamp, nonce +- How the chain ensures immutability +- Example flow: + 1. User creates a transaction + 2. Signs it + 3. Transaction included in block + 4. Block hash links to previous block + +* Proof of Work (Optional) +- Hash puzzles to add blocks +- Why it's hard to modify history +- Keep this section simple + +* Conclusion +- Summarize how these primitives work together +- Tease next post: "Next, we'll explore security threats and how blockchain + networks mitigate them." +- Optional links to further reading: + - Bitcoin whitepaper + - Ethereum docs + - Cryptography references + +* Optional Extras +- Glossary box with terms (hash, signature, Merkle tree) +- External references (e.g., NIST docs on hashes) diff --git a/theme/static/styles.css b/theme/static/styles.css index d21b23f..9de0c4f 100644 --- a/theme/static/styles.css +++ b/theme/static/styles.css @@ -9,8 +9,10 @@ */ html { - line-height: 1.15; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ + line-height: 1.15; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ } /* Sections @@ -43,9 +45,12 @@ h1 { */ hr { - box-sizing: content-box; /* 1 */ - height: 0; /* 1 */ - overflow: visible; /* 2 */ + box-sizing: content-box; + /* 1 */ + height: 0; + /* 1 */ + overflow: visible; + /* 2 */ } /* Text-level semantics @@ -65,9 +70,12 @@ a { */ abbr[title] { - border-bottom: none; /* 1 */ - text-decoration: underline; /* 2 */ - text-decoration: underline dotted; /* 2 */ + border-bottom: none; + /* 1 */ + text-decoration: underline; + /* 2 */ + text-decoration: underline dotted; + /* 2 */ } /** @@ -121,10 +129,14 @@ input, optgroup, select, textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 1 */ - line-height: 1.15; /* 1 */ - margin: 0; /* 2 */ + font-family: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + line-height: 1.15; + /* 1 */ + margin: 0; + /* 2 */ } /** @@ -199,12 +211,18 @@ fieldset { */ legend { - box-sizing: border-box; /* 1 */ - color: inherit; /* 2 */ - display: table; /* 1 */ - max-width: 100%; /* 1 */ - padding: 0; /* 3 */ - white-space: normal; /* 1 */ + box-sizing: border-box; + /* 1 */ + color: inherit; + /* 2 */ + display: table; + /* 1 */ + max-width: 100%; + /* 1 */ + padding: 0; + /* 3 */ + white-space: normal; + /* 1 */ } /** @@ -230,8 +248,10 @@ textarea { [type="checkbox"], [type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ } /** @@ -249,8 +269,10 @@ textarea { */ [type="search"] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ } /** @@ -267,8 +289,10 @@ textarea { */ ::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ } /* Misc @@ -316,11 +340,21 @@ body { Liberation Mono, Lucida Console, monospace; - font-size: 0.9rem; + font-size: clamp(0.95rem, 1vw + 0.5rem, 1.1rem); line-height: 1.5; max-width: 50em; margin: 0 auto; - padding: 0 1rem; + padding: 0 clamp(1rem, 5vw, 3rem); +} + +@media (min-width: 768px) { + body { + padding: 0 2rem; + } +} + +main>*+* { + margin-top: 2rem; } .site-nav, @@ -329,7 +363,7 @@ footer { } footer { - border-top: 1px dotted; + /* border-top: 1px dotted; */ padding-top: 1rem; margin: 1rem 0; } @@ -342,9 +376,9 @@ ul { list-style-type: "- "; } -.site-nav { +/* .site-nav { border-bottom: 1px dotted; -} +} */ .site-nav ul { list-style-type: none; @@ -362,12 +396,43 @@ h2, h3, h4 { color: var(--fg); + text-transform: uppercase; +} + +h1 { + font-size: 2rem; + font-weight: bold; + /* border-bottom: 1px solid var(--border); */ + margin-top: 2rem; + margin-bottom: 1rem; +} + +h2 { + font-size: 1.5rem; + margin-top: 1.5rem; + margin-bottom: .75rem; +} + +h3 { + font-size: 1.25rem; + margin-top: 1.25rem; + margin-bottom: .5rem; +} + +#text-table-of-contents li { + text-transform: uppercase; } a, a:visited { color: var(--link); - text-decoration: none; + text-decoration: underline; + text-decoration-skip-ink: auto; +} + +a:focus-visible { + outline: 2px solid var(--link); + outline-offset: 2px; } a:hover { @@ -393,7 +458,7 @@ table { Liberation Mono, Lucida Console, monospace; - font-size: 0.9rem; + font-size: inherit; width: 100%; } @@ -406,7 +471,7 @@ td { } pre, -pre > code, +pre>code, time, code { font-family: @@ -426,7 +491,7 @@ pre { overflow-x: auto; } -:not(pre) > code { +:not(pre)>code { color: var(--code); font-family: inherit; } @@ -471,8 +536,8 @@ blockquote p { } .post-metadata { - border: 1px dotted var(--fg); - border-top: none; + border: 1px dotted var(--border); + /* border-top: none; */ padding: 1rem; } @@ -526,39 +591,80 @@ span.tag::before { } .post { - display: flex; - flex-direction: row; - margin-bottom: 1rem; + display: flex; + flex-direction: row; + margin-bottom: 1rem; } .post-content { - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; } .post-tags { - font-size: 0.75rem; - color: #999; - margin-top: 0.1rem; + font-size: 0.85rem; + color: #999; + margin-top: 0.1rem; } .tag { - margin-right: 0.3rem; - font-style: normal; - opacity: 0.8; + margin-right: 0.3rem; + font-style: normal; + opacity: 0.8; } .tag::before { - content: "#"; + content: "#"; +} + +.skip-link { + position: absolute; + left: -999px; + top: auto; + width: 1px; + height: 1px; + overflow: hidden; +} + +.skip-link:focus { + left: 1rem; + top: 1rem; + width: auto; + height: auto; + background: var(--bg-bright); + color: var(--fg); + padding: .5rem; + border: 1px solid var(--fg); } @media (prefers-color-scheme: dark) { :root { - --bg: #141617; - --bg-bright: #191c1d; - --fg: #b2aea9; - --link: gold; - --code: red; + --bg: #121212; + --bg-bright: #1e1e1e; + --fg: #e0e0e0; + --link: #8ab4f8; + --code: #f28b82; --border: #333; } } + +@media print { + body { + background: #fff; + color: #000; + font-size: 12pt; + padding: 0; + max-width: none; + } + + .site-nav, + footer, + aside { + display: none; + } + + a::after { + content: " (" attr(href) ")"; + font-size: 90%; + } +}
\ No newline at end of file diff --git a/theme/templates/base.html b/theme/templates/base.html index daa43d0..6867ec7 100644 --- a/theme/templates/base.html +++ b/theme/templates/base.html @@ -17,6 +17,7 @@ {% endblock %} </head> <body> + <a href="#main" class="skip-link">Skip to content</a> <nav class="site-nav" aria-label="site-nav" role="navigation"> <ul> <li><a href="/">Home</a></li> @@ -25,7 +26,7 @@ <li><a href="/wiki/">Wiki</a></li> </ul> </nav> - <main>{% block main %}{% endblock %}</main> + <main id="main">{% block main %}{% endblock %}</main> <footer> <p>Donate: <a href="monero:82frXv83WVsGbTwuqSyb27cvy67JpD7Ktaij12Avy6ogfZatsgPG67YgsmEmvTFLKd1Rk7MUwx8D31ieGwLdD4wa4KdtxDB">XMR</a> | <a href="ethereum:0x11255046Ccd637f1ACc78ae7c8849870f85638B3">ETH</a> |