Try Bitcoin


🇫🇷 | 🇪🇸 | 🇩🇪

Welcome!

This is an interactive tutorial for beginners who want to learn more about the technical side of Bitcoin. Coding experience is helpful, but not required.

This takes about 20 minutes to complete. It's designed for desktop, so please, I beg you, do not try this on mobile.

Try Bitcoin uses popular Bitcoin JavaScript libraries like bitcoinjs and bip-schnorr to explain different parts of system. It also introduces a few Bitcoin Core CLI commands.

Some concepts have been simplified for educational purposes but don't let that discourage you! The goals are for participants to gain a better understanding of how Bitcoin works, and to walk away with the confidence to tackle the many books, courses, and websites that take a deeper dive.

On the right we have something that's called a 📟 console 📟. You type commands into it and press 'Enter' on your keyboard. After that, the program returns a response.


To begin, type start into the console.

Lesson 1

Most people are familiar with bitcoin as a type of money, but what does it mean to own some?

Units of bitcoin are assigned to things called 🔑 public keys 🔑.

For advanced situations, bitcoin can be assigned to multiple public keys. Scripts make this possible, but we won't be covering them.

For now, it's okay to correlate bitcoin ownership with a single public key.

Every public key has a corresponding 🔑 private key 🔑.

While the public key can be shared, the private key should never be revealed to anyone else.


Let's start by generating a pair of public and private keys to see what they look like.

Type generateKeys() into the console to create a keypair.

Lesson 2 - Signatures

As you can see, public and private keys can look like big strings of letters and numbers. These ones are encoded in hexadecimal.

You'll see hex used a lot. You don't necessarily need to know how it works, just that it's a way to represent data. It's much easier for humans to look at and recognize hex than a bunch of 1's and 0's!

It turns out you can do some pretty cool stuff with public and private keys.

A private key can be used to sign some data and create a 🖋️ digital signature 🖋️.

The public key is then used to check that the signature is authentic. Was it really signed by who you think?

This means you can digitally sign a piece of data, and anyone who has your public key can verify the signature really came from you.


The private key you just generated has been saved to a variable called privateKey. Now, anytime you type privateKey, the program will know you are referring to that long string of letters and numbers that represent your private key.

Let's create a digital signature by signing a message. Type signMessage(privateKey, 'any message') into the console. You can change the any message part to something more exciting (just make sure you keep the quotation marks!).

After you press enter, the digital signature will be returned.

Lesson 3 - Signature Verification

Nice work! We've created a digital signature using the private key. Now we can use the corresponding public key to verify the signature's authenticity.


Similar to the previous lesson, this tutorial has automatically saved the publicKey,message and signature values to variables of the same name.

That means all you need to do is type verifySignature(publicKey, message, signature) to verify that the signature came from the private key we think it did.

Lesson 4 - Hashing

As expected, the signature is valid!

Digital signatures like these are among the most important technologies at the heart of Bitcoin. Spending bitcoin is actually the act of signing a message—a message to transfer ownership.

You may have heard about the importance of protecting your (private) keys. This is why! Anyone that has access to them can sign messages on your behalf, messages that transfer ownership, aka spend, your bitcoin.

Another essential, and related part of Bitcoin is #️⃣ hashing #️⃣.

Hashing is kind of like creating a digital fingerprint for a piece of data.

It all starts with a function, a hash function, that always returns outputs, or hashes of a certain size. This is true no matter how big or small the input is.

  • Just like fingerprints, hashes are unique. Barring some exceptional circumstances, the hashes for two different things should never be the same.
  • Hash functions are one way streets. You can't reverse engineer a hash and figure out the data used to make it.
  • Hashes are extremely reliable in the sense that they are deterministic. This means you can hash the same piece of data over and over again and you'll always get the same result.


Example

I've taken the phrase "Cypherpunks write code" and sent it through a hash function, represented by that sparkly black box. On the right, out pops a string of letters and numbers.

This probably doesn't look that exciting. The resulting hash is actually longer than the phrase that was input, and it's now completely indecipherable. But what if we tried hashing something longer? What about hashing the first paragraph of the Bitcoin whitepaper?

Look at that! That long paragraph has been reduced to a unique string of letters and numbers. As expected, it's totally different than the hash for "Cypherpunks write code", yet the two hashes are the same length.

You see hashes all over Bitcoin, from transaction IDs, to address creation, to scripts that define particular spending conditions. Oftentimes, a piece of information will be reduced to its hash to save space.


Let's test the deterministic property of hash functions. Make a mental note of the hash in the first picture, the hash of "Cypherpunks write code".

We're going to regenerate this hash ourselves. Type hash('Cypherpunks write code') to see that the hash is the same as the example.

Lesson 5 - Addresses

The hashes match! Now that we know about public/private keypairs and hashing, we can begin to understand what it means to receive bitcoin. When you want to receive some, you provide an 📪 address 📪 for someone to send it to.

Here's an example of one: 2NEwkTybLpYyaRooBFMXAJDtchRdA8FMM4G

Yes, I know, another random looking string of letters and numbers... but it's actually a hash!

