A coin is a shared ledger

A cryptocurrency begins with a record of who may spend what. We establish the rules DCoin needs, compare network topologies, and build the cryptographic tools for checking messages without trusting their sender. Along the way, we distinguish authorization from agreement and pseudonymity from privacy.

Updated 8 min read

Suppose a group of friends wants a currency for exchanging things: a book, a set of lecture notes, an afternoon of help with a project. Call it DCoin, with Ð as its currency symbol. At first, a spreadsheet would do. Someone creates a column of names, assigns balances and updates the rows whenever money changes hands.

The spreadsheet is already most of a payment system. It records ownership and prevents an honest operator from spending the same balance twice. Its weakness is also obvious: the person who controls it can edit a balance, refuse a payment, lose the file or publish different copies to different people.

We could appoint a second operator, add backups and require signatures on changes. Those are sensible designs. But let us try a different constraint: no participant gets the final say merely because they operate the ledger. Anyone should be able to check the rules for themselves.

That constraint turns a small accounting exercise into a distributed systems problem. Before choosing a blockchain, we need to understand which jobs it must perform and which tools can perform them.

1.1 #Decide what the ledger must guarantee

A coin in this system is not a little file that moves from one computer to another. Files are easy to copy. Instead, the ledger records permissions to spend amounts, and a payment changes those permissions according to public rules.

DCoin needs answers to five questions:

  1. Issuance: where do the initial units come from, and when may new ones be created?
  2. Authorization: what evidence allows a participant to spend an existing amount?
  3. Conservation: how do we check that a payment does not spend more than it owns?
  4. Ordering: what happens if two individually plausible payments spend the same money?
  5. Replication: how do participants obtain and check the history without asking a single privileged server?

These questions are related, but they are not interchangeable. A signature can answer an authorization question without answering an ordering question. A network can deliver two conflicting messages perfectly. A database can preserve an invalid history just as faithfully as a valid one.

We will make the distinction concrete throughout the series. For now, assume that DCoin has a published initial allocation and deterministic validation rules. Two computers given the same valid history should derive the same spendable state. This gives us a useful boundary: implementation bugs aside, disagreement must come from different inputs, different histories or different rules—not from a validator making a personal judgment.

The difficult environment is one in which participants may arrive late, disconnect, lie or create many identities. Messages take time to travel. A peer can withhold a payment or show it to only part of the network. We should not design a protocol whose correctness depends on everybody receiving everything at the same instant.

1.2 #Share the data without appointing its owner

A peer-to-peer network lets participants exchange data directly. A node may request a block from one neighbor and serve it to another. This does not require every node to connect to every other node. A full mesh of nn participants would need n(n−1)/2n(n-1)/2 connections, which quickly becomes impractical.

The following three shapes illustrate different dependencies. The machines represent peers; the lines represent communication paths, not voting power or ownership.

CentralhubRegionalhubsPeermesh
Figure 1.1. A central hub, a hierarchy of hubs and a mesh with several routes between peers. Distribution of connections and distribution of authority are separate design choices.

The central hub is simple to operate, but losing it breaks communication. Regional hubs spread the load while retaining dependencies on particular machines. A mesh provides alternative paths, although whether it remains connected depends on which nodes fail and how neighbors were selected.

Real systems mix these patterns. A peer may initially discover other peers through a small set of well-known services, then exchange data without routing every request through those services. Bootstrapping is a dependency worth examining, but it is a different question from who validates a payment. Likewise, a structured overlay that organizes lookup by keys is not the same concept as a network that uses central hubs.

Replication has a cost. Each additional full validator must obtain and process the relevant data; it does not magically make a globally replicated ledger faster. Peers also differ in bandwidth, uptime, storage and influence over message propagation. Saying that they follow the same validation rules is much more precise than saying that all nodes are equal.

For DCoin, we will use a mesh of peers to distribute candidate transactions and blocks. A peer is a source of data, not a source of truth. Whenever possible, the receiver checks what it receives.

1.3 #Fingerprint a message with a hash

