Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Part V · Toward real engineering The point of a hardware wallet is not that it signs. It is that the key never crosses the line.

Last chapter turned your private key into a tree. This one asks: which machine holds the root?

If it is a networked computer, that computer can be infected, remotely controlled, and read end to end. And chapter 15 established: knowing the mnemonic is owning the money.

The design of hardware signing is one sentence:

The online computer builds and broadcasts transactions, and has no private key.
The hardware device holds the key, shows the transaction, signs on confirmation, and never
goes online.

16.1 Setup

We keep the stand-in signature. The subject here is where the boundary is.

the device holds priv; the online computer should only know pub: 03e462bb33824fd4

16.2 The online computer: allowed to do almost everything, except hold the key

A networked computer can know your UTXOs, the destination, the amount, the fee. It can assemble a transaction. It should not possess the private key.

online computer builds: spend coin1 -> BobAddress amount=10 fee=0.1
does the online computer have a private key? False

Look at self.private_key = None.

That line is the entire technical content of this chapter. A hardware wallet is not an exotic cryptographic device — it is a separation of duties: move the one step that needs the key onto a different machine.

OnlineWallet can still do plenty: check balances, select UTXOs, estimate fees, build the transaction, broadcast it. None of that requires a private key. Exactly one thing does: signing.


16.3 The signer returns a signature, never a key

CONFIRM: send 10 to BobAddress, fee 0.1
signature: d09f90d58f6b7a8966 ...
did the online computer get the private key? False
does the signature verify? True

Look at HardwareSigner’s public surface: display and sign_if_confirmed. That is all.

The underscore on _priv is more than a Python convention — it stands for a physical boundary. In a real device the key lives in a dedicated secure element that even the device’s own main processor cannot read, reachable only through a “give me data, I’ll give you a signature” interface.

May cross the line   : unsigned transactions, signatures, public keys
May never cross      : private keys, mnemonics, seeds

That line is the entire product definition of a hardware wallet.


16.4 Why the device needs its own screen

You might think the problem is now solved. It is not.

If the online computer is compromised, it can quietly change the destination:

You think you're paying Bob.
The computer actually pays Mallory.

The key was never stolen, and the money is gone anyway.

the computer screen may claim: sending 10 to BobAddress
the device screen actually shows: CONFIRM: send 10 to MalloryAddress, fee 0.1
CONFIRM: send 10 to MalloryAddress, fee 0.1
after the user declines, is there a signature? False

This is why a hardware wallet must have its own display.

A device with no screen — just a USB dongle — leaves you entirely dependent on the possibly-infected computer to tell you what you are signing.

The device shows “who, how much, what fee” on its own trusted screen and lets you check it with your eyes. That is the one link in the chain malware cannot reach.

Which means: pressing confirm without reading the device screen is the same as not having a hardware wallet at all.

And to be honest: a hardware wallet does not prevent everything. It prevents the most fatal single failure — the online computer stealing the key outright. It cannot save you from phishing, from social engineering, or from photographing your seed phrase.


16.5 The idea behind PSBT

In practice this flow has a standard name: PSBT — Partially Signed Bitcoin Transaction.

Online computer: I've prepared the transaction, unsigned.
Hardware device: I've checked it and added a signature.
Online computer: I have the signature; broadcasting.
PSBT, initial: {'unsigned_tx': {'from_pub': '03e462bb33824fd4', 'utxo': 'coin1', 'to': 'BobAddress', 'amount': 10, 'fee': 0.1}, 'signatures': {}}
CONFIRM: send 10 to BobAddress, fee 0.1
PSBT signature keys: ['03e462bb33824fd4']
ready to broadcast? True

Notice signatures is a dictionary keyed by public key.

That is not incidental — it exists for multisig. A 2-of-3 transaction can go to the first device for one signature, then the second device for another, each adding an entry to that dictionary, and only broadcast once enough are collected.

“Partially” means exactly that: a transaction container that several parties can fill in by turns.

Which links straight back to chapter 14’s lock: if the UTXO’s locking script demands two signatures, the PSBT must collect two. However the lock is written is how the PSBT gets filled.

YOUR TURN

Question 3 is practical: a hardware wallet is a safe for your key, not the only copy of it. Devices break, get lost, and go through washing machines. Chapter 15’s mnemonic is the actual backup — and it has to live somewhere else, and not as a photograph on a networked device.


16.6 The ledger

What you wroteField
OnlineWallet — a builder with no keySecurity engineering (separation of duties)
HardwareSigner — returns only a signatureSecurity engineering (trust boundary)
Confirmation on an independent screenHuman-computer interaction + security
The PSBT containerInteroperability standard

Zero cryptography.

Three roles and what each holds:

RoleHasDoes
Online computerpublic keys, UTXOs, the networkbuilds and broadcasts
Hardware signerthe private key, a trusted screendisplays and signs
Attackerpossibly control of the online computerwants the key, or wants you to sign the wrong thing

The sentence:

A hardware wallet does not make signing more magical. It keeps the key from crossing the line. The networked machine may be compromised, and the key is still sitting in a room with no cable.


Next

A multi-node network.

Sixteen chapters have described mechanisms, and every one of them has run inside a single machine and a single Python process.

The next chapter puts them into several mutually distrustful containers, each keeping its own mempool, mining on its own, broadcasting, and verifying independently.

Then you will watch them converge on the same chain.

It is the first time in this book that chapter 7’s “a shared ledger is not the starting point but the result of convergence” becomes something you can see with curl.