📝 This article is a cross-post from the Ledger Engineering blog.
Bitcoin is a technological breakthrough. It’s not just money over TCP/IP, but also something that comes with total and unrestricted ownership, making it a very robust store of value. Back in 2014, we released the first ever smartcard-based Bitcoin hardware wallet named BTChip HW.1. Ledger has come a long way since, but our core ideas have not changed — we want to bring Bitcoin to the masses, and help you secure your keys like your life depends on it. Needless to say, Bitcoin is something that cuts close to our mission and values.
In September this year, we gave our Bitcoin users the possibility to choose which coins are selected for spending in an outgoing transaction, with Coin Control. This powerful feature received a lot of love from our Bitcoin community because it allowed them to avoid leaking their privacy to surveillance companies, since Bitcoins are not perfectly fungible.
Today, we are taking it up a notch. We’re giving you the ability to connect Ledger Live to your personal Bitcoin full node, for maximum privacy and trustlessness. We’re calling it SatStack.
What is a full node?
A full node, or fully validating node, maintains a full copy of the Bitcoin blockchain and checks it against Bitcoin’s consensus rules. It independently and unfailingly verifies every transaction registered on the blockchain, by authoritatively reconciling with its copy. A major disagreement in the consensus rules among the full nodes will result in a hard fork. Some of the consensus rules checked by full nodes are:
- cryptographic signatures of transactions are valid.
- there is no unusual inflation in the block subsidy.
- transaction outputs are not double spent.
Full nodes also play a crucial role in keeping the network healthy by propagating blocks through the Bitcoin p2p network and assigning ban scores to peers that misbehave or attempt to spam the network with invalid transactions. Blocks that violate the consensus rules, or have been orphaned, are not forwarded to the connected peers, effectively forming a shield and preventing peers from wasting compute resources to process invalid blocks. This ability to self-heal and rapidly prune errors is what makes the Bitcoin network extremely antifragile and resistant to DoS attacks.
Why you should consider running a full node
Don’t trust, verify.
Bitcoin is a monetary good that eliminates trust. Relying on a remote server for querying your balances and transactions is, therefore, a trust failure. A wallet that’s not using a full node will blindly trust just about anything. While a pwned explorer cannot get the private keys on your hardware wallet, or do transactions on your behalf, it can still trick you into believing a completely different state of the blockchain and your wallet, like balances, UTXOs, transaction history, and confirmations. This has security consequences because the compromised explorer server could lie by omission, or be used to trick a user into exchanging real goods or services for fake Bitcoins.
Luckily, the trusted display on your Ledger hardware wallet is the ultimate line of defence against signing something that has been spoofed by a malicious explorer. What you see is what you sign.
There is a theoretical case to be made that third-party explorers can spy on users’ transactions, lie about their balances, or even censor certain addresses from using their services. This is the principal reason why Ledger runs its own Bitcoin nodes and has developed in-house indexer and explorer services, despite having cheaper alternatives. Delegating this job to third-party services would expose our users to the risk of on-chain surveillance.
Running a full node avoids leaking your privacy, and protects you from censorship and surveillance.
Until today, Ledger’s cloud infrastructure has been indispensable, and critical to the functioning of Ledger Live. Running a full node will allow our users to continue using Ledger Live even if the company shuts down its servers or ceases to exist. This is a powerful statement in itself — much like being able to access your emails even if Gmail is down.
Running bitcoin— halfin (@halfin) January 11, 2009
Ledger Blockchain Explorer
Before diving into SatStack, it’s important to have a clear picture of what it intends to replace — Ledger’s cloud-based blockchain explorers. An explorer is simply a service that allows querying addresses to get associated transactions.
Unlike most third-part services, Ledger’s explorers do NOT require you to send your account
xPub to its remote server. With your
xPub, anyone can track all past and future transactions of your account, thereby leaking your privacy. Instead, Ledger Live locally derives individual addresses and uses them to query the associated transactions.
In the above picture, there are two important things to note:
- private keys never leave your hardware wallet (in red).
- extended public keys never leave Ledger Live (in yellow).
How SatStack works
At its core, SatStack is a lightweight blockchain explorer that allows querying the transaction history of addresses.
Most hosted explorers, including general purpose Electrum servers, achieve this by building an address-to-transactions mapping of the entire blockchain. While this is well suited for most use-cases, it is also extremely resource-hungry and something regular users cannot easily run on their own machines.
SatStack takes a different approach. It is completely stateless, consumes merely a few megabytes of RAM, and does not require any additional disk space. This is made possible by importing the public wallet descriptors of the user’s accounts into the Bitcoin full node’s native wallet, and watching for any new transactions on the associated addresses. It follows the model of personal wallet indexers, first popularized by Electrum Personal Server.
We developed SatStack to act as a bridge between Ledger Live and a Bitcoin Core full node. It exposes a REST API to Ledger Live on one side, and communicates with the Bitcoin Core node over RPC on the other side.
One of the design decisions was to develop SatStack as an independent and standalone binary. This allows for a future possibility to do the things like: - connect Ledger Live mobile app with a full node. - locally serve an explorer frontend for even better privacy. - integrate various protocol extensions.
Under the hood
Choosing the right language for this project was critical for a successful execution. We used the following checklist for deciding the programming language to use:
- How easy is to learn, and get productive with it?
- Is there a mature Bitcoin library that provides a rich RPC client, and wire protocol implementation?
- Can it provide high performance, with low memory footprint, without any intritcate optimizations?
- Can it produce small binaries that target a wide range of operating systems?
We settled with the choice of using Go, although Rust was a close second. SatStack uses btcsuite libraries, and heavily relies on the transport layer, data structures, and wire protocol parser of btcd.
One of the challenges of building a personal wallet indexer is that non-wallet addresses cannot be tracked by the full node, often resulting in missing information in the transaction history. While this is not a problem if
txindex is enabled on Bitcoin Core, it was important for us to build a solution that does not explicitly rely on specialized full node features, in order to accomodate all kinds of full nodes.
Something else we had to keep in mind was performance, to have fast synchronization on Ledger Live. Much of it was solved by caching UTXOs, and natively decoding wire transactions instead of relying on the full node. Performance of SatStack is currently comparable to that of a third-party hosted explorer, which makes it a very attractive alternative. This is a moving target, and we plan on further reducing the RPC overhead on SatStack. Performance benchmarks comparing SatStack and Ledger’s cloud explorers are available here.
Contributions and Final Thoughts
- Starting Ledger Live 2.18.0, users have the option to use a personal Bitcoin full node, instead of relying on Ledger’s infrastructure.
- We designed our solution to be lightweight in terms of CPU and memory usage, with no additional requirements on disk space.
- We contributed several patches to the btcd project and will keep doing more in the future.
- We will continue to iterate on SatStack; adding new features, and improving its performance and user-friendliness.
- We hope to see members of our community become sovereign individuals and contribute to the decentralization of the Bitcoin network.
As Captain Planet likes to say — the power is yours.