To put it in simple terms, addresses are hashes of public keys. Remember earlier when we learned bitcoin ownership is correlated to public keys? This is how.

For advanced applications, addresses can correspond to multiple public keys. This is made possible by something called scripts, but that's beyond the scope of this tutorial.

We know from the previous lesson that you cannot go backwards with hashes. If someone gives you an address, you cannot reverse engineer the public key used to create it.


Try generating an address for yourself! Type createAddress(publicKey). This will invoke the createAddress() function with the public key that you created earlier.

Lesson 6 - Transactions and Coins

There's the address!

At this point I must state the obvious. Do not send any bitcoin to this address. You will never see it again. In the words of Bitcoin's anonymous creator, Satoshi Nakamoto,

"Lost coins only make everyone else's coins worth slightly more. Think of it as a donation to everyone."

The movement of bitcoin is tracked by 🧾 transactions 🧾. If Alice has one bitcoin and wants to send it to you, the transaction would look something like this:

You'll see the transaction is divided into two parts, the ⬇️ input ⬇️ and ⬆️ output ⬆️.


This is similar to double entry bookkeeping, a practice popular with Italian merchants in the 14th century. Their ledgers had two columns, one for debits and one for credits.

The input part of the transaction is like the "debit" column and the output part is like the "credit" column.

Source: Christopher Watrous' account book, Debits and Credits for Vincent Stillwill accounts, Durham, Connecticut, 1817


