This is part 1 in a tutorial series on Stellar. Throughout the series we'll go over the theoretical ideas underpinning Stellar, and we'll learn to automate our interactions with the network using Python, through the Horizon REST API.
Stellar is a decentralized, federated financial platform with a native asset, the lumen. Why is Stellar is decentralized? Why is it federated? What is a lumen? We'll go through this step by step.
The lumen, like bitcoin, is a cryptocurrency. A cryptocurrency is a currency whose power/value stems not from the authority of a sovereign state, but from the principles of mathematics (more precisely, number theory).
Blockchains are at the heart of cryptocurrencies. Consensus is at the heart of blockchains.
In one sentence, a blockchain is a distributed ledger.
A ledger is just a sequence of transactions. The ledger keeps a record of every transaction ever made, and everyone keeps a copy of that ledger. Consensus is what makes the "distributed" part work. Consensus on what, though? In Stellar's case, we must reach consensus on the state of the Stellar network. What is the Stellar network? What is its "state"? More on this later.
A physical ledger from 1828. Wikipedia article on ledgers.
Stellar reaches consensus by turning local consensus into global consensus. Local consensus is called a quorum slice. Global consensus is called quorum. Global consensus arises when there's enough local consensus in the network. Or, to use the new language: quorum arises when there's enough quorum slices in the network. The tricky part is to define enough.
The punchline in Stellar's consensus mechanism is: global consensus doesn't need everyone to agree with everyone. It's enough for everyone to simply agree with their "neighbors", and, by having everyone agreeing with a small neighborhood around them, global agreement/consensus magically arises. Well, not magically, but mathematically.
The formal properties of Stellar's consensus algorithm allow 4 important things:
- To reach consensus fast and cheaply: within a few seconds and spending little energy
- To let anyone join the consensus process: no one has all the decision-making power
- To let everyone decide who to trust: if you want to be trusted, you better play clean
- To be safe: even if bad actors join the network, the network can still arrive at the "right" consensus
Before you say the first point is not important, consider 2 examples. A sequence of transactions that would cost 150 million dollars in fees over the traditional financial system only costs 20 cents over the Stellar network. The Bitcoin network has, as of January 2017, 2 exahashes of processing power, which consumes as much energy as all of Ireland, and its network still takes ~30 minutes to process a transaction.
A hard problem: consensus
Reaching consensus is one of the hardest problems cryptocurrencies face.
The key issue with consensus is trust. It's hard to reach consensus with untrusted parties. What if Alice tells me to meet her at place X, but she goes to place Y? Of course, if Alice is my friend, I definitely trust her, but when it comes to the economy, with all sort of parties involved, it's unreasonable to trust everyone.
Now, the key issue with trust is power. It's easy to trust someone if we know there's some entity looming behind, more powerful than both of us, who can keep us honest.
Currency is a form of trust that is easy to quantify and divide, which what we want in order to do economic transactions. Without currency, transactions would be cumbersome. So, everyone wants to use currency because it's convenient. How can everyone agree on the value of a given currency, though?
Say, If I were to mint some fiat currency, it would have zero value, because people would have zero trust in it. Why? Because I have zero power. Sovereign states do have power, which is why people (usually) trust currencies minted by them. The less powerful a state, the less value any currenty minted by it would have, and, in the limiting case, a failed state may end up with a currency that has zero value.
What is a blockchain?
A blockchain is a mathematical object whose main goal is to provide trust.
To do this, a blockchain must reach consensus through some consensus algorithm.
So, currency is a form of trust, and blockchains are a mathematical way of providing trust. Can there exist currencies whose trust doesn't come from the power of a sovereign state, but from the power of mathematics?
The answer is yes.
A solution: proof of work
The Bitcoin blockchain reaches consensus through a mechanism called proof of work.
The first application of proof of work was fighting spam. Each time Alice sent an email, the server required her computer to compute hashes; say, half a second worth of hashes. As a first approximation, we can see a hash as the value of a function at some point. For example, the value of the square function at the point 4 is 16, because 16 is the square of 4. A hash arises in the same way, but by using a function with special properties. That function is called a hash function.
To get an idea of what this looks like, the hash of
123 under a common hash function is
So, proof of work adds a small overhead to each email sent (half a second). This is small enough to go unnoticed by Alice, but a game-changer for spammers, who now must spend half a million seconds to send one million emails. How can the server verify that Alice has actually done all that work, though? The details are tricky:
The server arbitrarily chooses a number, say
1,000,000,000,000. In Bitcoin this is called the difficulty target. The lower its value, the harder it is to compute. To arrive at this number, Alice must hash her email repeatedly, until she (by acccident) arrives at a number smaller than
999,999,999,999. Now, to verify Alice has actually ran tons and tons of hashes to arrive at
999,999,999,999 (or smaller), the server simply looks at Alice's hash and compares it to the one it has. If they're identical, the server knows Alice did do all the work. This works because (good) hash functions are expected (but maybe not proved!) to behave randomly, it's possible to calculate how long she has to keep on computing until she finds the desired number by accident.
Satoshi used proof of work as a way to establish consensus. It's not at all obvious how one would do this, which is probably why it took so long for people to figure it out.
But the key to this relies in number-theoretic magic. Proof of work can only exist if there are functions that hard in "one direction", but easy in "another" one, in a precise technical sense.
An example of such objects are hash functions, which are easy to evaluate but near impossible to reverse. In our previous example, it's easy to arrive at
75263518707598184987916378021939673586055614731957507592904438851787542395619 if we're given
123, but it's near to impossible to calculate
123 if we only have
This is not because the hash is a large number, but because of the number-theoretic properties of this particular hash function.
The mathematical foundations of blockchains come from number theory, and the computational complexity of certain objects, such as the integers and elliptic curves. (Find out more about elliptic curves here and here)These objects can get so complicated that certain problems on them are possible to solve but require more computational resources than what can be found in, say, the observable universe. This aspect is used as shelter against attackers.
On the other side, we can also reach consensus based on them, but it comes at a price: lots of (feasible) computation.
The two largest cryptocurrencies, by market capitalization (as of Jan 2017), are Bitcoin (USD 16 billion) and Ethereum (USD 1 billion). Both use different mechanics to reach consensus. They have different formal properties, making them, in particular, very expensive to compute. (Bitcoin, for instance, is starting to consume as much energy as whole countries). At these capitalizations, blockchains are still very small in the global economy, and scaling up some of these algorithms to the planetary level is a serious concern.
Stellar is a decentralized financial platform that reaches consensus in a computationally cheap way. This grants the network a level of nimbleness that is mathematically difficult for other similar systems.
Every transaction has a .00001 XLM fee, as a deterrent to spammers, called the base fee. These funds are fed back to the Stellar network in the process of inflation. For more information go here.
A first dive into the Stellar network
But enough talk of ledgers, transactions, operations, and effects. What does the state of the network actually look like? It's easy to take a peek using the REST API, which we'll access through Python.
import requests # Install by running `pip install requests` on the console from pprint import pprint class Horizon: """A thin Python wrapper around the Horizon REST API!""" def __init__(self, horizon_url='https://horizon.stellar.org'): self.horizon_url = horizon_url def metrics(self): return requests.get(self.horizon_url + '/metrics') def ledgers(self, limit=10, order='desc'): return requests.get(self.horizon_url + '/ledgers?limit=' + limit + '&order=' + order) def ledgers(self): return requests.get(self.horizon_url + '/ledgers?limit=10&order=desc') def account(self, account_id): return requests.get(self.horizon_url + '/accounts/' + account_id) def trades(self, account_id): return requests.get(self.horizon_url + '/accounts/' + account_id + '/trades') def payments(self, account_id): return requests.get(self.horizon_url + '/accounts/' + account_id + '/payments') def transactions(self, account_id): return requests.get(self.horizon_url + '/accounts/' + account_id + '/transactions') def operations(self, account_id): return requests.get(self.horizon_url + '/accounts/' + account_id + '/operations') def effects(self, account_id): return requests.get(self.horizon_url + '/accounts/' + account_id + '/effects') def offers(self, account_id): return requests.get(self.horizon_url + '/accounts/' + account_id + '/offers') # This is an account on the real network that I created for testing purposes account_id = 'GAOXVBKHGKH3UNAK4EIG3XVAWMA4B7Y3LF42EMIKJINVMLTNXYGHUQWM' horizon = Horizon() response = horizon.metrics() pprint(response.json()) response = horizon.ledgers() pprint(response.json()) response = horizon.account(account_id=account_id) pprint(response.json()) response = horizon.trades(account_id=account_id) pprint(response.json()) response = horizon.payments(account_id=account_id) pprint(response.json()) response = horizon.transactions(account_id=account_id) pprint(response.json()) response = horizon.operations(account_id=account_id) pprint(response.json()) response = horizon.effects(account_id=account_id) pprint(response.json()) response = horizon.offers(account_id=account_id) pprint(response.json())
What does the output look like? It's a mess, isn't it? But at least it's human-readable,
In time we'll turn this innocent-looking snippet into a powerful application that can do all sorts of useful things, from making simple payments to doing high-frequency trading. But before that, we'll go deeper into Stellar itself. The key idea is this: federated Byzantine agreements.
Here's 3 suggestions to start getting familiar with Stellar.