A cryptographic hash maps a byte string of arbitrary length to a fixed-length result. SHA-256, for example, produces 256 bits. Its hexadecimal representation has 64 characters because each hexadecimal digit represents four bits.

For our purposes, a useful hash has three practical properties: finding an input for a specified output should be infeasible; finding a different input with the same hash as a given message should be infeasible; and finding any pair of different inputs with the same hash should be infeasible. These are computational expectations, not a claim that collisions do not exist. There are infinitely many messages and only finitely many digests.

Hello,friendsSHA-256Digest5326d882e6c7...Onechangedbytegivesadi®erent¯ngerprint
Figure 1.2. The same message bytes always produce the same digest. The displayed value is the first 12 hexadecimal characters of SHA-256, not the complete hash.

We can check the figure with Python's standard library:

from hashlib import sha256
 
for message in ("Hello, friends", "Hello, friends!"):
    print(sha256(message.encode("utf-8")).hexdigest())

The results are:

5326d882e6c7a07e3727f52ad6f47b30158a06efc3fdc543adb3b629b6490ae6
c56846234054fb1fd7f36474fbf6c3c1a41667f473d6ba3f21a02c798c5c211f

Adding a single exclamation mark changes the digest completely. This makes a hash useful for detecting changes and referring to large objects compactly. It does not hide the input. Anyone who suspects the message was “Hello, friends” can hash that guess and compare it. Hashing a name or email address is therefore not, by itself, a privacy mechanism.

There is another detail we cannot leave implicit: hashes operate on bytes. Two JSON objects with identical meaning may have different whitespace or key order and therefore different hashes. DCoin must specify an unambiguous serialization before it can use a digest as a transaction identifier.

1.4 #Authorize a payment with a signature

Hashes identify content, but they do not identify who approved it. If anybody can compute H(m)H(m), anybody can attach that hash to a forged payment.

A digital signature scheme introduces a key pair. The private key stays with its holder; the public key can be distributed. The holder signs a message with the private key. A verifier checks the message and signature using the public key. An appropriate scheme makes it infeasible to produce a valid signature for a new message without the private key.

SigningMessagemPrivatekeySignSignedmessageVeri¯cationmand¾PublickeyVerifyValid/invalid
Figure 1.3. Signing needs the message and private key. Verification needs the message, its signature and the public key. The message remains readable throughout.

For DCoin, a payment must commit to the spending inputs, recipients and amounts in the way our rules prescribe. Signing an incomplete message is dangerous: if the recipient is not covered, someone may be able to substitute another recipient while keeping the signature valid. Real transaction signature rules are more intricate than “sign the transaction hash”; the important design requirement is to state exactly which bytes and which spending context are authorized.

A valid signature says that the relevant key authorized this message. It does not prove that the key belongs to a particular human, that the human intended the action, or that the device was not compromised. It also does not prove that the money is still available. The same holder can sign two conflicting payments.

This is why signatures do not encrypt identities. A public ledger can expose amounts, links between transactions and patterns of activity even when its keys carry no legal names. Pseudonymity and privacy are separate properties, and DCoin has not gained the latter simply by using cryptography.

1.5 #The missing piece is a common history

We now have a way to distribute messages, detect changes and check authorization. Imagine Alice has 500 Ð. She signs one payment spending it to Bob and another spending it to Carol. Both signatures verify. Both messages may reach honest peers. Neither a better hash function nor more network connections tells us which payment should take effect.

A single operator would settle the conflict by ordering the payments in its database. Our design needs an alternative that participants can verify and apply even when they initially see different messages.

That is the job for the rest of the series. First we need a precise model of a spendable output, a transaction and a block. Once those objects exist, we can ask how competing histories are compared. The blockchain is useful only if those surrounding rules turn a pile of signed messages into one coherent account of what may be spent next.

For the original formulation of the double-spending problem and its proof-of-work solution, see the Bitcoin white paper. DCoin is a teaching model; when we switch to Bitcoin's actual data formats, we will mark that boundary explicitly.