Would you, like me, be very interested in encrypting the block-chain technology at the bottom of the digital currency, especially to understand how they operate.
But learning block chain technology is not plain sailing, I see a lot of video tutorials and a variety of courses, the ultimate feeling is that the actual combat courses available are too few.
I like to learn in practice, especially like a code based to understand the whole work mechanism. If you and I like this way of learning, when you finish this tutorial, you will know how the block chain technology works. write before you start
Remember, the block chain is an immutable, orderly chain of records called blocks. They can contain transactions, files, or any data that you like. But the important thing is that they are linked together with hashes.
If you are unfamiliar with hashing, here is an explanation.
What is the purpose of the guide? You can comfortably read and write the basics of Python, as we will discuss HTTP with the block chain, so you also need to understand how HTTP works.
What do I need to prepare? Make sure you have the Python 3.6+ (and PIP) installed, you will also need to install flask, Requests libraries:
Pip Install flask==0.12.2 requests==2.18.4
Yes, you also need a client that supports HTTP, such as Postman or CURL, and so on.
Where is the source code? You can click here Step 1: Create a block chain
Open your favorite text editor or IDE, I personally prefer pycharm. Create a new file named blockchain.py. We'll just use this one file. But if you are still not clear, you can also refer to the source code. Description block Chain
We're going to create a blockchain class whose constructor creates an initialized empty list (to store our chunk chain) and another store transaction. Here is an example of our class:
blockchain.py
class Blockchain (object):
def __init__ (self):
self.chain = []
self.current_ transactions = []
def new_block (self):
# Creates a new block and adds it to the chain
pass
def New_transac tion (self):
# Adds A new transaction to the list of transactions
pass
@staticmethod
def Hash (block): c12/># hashes a block
pass
@property
def last_block (self):
# Returns of the last blocks in the chain
pass
Our Blockchain class is responsible for managing chained data, which stores transactions and also adds new chunks to the chained data method. Let's start by expanding more method blocks .
Each block has an index, a timestamp (Unix timestamp), a transaction list, a checksum (detailed later), and a hash of the previous block.
Here is an example of a block:
blockchain.py block
= {
' index ': 1,
' timestamp ': 1506057125.900785,
' transactions ': [
{
' Sender ': "8527147fe1f5426f9dd545de4b27ee00",
' recipient ': "a77f5cdfa2934df3954a5c7c7da5df1f",
' Amount ': 5 ,
}
],
' proof ': 324984774000,
' Previous_hash ': " 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 "
}
At this point, the concept of a block chain should be obvious-each new block is contained in the hash of the previous block. This is essential because this is the reason that the block chain cannot be changed: If an attacker damages an earlier block in the block chain, all subsequent blocks will contain an incorrect hash value.
Does that make sense? If you haven't figured it out, take the time to think about it-this is the core idea behind the block chain. Add deals to blocks
We will need a way to add transactions to the block. This is the responsibility of our new_transaction () method, and it is very simple:
blockchain.py
class Blockchain (object): ...
def new_transaction (self, sender, recipient, amount): "" "
creates a new transaction to go into the next mined bloc K
:p Aram Sender: <str> address of the sender
:p Aram recipient: <str> address of the recipient
:p AR Am Amount: <int> Amount: Return: <int> The index of the ' block ' that would
hold this transaction
""
self.current_transactions.append ({
' sender ': sender,
' recipient ': Recipient,
' Amount ': Amount,
})
Return self.last_block[' index '] + 1
The New_transaction () method adds a transaction to the list, which returns the index of the chunk that the transaction will be added to---talk mining next this is useful for users who submit transactions later. Create a new block
When our blockchain is instantiated, we need to add the Genesis block (a block without a leading block). We also need to add a proof to our Origin block, which is the result of the mining (or work proof). We will discuss the ore digging in detail later.
In addition to creating a Genesis block in a constructor, we also complement the full New_block (), New_transaction (), and hash () functions:
blockchain.py Import hashlib Import JSON from time Import time class Blockchain (object): Def __init__ (self): Self.current_transactions = [] Self.chain = [] # Create Genesis Block Self.new_block (Previous_hash=1, proof=10 0 def new_block (self, Proof, Previous_hash=none): "" "Create a new chunk into the block chain:p Aram Proof: <int> ;
Proof generated by Work proof algorithm:p Aram Previous_hash: (Optional) <str> hash value of previous block: return: <dict> new block "" "block = {' index ': Len (self.chain) + 1, ' timestamp ': Time (), ' transaction S ': self.current_transactions, ' proof ': proof, ' previous_hash ': Previous_hash or Self.hash (self.ch Ain[-1]),} # Reset Current transaction self.current_transactions = [] self.chain.append (block) r Eturn Block def new_transaction (self, sender, recipient, amount): "" Creates a new transaction into the next excavated chunk:p a Ram Sender: <str> Sender's address:p Aram recipient: <str> Recipient's address:p Aram Amount: <int> Amount: Return: <int> hold this Sub-transaction block index "" "Self.current_transactions.append ({' sender ': sender, ' recipient ': rec Ipient, ' Amount ': Amount,}) return self.last_block[' index ' + 1 @property def last_
Block (self): return self.chain[-1] @staticmethod def hash (blocks): "" To generate SHA-256 values for a chunk :P Aram Block: <dict> Block:return: <str> "" "# we have to make sure that the dictionary (block) is sorted, otherwise we will get no Consistent hash block_string = Json.dumps (block, sort_keys=true). Encode () return hashlib.sha256 (block_string). Hexdig
EST ()
The code above should be straightforward---I added some comments and documentation to make the code clear. We have almost finished our block chain. But at this point you must be wondering how the new block was created, forged or dug. Work Proof Algorithm
Use the work proof (PoW) algorithm to prove how to create or excavate new chunks on a block chain. The goal of PoW is to compute a number that meets certain criteria, which must be very difficult to compute for all, but easy to verify. This is the core idea behind the work certificate.
We'll see a simple example to help you understand:
Suppose the hash value of an integer x multiplied by the product of another integer y must end with 0, i.e. hash (x * y) = AC23DC ... 0. Set x = 5, and Y. Implemented in Python:
From hashlib import sha256
x = 5
y = 0 # We don ' t know what y should to be yet ...
While sha256 (f ' {x*y} '. Encode ()). Hexdigest () [-1]!= "0":
y + + 1
print (f ' the solution is y = {y} ')
The result is: y = 21. Because the resulting Hash value must end in 0.
Hash (5 *) = 1253e9373e ... 5e3600155e860
In Bitcoin, the work proof algorithm is called Hashcash, which is similar to the above problem, except that it is very difficult to compute. This is the problem that miners are scrambling to calculate in order to scramble for the right to create blocks. In general, the calculation difficulty is proportional to the number of specific characters that the target string needs to satisfy, and the miner calculates the result and obtains a certain amount of bit-currency rewards (through the transaction).
Verifying the results, of course, is very easy. achieve work Proof
Let's implement a similar PoW algorithm. The rule is similar to the above example:
Finds a number P, which proof the Hash value of the string that it is stitching into with the previous block to start with 4 0.
blockchain.py Import hashlib Import JSON from time Import/from UUID Import Uuid4 class Blockchain (object):..
. def proof_of_work (self, Last_proof): "" "simple proof of the work algorithm:-Find a number p ' such That hash (pp ") contains leading 4 zeroes, where P is the previous P '-P's is the previous proof, and P ' is the new Proof:p Aram Last_proof: <int>: return: <int> "" proof = 0 while SE Lf.valid_proof (Last_proof, proof) is False:proof + 1 return proof @staticmethod def valid_
Proof (Last_proof, proof): "" Validates the Proof:does hash (last_proof, proof) contain 4 leading zeroes? :p Aram Last_proof: <int> Previous proof:p Aram Proof: <int> current Proof:return:
;bool> True If correct, False if not. "" "Guess = f ' {last_proof}{proof} '. Encode () Guess_hash = hashlib.sha256 (guESS). Hexdigest () return guess_hash[:4] = = "0000"
The way to measure the complexity of an algorithm is to modify the number of 0 starts. Using 4 for the demo, you'll find that one more 0 will greatly increase the time it takes to calculate the results.
Now that the Blockchain class is basically complete, the next step is to use the HTTP requests to interact. Step 2:blockchain as API interface
We'll use the Python flask Framework, a lightweight Web application framework that facilitates mapping network requests to Python functions, and now lets blockchain run on the flask Web.
We will create three interfaces:
/transactions/new Create a transaction and add it to the block
/mine told the server to dig up new blocks.
/chain return entire block chain create node
Our "Flask Server" will act as a node in the block chain network. Let's add some framework code first:
blockchain.py Import hashlib Import json from textwrap import dedent to time import from UUID import Uuid4 from Flask Import Flask Class Blockchain (object): ... # instantiate our Node app = Flask (__name__) # Generate a globally Unique address to this node Node_identifier = str (UUID4 ()). Replace ('-', ') # instantiate the blockchain blockchain = B Lockchain () @app. Route ('/mine ', methods=[' Get ']) def mine (): Return "We'll mine a new block" @app. Route ('/transactio Ns/new ', methods=[' POST ') def new_transaction