Cách nhanh nhất để tìm hiểu cách hoạt động của Blockchain là tự tay xây dựng nó.
Bạn bị choáng ngợp bởi sự tăng giá của tiền điện tử Bitcoin? Bạn muốn “hiểu rõ” cách hoạt động của Blockchain – công nghệ nền tảng đằng sau Bitcoin nhưng mọi thứ chỉ giới hạn ở việc “biết” vì chỉ có thể lướt qua các bài viết và video hướng dẫn về Blockchain mà không có ví dụ cụ thể.
Bài viết này sẽ cùng bạn tạo ra 1 blockchain của chính bạn. Nếu làm theo đến phần cuối của hướng dẫn này, bạn sẽ tự khởi tạo được 1 blockchain hoạt động được và nắm được cách chúng hoạt động.
Trước khi bắt đầu…
Hãy nhớ rằng một blockchain là một chuỗi bất biến tuần tự, các hồ sơ được gọi là các “khối”. Chúng có thể chứa các giao dịch, file hoặc bất kỳ dữ liệu nào bạn thích. Nhưng điều quan trọng là chúng được liên kết với nhau bằng cách sử dụng hàm băm (hash).
Nếu bạn chưa nắm rõ sơ lược về Blockchain, đây là bài viết dành cho bạn.
Hướng dẫn dành cho ai? Những bạn có thể đọc và viết code Python cơ bản và có hiểu biết về HTTP request, vì chúng ta sẽ thao tác với Blockchain thông qua giao thức HTTP.
Cần chuẩn bị những gì? Python 3.6+ cùng với pip
. Ngoài ra bạn cần cài đặt thư viện Request và Flask.
pip install Flask==0.12.2 requests==2.18.4
Nếu bạn đang sử dụng môi trường Windows, bạn có thể truy cập trực tiếp vào python.org để tải xuống phiên bản Python mới nhất.
Xây Dựng Blockchain
Bước 1: Tạo Blockchain
Mở Text Editor hoặc IDE yêu thích của bạn, tạo 1 file mới là blockchain.py
. Tham khảo mã nguồn tại đây. Đầu tiên là tạo lớp blockchain
.
Giới thiệu về lớp Blockchain
Lớp blockchain
chịu trách nhiệm quản lý chuỗi. Nó sẽ lưu trữ giao dịch và có một số phương pháp để thêm các block mới vào chuỗi. Chúng ta sẽ tạo 2 lớp blockchain
. Lớp blockchain
thứ nhất có hàm khởi tạo tạo ra 1 danh sách trống ban đầu để lưu trữ blockchain. Lớp còn lại sẽ lưu trữ giao dịch. Dưới đây là bản thiết kế cho lớp blockchain
của chúng ta:
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_transaction(self):
# Adds a new transaction to the list of transactions
pass
@staticmethod
def hash(block):
# Hashes a Block
pass
@property
def last_block(self):
# Returns the last Block in the chain
pass
Xác định Block
Tiếp theo, chúng ta sẽ xác định các block trông như thế nào. Mỗi block sẽ có các thông tin sau:
- Index
- Timestamp
- Transactions
- Proof-Of-Work (PoW)
- Previous hash
Ví dụ về một block:
block = {
'index': 1,
'timestamp': 1506057125.900785,
'transactions': [
{
'sender': "8527147fe1f5426f9dd545de4b27ee00",
'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
'amount': 5,
}
],
'proof': 324984774000,
'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}
Khi xác định block trông như thế nào, ý tưởng về blockchain đã phải thật rõ ràng – mỗi block mới chứa hash function (hàm băm) của khối trước đó. Đây là yếu tố quyết định cho tính bất biến của blockchains. Nếu kẻ tấn công làm hỏng một block trước đó trong chuỗi thì tất cả các khối tiếp theo sẽ chứ hàm băm không chính xác.
Thêm giao dịch vào một block
Chúng ta sẽ sử dụng phương thức new_transaction()
để thêm giao dịch vào 1 block:
class Blockchain(object):
...
def new_transaction(self, sender, recipient, amount):
"""
Creates a new transaction to go into the next mined Block
:param sender: <str> Address of the Sender
:param recipient: <str> Address of the Recipient
:param amount: <int> Amount
:return: <int> The index of the Block that will hold this transaction
"""
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.last_block['index'] + 1
Sau khi phương thức new_transaction()
thêm giao dịch vào danh sách, nó trả về index của block mà giao dịch sẽ được thêm vào.
Tạo block mới
Khi lớp blockchain
được khởi tạo, chúng ta sẽ cần thêm khối genesis (khối đầu tiên) vào chuỗi. Ngoài ra, chúng ta sẽ cần thêm một proof vào khối genesis. Chúng ta sẽ tạo các phương thức new_block()
, new_transaction()
và hash()
như sau:
import hashlib
import json
from time import time
class Blockchain(object):
def __init__(self):
self.current_transactions = []
self.chain = []
# Create the genesis block
self.new_block(previous_hash=1, proof=100)
def new_block(self, proof, previous_hash=None):
"""
Create a new Block in the Blockchain
:param proof: <int> The proof given by the Proof of Work algorithm
:param previous_hash: (Optional) <str> Hash of previous Block
:return: <dict> New Block
"""
block = {
'index': len(self.chain) + 1,
'timestamp': time(),
'transactions': self.current_transactions,
'proof': proof,
'previous_hash': previous_hash or self.hash(self.chain[-1]),
}
# Reset the current list of transactions
self.current_transactions = []
self.chain.append(block)
return block
def new_transaction(self, sender, recipient, amount):
"""
Creates a new transaction to go into the next mined Block
:param sender: <str> Address of the Sender
:param recipient: <str> Address of the Recipient
:param amount: <int> Amount
:return: <int> The index of the Block that will hold this transaction
"""
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.last_block['index'] + 1
@property
def last_block(self):
return self.chain[-1]
@staticmethod
def hash(block):
"""
Creates a SHA-256 hash of a Block
:param block: <dict> Block
:return: <str>
"""
# We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
block_string = json.dumps(block, sort_keys=True).encode()
return hashlib.sha256(block_string).hexdigest()
Proof-Of-Work là gì
Thuật toán PoW là cách các blockchain mới được tạo ra hoặc khai thác trên blockchain. Mục tiêu của PoW là tìm một con số (sao cho ai cũng có thể xác minh nhưng lại khó tìm ra) để giải quyết 1 vấn đề nào đó. Chúng ta sẽ xem xét 1 ví dụ đơn giản để hiểu sâu về vấn đề này.
Mã băm của số nguyên x * y
phải kết thúc bằng 0
. Khi đó, mã băm có dạng:
hash(x * y) = ac23dc...0
. Giờ chúng ta sẽ thử với x=5
.
Triển khai bằng Python:
from hashlib import sha256
x = 5
y = 0 # We don't know what y should be yet...
while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":
y += 1
print(f'The solution is y = {y}')
Giải pháp ở đây là y = 21
. Kể từ đó, hàm băm được tạo ra kết thúc bằng 0
.
hash(5 * 21) = 1253e9373e...5e3600155e860
Trong Bitcoin, thuật toán PoW được gọi là Hashcash. Đây là thuật toán mà các miners cần giải quyết để tạo ra 1 block mới.
Độ khó ở đây là số lượng ký tự được tìm kiếm trong một chuỗi. Những miners sau đó sẽ nhận được 1 coin như là phần thưởng cho giải pháp của họ – trong một giao dịch.
Triển khai Bằng chứng công việc (Pow) cơ bản
Hãy triển khai một thuật toán tương tự cho blockchain của chúng ta. Quy tắc sẽ tương tự như ví dụ trên:
Tìm một số p mà khi băm với mã băm của khối trước đó tạo ra một mã băm có 4 số
0
đứng đầu.
import hashlib
import json
from time import time
from uuid import uuid4
class Blockchain(object):
...
def proof_of_work(self, last_proof):
"""
Simple Proof of Work Algorithm:
- Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
- p is the previous proof, and p' is the new proof
:param last_proof: <int>
:return: <int>
"""
proof = 0
while self.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?
:param last_proof: <int> Previous Proof
:param 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"
Để điều chỉnh độ khó của thuật toán, chúng ta có thể sửa đổi số lượng các số 0 đứng đầu. Ở đây chúng ta sẽ để 4 số. Lớp blockchain
của chúng ta gần như đã hoàn thành và đã có thể tưởng tác bằng cách sử dụng các HTTP Request.
Bước 2: Tích hợp API
Vậy là blockchain của chúng ta đã hoạt động, giờ chúng ta cần tạo 1 API để sử dụng blockchain hiệu quả.
Chúng ta sẽ sử dụng một micro-framework là Python Flask Framework. Framework này giúp dễ dàng ánh xạ các điểm cuối (endpoint) đến các hàm Python. Điều này cho phép chúng ta làm việc với blockchain bằng cách sử dụng các HTTP request.
Chúng ta sẽ tạo ba điểm cuối:
/transactions/new
để tạo một giao dịch mới cho một khối./mine
để yêu cầu máy chủ của chúng ta khai thác một khối mới./chain
để trả lại toàn bộ Blockchain.
Cấu hình Flask
“Máy chủ” của chúng ta sẽ tạo thành một nút duy nhất trong mạng blockchain của chúng ta. Hãy tạo bộ khung code như sau:
import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4
from flask import Flask
class Blockchain(object):
...
# Instantiate our Node
app = Flask(__name__)
# Generate a globally unique address for this node
node_identifier = str(uuid4()).replace('-', '')
# Instantiate the Blockchain
blockchain = Blockchain()
@app.route('/mine', methods=['GET'])
def mine():
return "We'll mine a new Block"
@app.route('/transactions/new', methods=['POST'])
def new_transaction():
return "We'll add a new transaction"
@app.route('/chain', methods=['GET'])
def full_chain():
response = {
'chain': blockchain.chain,
'length': len(blockchain.chain),
}
return jsonify(response), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
- Dòng 15: Khởi tạo nút. Đọc thêm về Flask tại đây.
- Dòng 18: Tạo một tên ngẫu nhiên cho nút.
- Dòng 21: Khới tạo lớp Blockchain.
- Dòng 24–26: Tạo điểm cuối /mine sử dụng phương thức GET.
- Dòng 28–30: Tạo điểm cuối /transactions/new sử dụng phương thức POST, vì chúng ta sẽ gửi dữ liệu đến đó.
- Dòng 32–38: Tạo điểm cuối /chain sử dụng phương thức GET để trả về toàn bộ Blockchain.
- Dòng 40–41: Khởi chạy máy chủ trên cổng 5000.
Điểm cuối giao dịch
Dưới đây là dữ liệu (nội dung) của một yêu cầu cho một giao dịch. Đó là những gì người dùng gửi đến máy chủ:
{
"sender": "my address",
"recipient": "someone else's address",
"amount": 5
}
Vì chúng ta đã có phương thức để thêm giao dịch vào 1 block, giờ chúng ta sẽ viết hàm để thêm giao dịch:
import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4
from flask import Flask, jsonify, request
...
@app.route('/transactions/new', methods=['POST'])
def new_transaction():
values = request.get_json()
# Check that the required fields are in the POST'ed data
required = ['sender', 'recipient', 'amount']
if not all(k in values for k in required):
return 'Missing values', 400
# Create a new Transaction
index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
response = {'message': f'Transaction will be added to Block {index}'}
return jsonify(response), 201
Điểm cuối khai thác
- Tính toán Pow.
- Tạo block mới bằng cách thêm nó vào chuỗi (chain).
- Thưởng cho miner (ở đây chính là chúng ta) bằng cách thêm một giao dịch cấp cho chúng ta 1 coin.
import hashlib
import json
from time import time
from uuid import uuid4
from flask import Flask, jsonify, request
...
@app.route('/mine', methods=['GET'])
def mine():
# We run the proof of work algorithm to get the next proof...
last_block = blockchain.last_block
last_proof = last_block['proof']
proof = blockchain.proof_of_work(last_proof)
# We must receive a reward for finding the proof.
# The sender is "0" to signify that this node has mined a new coin.
blockchain.new_transaction(
sender="0",
recipient=node_identifier,
amount=1,
)
# Forge the new Block by adding it to the chain
previous_hash = blockchain.hash(last_block)
block = blockchain.new_block(proof, previous_hash)
response = {
'message': "New Block Forged",
'index': block['index'],
'transactions': block['transactions'],
'proof': block['proof'],
'previous_hash': block['previous_hash'],
}
return jsonify(response), 200
Lưu ý rằng người nhận block đã khai thác là địa chỉ nút của chúng ta. Hiện tại, mọi thứ đã hoàn tất và chúng ta có thể bắt đầu tương tác với blockchain.
Bước 3: Tương tác với Blockchain
Bước cuối cùng là tương tác với blockchain. Chúng tôi sẽ sử dụng Postman để tương tác với Blockchain bằng cách sử dụng API mà chúng ta vừa tạo.
Chạy code bên dưới trên Python Console:
$ python blockchain.py
Kết Luận
Vậy chúng ta đã đến phần cuối của hướng dẫn. Hy vọng rằng hướng dẫn này sẽ truyền cảm hứng cho bạn để bắt đầu một dự án mới, hoặc đơn giản là giúp bạn có thêm động lực khi bước vào thế giới blockchain.
Nguồn tham khảo: