- Hello world, it's Siraj.
Today, we're gonna build a blockchain
in five minutes using Python.
Ready? Let's get started.
A block is a data structure that
contains data and some attributes.
Blocks can be linked together to form a chain of blocks.
This is called a blockchain.
The Bitcoin protocol uses a blockchain data structure
to store transaction data,
but we can store any kind of data in a blockchain.
To understand how it works,
let's code our own in the browser together
using Google's Colab environment.
We'll also periodically view a blockchain demo
in the browser as well, while we code,
for better comprehension.
This will be a four step process.
Import our dependencies, create a block,
create a blockchain, then print out the blockchain.
First, we'll want to import datetime
so that we can generate timestamps for each block.
We'll also import hashlib since
it contains an important alogorithm
we'll use to define our block.
We can define our block as a Python class,
then define its attributes.
Each block has seven attributes,
and we can list each as a distinct variable.
First, the number of the block so we can index each of them.
Next, the data we'll store in this block.
Bitcoin's blockchain stores transactions in here,
but we'll just store text strings in here for simplicity.
We'll define a pointer to the next block,
as well as the hash of this block.
A hash is a function that converts data
into a number within a certain range.
The hash serves as both a unique identifier for a block,
and verifies its integrity.
More on that in a second.
We'll define a nonce, or a number only used once.
We'll later use it to compute a unique hash for our block.
Then, we'll define a previous hash,
which will store the hash of the
previous block in the blockchain
when we actually build a blockchain.
Lastly, we'll define a timestamp for a block
using the datetime library.
Now that we've defined our attributes,
we can write the in it function for our class.
It defines how we initialize a block,
using some provided data as the only parameter.
We'll also need to define a has function for a block.
The hashlib library contains the popular sha256 algorithm,
which generates a unique 256 bit signature
that represents some piece of text.
The input to our algorithm will be a concatenated string
that consists of five of our block attributes.
See how a hash is created using
the unique attributes of a block?
This means that if someone tries
to change the hash of a block in a chain of blocks,
every block after it is changed
since each block's hash is generated, in part,
using the hash of the previous block.
Before we finish our block class,
let's write a small print function
that will print out the value of a block.
Now that we've defined our block class,
we can define our blockchain class.
We'll define two key attributes
of our chain of blocks, or blockchain, first.
The genesis block and the head.
The genesis block is what we call
the first block in a blockchain,
and we'll store the string genesis inside of it.
The head will be the newest addition to our block.
As we add more blocks to our chain,
this head will be updated.
Speaking of adding blocks, let's write our add function.
This will add a given block to the chain of blocks.
The block to be added is the only parameter we'll need.
Blockchains are just glorified, linked lists.
We can set the hash of a given block
as our new block's previous hash,
and set the block number of our new block
as the given block's number plus one,
since it's next in the chain.
Then, we'll set the next block equal to itself.
This is the new head of the blockchain.
We now have one more function to write, the mining function.
This is what lets nodes in a network
that don't necessarily know each other
come to consensus on what the one
true chain of blocks look like,
a chain that is immutable.
It requires computing power to mine a block.
This is a defense mechanism.
In Bitcoin's blockchain, an attacker would need
the majority of the computing power in the network
to modify a block and give themselves money
they don't rightfully have.
In the Bitcoin network, 51% of the computing power
is more computing power than the 500 fastest
super computers in the world combined,
and since no one has anything close
to that much computing power,
the network has survived for almost a decade now.
We'll need to define three additional
attributes in our blockchain class,
the maxNonce, which is two to the 32nd.
It's the biggest number we can store in a 32 bit number.
Then, a mining difficulty.
We use the mining difficulty value
to compute our target hash.
It's going to be two to the 256 minus our difficulty.
In our mining function, we'll determine if a given block,
which we'll input as a parameter,
can be added to the blockchain.
For a range of numbers from zero to two to the 32nd,
our maxNonce value will check to see
if the value of the given block's hash
is less than our target value.
This is exactly what Bitcoin's mining function does as well.
If it's less, we'll add that block to the blockchain
and break out of the loop, else we'll increment the nonce
and repeat the process until we reach the end of the loop.
The mining difficulty sets how computationally
expensive it is to mine a block.
The higher the number, the longer it will take to mine,
and the value of the nonce after mining reflects that.
Now that we've defined both classes,
we can initialize a blockchain.
Then, we'll write a loop to mine 10 blocks.
Each of them will be initialized by a unique string.
Finally, we'll print out each block in the blockchain.
If we compile this code, we'll see each block
in our block chain with its associated attributes,
including the unique hash, the data, and the timestamp.
I hope you found this tutorial useful.
Please subscribe for more programming videos,
and for now, I've gotta break the great firewall,
so thanks for watching.