top of page

Học Cách Xây Dựng Blockchains Từ A->Z

Khi bạn bắt đầu tìm hiểu về thuật ngữ Blockchains, chắc hẳn bạn cũng đang rất quan tâm tới sự gia tăng của tiền điện tử. Thế nhưng để hiểu về Blockchains không phải là một điều dễ dàng, bạn sẽ chìm đắm trong một loạt thuật ngữ trước khi bạn có thể hiểu được cách hoạt động và công nghệ cơ bản đằng sau chúng. Cách tốt nhất là tự mình xây dựng một Blockchains để biết được những vấn đề phát sinh và nắm thật rõ ràng. Tham khảo cách xây dựng chi tiết Blockchains từ jt1.vn qua bài viết dưới đây.

Học Cách Xây Dựng Blockchains Từ A->Z

Trước khi bắt đầu

Hãy nhớ rằng Blockchains là một chuỗi bất biến, liên tục của các bản ghi. Chúng có thể chứa các giao dịch, tệp hoặc bất kỳ dữ liệu nào bạn thích, chúng được kết nối với nhau bằng cách sử dụng hashes (hàm băm).


Bạn nên nắm chắc về Python cơ bản, cũng như có một số hiểu biết về cách yêu cầu HTTP hoạt động vì bài viết này sẽ xây dựng Blockchains thông qua HTTP. Đồng thời bạn cũng cần đảm bảo Python 3.6+ (cùng với pip) và Flask và thư viện Requests đã được cài đặt.


Bước 1: Xây dựng Blockchains

Tạo lớp Blockchains

Mở trình soạn thảo văn bản hoặc IDE yêu thích của bạn. Tạo một tệp mới và đặt tên nó là blockchain.py. Bạn cần tạo một lớp Blockchains để xây dựng danh sách trống ban đầu và một lớp khác để lưu trữ các giao dịch.


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

Bằng cách này mà nó có thể lưu trữ các giao dịch và có một số phương thức trợ giúp để thêm các block mới vào chuỗi..

IT JOBS

Cách Block đơn được tạo dựng

block = {

'index': 1,

'timestamp': 1506057125.900785,

'transactions': [

{

'sender': "8527147fe1f5426f9dd545de4b27ee00",

'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",

'amount': 5,

}

],

'proof': 324984774000,

'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"

}


Tại thời điểm này, ý tưởng về một chuỗi cần phải rõ ràng, với mỗi block mới được tạo cần phải nằm trong chuỗi và các hàm băm của block trước đó. Điều này rất quan trọng bởi vì nó có thể mang lại sự bất biến cho Blockchains.


Thêm giao dịch vào một Block

Để thêm các giao dịch mới vào một block cần tới câu lệnh new_transaction().


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


Khởi tạo một Block mới

Ngoài việc tạo khối genesis - khối đầu tiên trong Blockchains, trong hàm tạo cần bổ sung các phương thức cho new_block (), new_transaction () và hash ().


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()

Công việc IT

Xây dựng thuật toán Proof of Work (PoW)

Thuật toán Proof of Work (PoW) là cách các Block mới được tạo hoặc khai thác trên Blockchains. Mục tiêu của PoW là khám phá ra một con số giải quyết vấn đề. Trong Bitcoin, thuật toán PoW được gọi là Hashcash, độ khó được xác định bởi số lượng ký tự được tìm kiếm trong một chuỗi.


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"


Đến đây thì lớp Blockchains đã gần như hoàn tất và có thể tương tác với nó bằng các yêu cầu của HTTP.


Bước 2: Blockchains dưới dạng API

Sử dụng Python Flask Framework, điều này cho phép bạn thao tác với Blockchains qua web bằng các yêu cầu của HTTP.


Tạo dựng 3 cách thức:

/transactions/new để tạo một giao dịch mới cho Block

/mine để truyền tới máy chủ khi dùng một Block mới

/chain để trở về Blockchains đầy đủ


Thiết lập Flask

Máy chủ sẽ trực tiếp tạo thành một điểm nối trong mạng Blockchains. Hãy tạo ra một số mã soạn sẵn:


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)



Điểm cuối giao dịch

{

"sender": "my address",

"recipient": "someone else's address",

"amount": 5

}


Đây là những yêu cầu cho một giao dịch, nó là những gì người dùng gửi tới máy chủ.


Kể từ khi các phương thức cho việc giao dịch được thêm vào Block, bạn chỉ cần viết chức năng và thêm vào 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

Điểm cuối khai thác

Tại điểm cuối khai thác sẽ thực hiện ba nhiệm vụ chính:

Tính toán thuật toán Proof of Work (PoW).

Thưởng cho người dùng bằng cách thêm 1coin vào giao dịch.

Tạo một Block mới bằng cách thêm nó vào chuỗi.


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