In our example there is only one input (Alice's one bitcoin) and one output (now your bitcoin). What if Alice had 10 bitcoin? If she only wants to give you one, she must specify the remaining 9 will be returned to her as change.

Here's what that transaction looks like:

If Alice didn't specify she wanted change back, the remaining 9 bitcoin would have gone to people we call miners (more on that later)!

The dollar bill analogy

As you see, this transaction has one input and two outputs.

Inputs and outputs are a little like dollar bills. They can't be broken up without a transaction. If Alice only has a $10 bill and wants to give you $1, she can't make change on her own. She can't rip off 1/10th of the bill and give it to you. She needs to create some kind of a transaction, maybe with a cash register, and use the $10 bill as input.

Things start to differ from traditional money (aka fiat) when we look at denominations. In Bitcoin, you can have a "bill" in any denomination. For this analogy, Alice would actually recieve a $9 bill back as change.

Inputs and outputs, Alice's 10 bitcoin input, her 9 bitcoin change, and your 1 bitcoin are often called 🪙 coins 🪙.

It seems simple, but remember that a "coin" can be any denomination of bitcoin. It doesn't have to be 1 bitcoin. It can be 21 bitcoin, or fractions of a bitcoin like 0.1.

You'll hear "coin" used a lot when people talk about privacy.


The "official" Bitcoin software, the reference implementation, is something called Bitcoin Core. Bitcoin Core has a bunch of commands you can use to manage your bitcoin.

If we play out the example where Alice sends us one bitcoin, we can use the getbalance command to see that the money was received.

Type bitcoin-cli getbalance into the console.

Lesson 7 - Transaction Signing

The balance is correct! Now consider the scenario where Bob also sends you 1 bitcoin (lucky you!).

For privacy reasons, address reuse is not advised. We'll be making new addresses where needed in the following examples.

Details on how you can generate a range of new addreses is outside the scope of this tutorial. You can learn more by checking out BIP 32.

You create a new address to give to Bob, one that is different from what you gave to Alice.

Bob sends you a bitcoin, just like Alice did in the previous lesson. Now you have 2 bitcoin.

You'd like to purchase something from your friend Hal for 1.5 bitcoin. You do this by creating a transaction like this:

  • The two inputs are the bitcoin you received from Alice and Bob.
  • The first output sends 1.5 bitcoin to Hal
  • The second output returns the 0.5 bitcoin change back to you, to a new address.

This transaction is almost good to go, except for one very important thing!

Earlier we learned that in order to spend bitcoin, you must sign a message that authorizes the transfer of funds. This is how you prevent others from spending your bitcoin. The message that you sign is actually the transaction!

In previous examples both Alice and Bob had to sign their transactions when they sent you bitcoin.

Transactions have a special area where the spender adds their digital signature. This field is named scriptSig, though there are lots of special cases and rules for it that we won't be covering. For now, all we need to remember is:

1. signatures go in the scriptSig field, and

2. transactions aren't complete until they are signed.


Below is the raw data for our transaction. We can see the two scriptSig fields (one for each input) are empty. They have no signatures inside them.

If we try to broadcast this transaction out to the Bitcoin network as-is, it would be rejected. The transaction needs to be signed.


We'll be using a signTransaction() function for this. It's similar to the signMessage() call made earlier, but the data being signed is different. Instead of accepting any arbitrary message, this accepts a transaction. It then creates the appropriate number of signatures, one per input.

The raw transaction we looked at above has been saved to the transaction variable.

Type signTransaction(privateKey, transaction) into the console to sign the transaction.

Lesson 8 - Broadcasting a Transaction

See those values in the scriptSig fields? That means the transaction has been signed!

Now we can go ahead and 📣 broadcast 📣 it. This means giving the transaction to a Bitcoin node. The node will then propogate it to the rest of the nodes in the network.

Each Bitcoin node has a set of peers it regularly "talks" to. When a node hears about a new transaction, it shares it with its peers.

It only takes a few minutes for a transaction to make it to the rest of the Bitcoin network! At the time of writing, there are over 15,000 Bitcoin nodes worldwide.

We'll be using that same Bitcoin Core software from earlier to do the broadcast. The command name is sendrawtransaction and it accepts the transaction in hexadecimal format.

The conversion to hex has already been done for you, but you will notice that it comes out to be quite a long string of letters and numbers! Copy the following command and run it in the console:

Lesson 9 - Waiting for Confirmations

Look at that! After a successful broadcast, the Bitcoin Core client returns the transaction ID.

Since this is just an educational exercise, we can't do much with the transaction ID, but if it were real we'd be able to look up the transaction in a block explorer and see all kinds of detail about it.

Now that the rest of the network knows about your transaction, it's almost finalized, but there's one more step: ⚒️ mining ⚒️!

This is where the "block" part of the Bitcoin blockchain comes in. After you broadcast a transaction, it goes to a special holding area called the 🏊 mempool 🏊.

Unconfirmed transactions hang out here, waiting to be picked up by a miner and put into a block.

The mempool is not a single centralized place. Every node has its own mempool. After a transaction is broadcast, and before it's mined, it sits in the mempools of every node that has been made aware of the transaction.

Roughly every ten minutes, a miner will take a bunch of unconfirmed transactions from their copy of the mempool and put, or "mine" them into a block.


Fees

The likelihood of your transaction making it into the next block depends on the other transactions in the mempool and the fees you choose to pay.

We didn't explicitly cover fees, but learned a little about them when looking at change outputs. Remember the example where Alice had 10 bitcoin and wanted to send you one? She had to specify the remaining 9 should be returned back to her, otherwise they would have been considered fees! Fees go to the miner that creates the block.

Any amount of bitcoin that is "left over" in a transaction is considered to be the fee.

In the previous example if Alice decides to only return 8.5 bitcoin to herself, then 0.5 bitcoin would be the transaction fee. The math checks out: the total transaction input is 10 (Alice's 10 bitcoin), and the total output is 9.5 (1 to you, and 8.5 back to Alice as change).

In the early days of Bitcoin, transactions didn't need to pay fees, but as Bitcoin matures, fees are increasingly important.

For our exercise we'll consider the case where some time has passed and the transaction we broadcast in the previous lesson has been mined. It's made its way into a block.

How would we know this? We could periodically ask a Bitcoin node, or use one of the block explorers mentioned earlier to monitor the blockchain and see when a particular transaction is mined.


The last thing to do is check our balance one more time to make sure it's accurate and reflects the 1.5 bitcoin sent to our friend Hal in the previous lesson.

You can do that with the same bitcoin-cli getbalance command from an earlier lesson. We're expecting to see a remaining balance of 0.5 bitcoin.

That's all for now!

The balance is correct! We started with 2 bitcoin (one from Alice, and one from Bob), sent 1.5 to our friend Hal, and had 0.5 returned.




Thank you for checking out this little tutorial. If you wish to do it again, you can use the reset command.

The fun doesn't have to stop here! You're now ready to venture futher down the rabbit hole. Here are some of my favorite resources to continue learning about Bitcoin:


General resources

  • Hello Bitcoin: Your one stop shop for the basics. Covers a wide range of topics from economic empowerment and financial freedom to energy consumption and the peer-to-peer network. If you want to learn more about Bitcoin, but aren't jazzed about looking at more technical stuff. This is the place for you!
  • Bitcoin Money: A Tale of Bitville Discovering Good Money by Michael Caras: This is an adorable childern's book about Bitcoin, but I recommend it to all ages!
  • 6 week virtual seminars with Chaincode Labs: Need some external motivation? Want to learn with friends? Chaincode makes it fun and rewarding! These seminars are for all levels, you just need to be able to commit to 4-6 hours a week.
  • Mastering Bitcoin by Andreas Antonopoulos [free digital version]: This is the OG Bitcoin textbook and a must read for anyone that wants to build on top of or contribute to Bitcoin.
  • Learning Bitcoin from the command line by BlockChain Commons: Are you a command line wizard? Does the thought of using a GUI make you yawn? Do you refuse to go anywhere unless you can take your shell candy with you? BlockChain Commons is here for you. Learn your way through Bitcoin without ever having to leave the comfort of your terminal!
  • Still haven't found something for you? https://bitcoin.page has every type of Bitcoin resource you could ever want on every facet of Bitcoin you can think of. From podcasts, to videos, to statistics, to security, to art & music, this page it all. I have yet to see a quality resource that isn't on this comprehensive list, but if you manage to find something missing, PRs (pull requests) are always welcome!

Bitcoin Core Development:

For those that like drinking from the firehose and being thrown off the deep end, here's where you can go to learn more about Bitcoin Core.

Enter commands here