Bước 3: Tương tác với Blockchains

Bạn có thể sử dụng cURL hoặc Postman cũ đơn giản để tương tác với API qua mạng.


Để bật máy chủ:

$ python blockchain.py

* Chạy http://127.0.0.1:5000 / (Nhấn CTRL + C để thoát)

Hãy thử khai thác một Block bằng cách tạo một yêu cầu GET, tới http: // localhost: 5000 / mine:

Sử dụng Postman để tạo yêu cầu

Sau đó, khởi tạo một giao dịch bằng cách yêu cầu lệnh POST http://localhost:5000/transactions/new:

Sử dụng Postman để tạo yêu cầu

Trong trường hợp bạn không dùng Postman, bạn có thể thực hiện yêu cầu tương đương bằng cURL:

$ curl -X POST -H "Content-Type: application/json" -d '{

"sender": "d4ee26eee15148ee92c6cd394edd974e",

"recipient": "someone-other-address",

"amount": 5

}' "http://localhost:5000/transactions/new"


Bước 4: Sự đồng thuận

Khi đã tạo dựng thành công một Blockchains, về cơ bản nó đã chấp nhận các giao dịch và cho phép khai thác các Block mới. Thế nhưng có một vấn đề nảy sinh khi người dùng không cùng phản ánh cùng một chuỗi. Đây được gọi là vấn đề về sự đồng thuận và cần phải triển khai thuật toán nếu muốn có nhiều hơn một móc xích trong mạng lưới của mình.

Đăng ký một điểm nối mới

Để cho một điểm nối biết về các điểm nối lân cận trên mạng, mỗi điểm trên mạng lưới phải giữ cách thức tạo dựng của các điểm nối khác. Vì vậy, cần phải thêm một số điểm cuối:

/nodes/register để chấp nhận danh sách các điểm nối mới ở dạng URL.

/nodes/resolve để thực hiện thuật toán về sự đồng thuận cho người dùng.


Cần sửa đổi lại hàm tạo Blockchains và cung cấp một phương thức để đăng ký các điểm nối:

...

from urllib.parse import urlparse


...


class Blockchain(object):


def __init__(self):

...

self.nodes = set()

...


def register_node(self, address):

"""

Add a new node to the list of nodes

:param address: <str> Address of node. Eg. 'http://192.168.0.5:5000'

:return: None

"""


parsed_url = urlparse(address)

self.nodes.add(parsed_url.netloc)

APPLY NOW

Thực hiện thuật toán đồng thuận

Như đã đề cập ở trên, khi có xung đột xảy ra thì cách giải quyết tốt nhất là tạo một quy tắc mà ở đó chuỗi dài nhất trên mạng là chuỗi thực tế. Sử dụng thuật toán này, bạn sẽ đạt được sự đồng thuận giữa các điểm nối trong mạng lưới.

...

import requests


class Blockchain(object)


...


def valid_chain(self, chain):

"""

Determine if a given blockchain is valid

:param chain: <list> A blockchain

:return: <bool> True if valid, False if not

"""


last_block = chain[0]

current_index = 1



while current_index < len(chain):

block = chain[current_index]

print(f'{last_block}')

print(f'{block}')

print("\n-----------\n")


# Check that the hash of the block is correct

if block['previous_hash'] != self.hash(last_block):


return False


# Check that the Proof of Work is correct

if not self.valid_proof(last_block['proof'], block['proof']):


return False



last_block = block

current_index += 1


return True

def resolve_conflicts(self):

"""

This is our Consensus Algorithm, it resolves conflicts by replacing our chain with the longest one in the network.

:return: <bool> True if our chain was replaced, False if not

"""

neighbours = self.nodes

new_chain = None


# We're only looking for chains longer than ours

max_length = len(self.chain)


# Grab and verify the chains from all the nodes in our network for node in neighbours:

response = requests.get(f'http://{node}/chain')


if response.status_code == 200:

length = response.json()['length']

chain = response.json()['chain']



# Check if the length is longer and the chain is valid

if length > max_length and self.valid_chain(chain):

max_length = length

new_chain = chain


# Replace our chain if we discovered a new, valid chain longer than ours

if new_chain:

self.chain = new_chain

return True

return False


Trên đây là tất cả những kiến thức từ cơ bản tới nâng cao để tự mình xây dựng Blockchains. Hy vọng bài viết có thể giúp bạn hiểu thêm về Blockchains và cách thức hoạt động của nó.


Nguồn tổng hợp

---

JT1 - IT Recruitment Agency Website: https://www.jt1.vn Email: hi@jt1.vn Điện thoại: +8428 6675 6685 Xem thêm các bài viết khác tại: https://www.jt1.vn/blog Theo dõi chúng tôi tại: https://www.facebook.com/jt1asia/


Job_link_banner.gif
bottom of page