Python Blockchain - Hướng dẫn nhanh
Trong phần hướng dẫn về Blockchain, chúng ta đã tìm hiểu chi tiết về lý thuyết đằng sau blockchain. Blockchain là khối xây dựng cơ bản đằng sau đồng tiền kỹ thuật số phổ biến nhất thế giới Bitcoin. Hướng dẫn giải quyết sâu sắc những phức tạp của Bitcoin, giải thích đầy đủ về kiến trúc blockchain. Bước tiếp theo là xây dựng blockchain của riêng chúng tôi.
Satoshi Nakamoto đã tạo ra đồng tiền ảo đầu tiên trên thế giới có tên là Bitcoin. Nhìn vào sự thành công của Bitcoin, nhiều người khác đã tạo ra các loại tiền ảo của riêng họ. Để kể tên một số - Litecoin, Zcash, v.v.
Bây giờ, bạn cũng có thể muốn khởi chạy tiền tệ của riêng mình. Hãy để chúng tôi gọi đây là TPCoin (TutorialsPoint Coin). Bạn sẽ viết một blockchain để ghi lại tất cả các giao dịch giao dịch với TPCoin. TPCoin có thể được sử dụng để mua Pizza, Burgers, Salad, v.v. Có thể có các nhà cung cấp dịch vụ khác sẽ tham gia mạng của bạn và bắt đầu chấp nhận TPCoin làm đơn vị tiền tệ để cung cấp dịch vụ của họ. Khả năng là vô tận.
Trong hướng dẫn này, hãy để chúng tôi hiểu cách xây dựng một hệ thống như vậy và khởi chạy đồng tiền kỹ thuật số của riêng bạn trên thị trường.
Các thành phần tham gia vào phát triển dự án chuỗi khối
Toàn bộ quá trình phát triển dự án blockchain bao gồm ba thành phần chính:
- Client
- Miners
- Blockchain
Khách hàng
Khách hàng là người sẽ mua hàng hóa từ các nhà cung cấp khác. Bản thân khách hàng có thể trở thành người bán hàng và sẽ nhận tiền từ người khác đối với hàng hóa mà anh ta cung cấp. Ở đây chúng tôi giả định rằng khách hàng có thể vừa là nhà cung cấp vừa là người nhận TPCoins. Vì vậy, chúng tôi sẽ tạo một lớp khách hàng trong mã của chúng tôi có khả năng gửi và nhận tiền.
Thợ mỏ
Người khai thác là người chọn các giao dịch từ một nhóm giao dịch và tập hợp chúng thành một khối. Người khai thác phải cung cấp bằng chứng công việc hợp lệ để nhận được phần thưởng khai thác. Tất cả số tiền mà người khai thác thu như một khoản phí sẽ được anh ta giữ. Anh ta có thể chi số tiền đó để mua hàng hóa hoặc dịch vụ từ các nhà cung cấp đã đăng ký khác trên mạng, giống như cách Khách hàng đã mô tả ở trên.
Chuỗi khối
Cuối cùng, Blockchain là một cấu trúc dữ liệu chuỗi tất cả các khối được khai thác theo thứ tự thời gian. Chuỗi này là bất biến và do đó chống nóng.
Bạn có thể làm theo hướng dẫn này bằng cách gõ mã được trình bày trong mỗi bước vào sổ tay Jupyter mới. Ngoài ra, bạn có thể tải xuống toàn bộ sổ ghi chép Jupyter từ www.anaconda.com .
Trong chương tiếp theo, chúng tôi sẽ phát triển một ứng dụng khách sử dụng hệ thống blockchain của chúng tôi.
Khách hàng là một người nào đó nắm giữ TPCoins và giao dịch chúng cho hàng hóa / dịch vụ từ các nhà cung cấp khác trên mạng bao gồm cả của chính họ. Chúng ta nên xác định mộtClientlớp cho mục đích này. Để tạo nhận dạng duy nhất trên toàn cầu cho khách hàng, chúng tôi sử dụng PKI (Cơ sở hạ tầng khóa công khai). Trong chương này, chúng ta hãy nói về điều này một cách chi tiết.
Khách hàng sẽ có thể gửi tiền từ ví của mình cho một người đã biết khác. Tương tự, khách hàng sẽ có thể nhận tiền từ bên thứ ba. Để tiêu tiền, khách hàng sẽ tạo một giao dịch chỉ định tên người gửi và số tiền phải trả. Để nhận tiền, khách hàng sẽ cung cấp danh tính của mình cho bên thứ ba - về cơ bản là người gửi tiền. Chúng tôi không lưu trữ số dư tiền mà khách hàng giữ trong ví của mình. Trong một giao dịch, chúng tôi sẽ tính toán số dư thực tế để đảm bảo rằng khách hàng có đủ số dư để thực hiện thanh toán.
Để phát triển Clientvà đối với phần còn lại của mã trong dự án, chúng ta sẽ cần nhập nhiều thư viện Python. Chúng được liệt kê dưới đây -
# import libraries
import hashlib
import random
import string
import json
import binascii
import numpy as np
import pandas as pd
import pylab as pl
import logging
import datetime
import collections
Ngoài các thư viện chuẩn ở trên, chúng ta sẽ ký các giao dịch của mình, tạo hàm băm của các đối tượng, v.v. Đối với điều này, bạn sẽ cần nhập các thư viện sau:
# following imports are required by PKI
import Crypto
import Crypto.Random
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
Trong chương tiếp theo, chúng ta hãy nói về lớp khách hàng.
Các Client lớp tạo ra private và public các phím bằng cách sử dụng Python tích hợp RSAthuật toán. Bạn đọc quan tâm có thể tham khảothis tutorialđể thực hiện RSA. Trong quá trình khởi tạo đối tượng, chúng tôi tạo khóa riêng tư và khóa công khai và lưu trữ các giá trị của chúng trong biến cá thể.
self._private_key = RSA.generate(1024, random)
self._public_key = self._private_key.publickey()
Lưu ý rằng bạn không bao giờ được làm mất khóa cá nhân của mình. Để lưu trữ hồ sơ, khóa cá nhân đã tạo có thể được sao chép trên bộ nhớ ngoài được bảo mật hoặc bạn có thể chỉ cần viết ra biểu diễn ASCII của nó trên một mảnh giấy.
Tạo ra publickhóa sẽ được sử dụng làm danh tính của khách hàng. Đối với điều này, chúng tôi xác định một thuộc tính có tênidentity trả về biểu diễn HEX của khóa công khai.
@property
def identity(self):
return
binascii.hexlify(self._public_key.exportKey(format='DER'))
.decode('ascii')
Các identitylà duy nhất cho mỗi khách hàng và có thể được cung cấp công khai. Bất kỳ ai cũng có thể gửi tiền ảo cho bạn bằng cách nàyidentity và nó sẽ được thêm vào ví của bạn.
Mã đầy đủ cho Client lớp được hiển thị ở đây -
class Client:
def __init__(self):
random = Crypto.Random.new().read
self._private_key = RSA.generate(1024, random)
self._public_key = self._private_key.publickey()
self._signer = PKCS1_v1_5.new(self._private_key)
@property
def identity(self):
return
binascii.hexlify(self._public_key.exportKey(format='DER')).decode('ascii')
Kiểm tra khách hàng
Bây giờ, chúng tôi sẽ viết mã minh họa cách sử dụng Client lớp học -
Dinesh = Client()
print (Dinesh.identity)
Đoạn mã trên tạo ra một phiên bản của Client và gán nó cho biến Dinesh. Chúng tôi in khóa công khai củaDinesh bằng cách gọi nó identityphương pháp. Kết quả được hiển thị ở đây -
30819f300d06092a864886f70d010101050003818d0030818902818100b547fafceeb131e07
0166a6b23fec473cce22c3f55c35ce535b31d4c74754fecd820aa94c1166643a49ea5f49f72
3181ff943eb3fdc5b2cb2db12d21c06c880ccf493e14dd3e93f3a9e175325790004954c34d3
c7bc2ccc9f0eb5332014937f9e49bca9b7856d351a553d9812367dc8f2ac734992a4e6a6ff6
6f347bd411d07f0203010001
Bây giờ, chúng ta hãy chuyển sang tạo một giao dịch trong chương tiếp theo.
Trong chương này, chúng ta hãy tạo Transactionđể khách hàng có thể gửi tiền cho ai đó. Lưu ý rằng khách hàng có thể vừa là người gửi hoặc vừa là người nhận tiền. Khi bạn muốn nhận tiền, một số người gửi khác sẽ tạo một giao dịch và chỉ địnhpublicđịa chỉ trong đó. Chúng tôi định nghĩa việc khởi tạo một lớp giao dịch như sau:
def __init__(self, sender, recipient, value):
self.sender = sender
self.recipient = recipient
self.value = value
self.time = datetime.datetime.now()
Các init phương thức nhận ba tham số - của người gửi public chìa khóa, của người nhận publicvà số tiền sẽ được gửi. Chúng được lưu trữ trong các biến cá thể để sử dụng bởi các phương thức khác. Ngoài ra, chúng tôi tạo thêm một biến để lưu trữ thời gian giao dịch.
Tiếp theo, chúng tôi viết một phương thức tiện ích được gọi là to_dictkết hợp tất cả bốn biến phiên bản nêu trên trong một đối tượng từ điển. Điều này chỉ để đưa toàn bộ thông tin giao dịch có thể truy cập được thông qua một biến duy nhất.
Như bạn đã biết từ hướng dẫn trước đó rằng khối đầu tiên trong chuỗi khối là Genesiskhối. Khối Genesis chứa giao dịch đầu tiên do người tạo ra blockchain khởi xướng. Danh tính của người này có thể được giữ bí mật giống như trong trường hợp của Bitcoin. Vì vậy, khi giao dịch đầu tiên này được tạo, người tạo chỉ có thể gửi danh tính của mình làGenesis. Do đó, trong khi tạo từ điển, chúng tôi kiểm tra xem người gửi cóGenesisvà nếu vậy, chúng ta chỉ cần gán một số giá trị chuỗi cho biến nhận dạng; nếu không, chúng tôi chỉ định danh tính của người gửi choidentity Biến đổi.
if self.sender == "Genesis":
identity = "Genesis"
else:
identity = self.sender.identity
Chúng tôi xây dựng từ điển bằng cách sử dụng dòng mã sau
return collections.OrderedDict({
'sender': identity,
'recipient': self.recipient,
'value': self.value,
'time' : self.time})
Toàn bộ mã cho to_dict phương pháp được hiển thị bên dưới -
def to_dict(self):
if self.sender == "Genesis":
identity = "Genesis"
else:
identity = self.sender.identity
return collections.OrderedDict({
'sender': identity,
'recipient': self.recipient,
'value': self.value,
'time' : self.time})
Cuối cùng, chúng tôi sẽ ký đối tượng từ điển này bằng cách sử dụng khóa riêng của người gửi. Như trước đây, chúng tôi sử dụng PKI tích hợp với thuật toán SHA. Chữ ký đã tạo được giải mã để lấy biểu diễn ASCII để in và lưu trữ nó trong chuỗi khối của chúng tôi. Cácsign_transaction mã phương thức được hiển thị ở đây -
def sign_transaction(self):
private_key = self.sender._private_key
signer = PKCS1_v1_5.new(private_key)
h = SHA.new(str(self.to_dict()).encode('utf8'))
return binascii.hexlify(signer.sign(h)).decode('ascii')
Bây giờ chúng tôi sẽ kiểm tra điều này Transaction lớp học.
Kiểm tra lớp giao dịch
Với mục đích này, chúng tôi sẽ tạo hai người dùng, được gọi là Dinesh và Ramesh. Dinesh sẽ gửi 5 TPCoins cho Ramesh. Đầu tiên, chúng tôi tạo các khách hàng có tên là Dinesh và Ramesh.
Dinesh = Client()
Ramesh = Client()
Hãy nhớ rằng khi bạn khởi tạo một Client lớp học, public andkhóa riêng tư duy nhất cho khách hàng sẽ được tạo. Vì Dinesh đang gửi thanh toán cho Ramesh, anh ta sẽ cần khóa công khai của Ramesh, khóa này có được bằng cách sử dụng thuộc tính nhận dạng của khách hàng.
Do đó, chúng tôi sẽ tạo phiên bản giao dịch bằng cách sử dụng mã sau:
t = Transaction(
Dinesh,
Ramesh.identity,
5.0
)
Lưu ý rằng tham số đầu tiên là người gửi, tham số thứ hai là khóa công khai của người nhận và tham số thứ ba là số tiền cần chuyển. Cácsign_transaction phương thức truy xuất khóa riêng của người gửi từ tham số đầu tiên để hát giao dịch.
Sau khi đối tượng giao dịch được tạo, bạn sẽ ký nó bằng cách gọi sign_transactionphương pháp. Phương thức này trả về chữ ký đã tạo ở định dạng có thể in được. Chúng tôi tạo và in chữ ký bằng hai dòng mã sau:
signature = t.sign_transaction()
print (signature)
Khi bạn chạy đoạn mã trên, bạn sẽ thấy đầu ra tương tự như sau:
7c7e3c97629b218e9ec6e86b01f9abd8e361fd69e7d373c38420790b655b9abe3b575e343c7
13703ca1aee781acd7157a0624db3d57d7c2f1172730ee3f45af943338157f899965856f6b0
0e34db240b62673ad5a08c8e490f880b568efbc36035cae2e748f1d802d5e8e66298be826f5
c6363dc511222fb2416036ac04eb972
Bây giờ khi cơ sở hạ tầng cơ bản của chúng tôi để tạo khách hàng và giao dịch đã sẵn sàng, giờ đây chúng tôi sẽ có nhiều khách hàng thực hiện nhiều giao dịch như trong một tình huống thực tế.
Các giao dịch được thực hiện bởi các khách hàng khác nhau được xếp hàng đợi trong hệ thống; những người khai thác nhận các giao dịch từ hàng đợi này và thêm nó vào khối. Sau đó, họ sẽ khai thác khối và người khai thác chiến thắng sẽ có đặc quyền thêm khối vào blockchain và do đó kiếm được một số tiền cho mình.
Chúng tôi sẽ mô tả quá trình khai thác này sau khi chúng tôi thảo luận về việc tạo ra blockchain. Trước khi chúng tôi viết mã cho nhiều giao dịch, hãy thêm một chức năng tiện ích nhỏ để in nội dung của một giao dịch nhất định.
Hiển thị giao dịch
Các display_transactionhàm chấp nhận một tham số duy nhất của loại giao dịch. Đối tượng từ điển trong giao dịch đã nhận được sao chép vào một biến tạm thời được gọi làdict và sử dụng các phím từ điển, các giá trị khác nhau được in trên bảng điều khiển.
def display_transaction(transaction):
#for transaction in transactions:
dict = transaction.to_dict()
print ("sender: " + dict['sender'])
print ('-----')
print ("recipient: " + dict['recipient'])
print ('-----')
print ("value: " + str(dict['value']))
print ('-----')
print ("time: " + str(dict['time']))
print ('-----')
Tiếp theo, chúng tôi xác định một hàng đợi giao dịch để lưu trữ các đối tượng giao dịch của chúng tôi.
Hàng đợi giao dịch
Để tạo một hàng đợi, chúng tôi khai báo một list biến được gọi là transactions như sau -
transactions = []
Chúng tôi chỉ cần nối mỗi giao dịch mới được tạo vào hàng đợi này. Xin lưu ý rằng để ngắn gọn, chúng tôi sẽ không triển khai logic quản lý hàng đợi trong hướng dẫn này.
Tạo nhiều khách hàng
Bây giờ, chúng ta sẽ bắt đầu tạo giao dịch. Đầu tiên, chúng tôi sẽ tạo ra bốn khách hàng sẽ gửi tiền cho nhau để nhận các dịch vụ hoặc hàng hóa khác nhau từ những người khác.
Dinesh = Client()
Ramesh = Client()
Seema = Client()
Vijay = Client()
Tại thời điểm này, chúng tôi có bốn khách hàng tên là Dinesh, Ramesh, Seema và Vijay. Hiện tại, chúng tôi giả định rằng mỗi khách hàng này có một số TPCoins trong ví của họ để giao dịch. Danh tính của từng khách hàng này sẽ được xác định bằng cách sử dụng thuộc tính nhận dạng của các đối tượng này.
Tạo giao dịch đầu tiên
Bây giờ, chúng tôi bắt đầu giao dịch đầu tiên của mình như sau:
t1 = Transaction(
Dinesh,
Ramesh.identity,
15.0
)
Trong giao dịch này, Dinesh gửi 5 TPCoins cho Ramesh. Để giao dịch thành công, chúng tôi sẽ phải đảm bảo rằng Dinesh có đủ tiền trong ví của anh ấy cho khoản thanh toán này. Lưu ý rằng, chúng tôi sẽ cần một giao dịch gốc để bắt đầu lưu thông TPCoin trong hệ thống. Bạn sẽ viết mã giao dịch cho giao dịch khởi đầu này ngay sau khi bạn đọc cùng.
Chúng tôi sẽ ký giao dịch này bằng khóa riêng tư của Dinesh và thêm nó vào hàng đợi giao dịch như sau:
t1.sign_transaction()
transactions.append(t1)
Sau giao dịch đầu tiên do Dinesh thực hiện, chúng tôi sẽ tạo thêm một số giao dịch giữa các khách hàng khác nhau mà chúng tôi đã tạo ở trên.
Thêm nhiều giao dịch hơn
Bây giờ chúng tôi sẽ tạo thêm một số giao dịch, mỗi giao dịch sẽ cung cấp một vài TPCoin cho một bên khác. Khi ai đó tiêu tiền, không nhất thiết anh ta phải kiểm tra xem có đủ số dư trong ví này hay không. Người khai thác dù sao cũng sẽ xác thực từng giao dịch cho số dư mà người gửi có trong khi bắt đầu giao dịch.
Trong trường hợp không đủ số dư, người khai thác sẽ đánh dấu giao dịch này là không hợp lệ và sẽ không thêm nó vào khối này.
Đoạn mã sau tạo và thêm chín giao dịch khác vào hàng đợi của chúng tôi.
t2 = Transaction(
Dinesh,
Seema.identity,
6.0
)
t2.sign_transaction()
transactions.append(t2)
t3 = Transaction(
Ramesh,
Vijay.identity,
2.0
)
t3.sign_transaction()
transactions.append(t3)
t4 = Transaction(
Seema,
Ramesh.identity,
4.0
)
t4.sign_transaction()
transactions.append(t4)
t5 = Transaction(
Vijay,
Seema.identity,
7.0
)
t5.sign_transaction()
transactions.append(t5)
t6 = Transaction(
Ramesh,
Seema.identity,
3.0
)
t6.sign_transaction()
transactions.append(t6)
t7 = Transaction(
Seema,
Dinesh.identity,
8.0
)
t7.sign_transaction()
transactions.append(t7)
t8 = Transaction(
Seema,
Ramesh.identity,
1.0
)
t8.sign_transaction()
transactions.append(t8)
t9 = Transaction(
Vijay,
Dinesh.identity,
5.0
)
t9.sign_transaction()
transactions.append(t9)
t10 = Transaction(
Vijay,
Ramesh.identity,
3.0
)
t10.sign_transaction()
transactions.append(t10)
Khi bạn chạy đoạn mã trên, bạn sẽ có mười giao dịch trong hàng đợi để các thợ đào tạo khối của họ.
Giao dịch bán phá giá
Là một nhà quản lý blockchain, bạn có thể định kỳ xem xét nội dung của hàng đợi giao dịch. Với mục đích này, bạn có thể sử dụngdisplay_transactionchức năng mà chúng tôi đã phát triển trước đó. Để kết xuất tất cả các giao dịch trong hàng đợi, chỉ cần lặp lại danh sách giao dịch và đối với mỗi giao dịch được tham chiếu, hãy gọidisplay_transaction chức năng như được hiển thị ở đây -
for transaction in transactions:
display_transaction (transaction)
print ('--------------')
Các giao dịch được phân tách bằng một đường đứt nét để phân biệt. Nếu chạy đoạn mã trên, bạn sẽ thấy danh sách giao dịch như hình bên dưới:
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c49214
4a9f463480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329e
c86794b04d773eb4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b
47e5157f8fe56c2ce3279c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311
c4d866c12d79d3fc3034563dfb0203010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e
674abe7abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8ad
d126b6e1a1308fb98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa93977
04de625d1836d3f42c7ee5683f6703259592cc24b09699376807f28fe0e00ff882974484
d805f874260dfc2d1627473b910203010001
-----
value: 15.0
-----
time: 2019-01-14 16:18:01.859915
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c49214
4a9f463480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329e
c86794b04d773eb4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b
47e5157f8fe56c2ce3279c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311
c4d866c12d79d3fc3034563dfb0203010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae14
3cbe59b3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fb
d9ee74b9e7ea12334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0
961b4f212d1fd5b5e49ae09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d0623
75799742a359b8f22c5362e5650203010001
-----
value: 6.0
-----
time: 2019-01-14 16:18:01.860966
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e
674abe7abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8ad
d126b6e1a1308fb98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa93977
04de625d1836d3f42c7ee5683f6703259592cc24b09699376807f28fe0e00ff882974484
d805f874260dfc2d1627473b910203010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876
f41338c62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cc
e25be99452a81df4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47
452590137869c25d9ff83d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f0
0e321b65e4c33acaf6469e18e30203010001
-----
value: 2.0
-----
time: 2019-01-14 16:18:01.861958
-----
--------------
Để ngắn gọn, tôi chỉ in một số giao dịch đầu tiên trong danh sách. Trong đoạn mã trên, chúng tôi in tất cả các giao dịch bắt đầu bằng giao dịch đầu tiên ngoại trừ giao dịch gốc chưa bao giờ được thêm vào danh sách này. Khi các giao dịch được thêm vào các khối theo định kỳ, bạn thường sẽ quan tâm đến việc chỉ xem danh sách các giao dịch chưa được khai thác. Trong trường hợp đó, bạn sẽ cần tạofor vòng lặp để lặp lại các giao dịch chưa được khai thác.
Cho đến nay, bạn đã học được cách tạo khách hàng, cho phép họ tham gia với nhau và duy trì hàng đợi các giao dịch đang chờ xử lý sẽ được khai thác. Bây giờ, đến phần quan trọng nhất của hướng dẫn này và đó là tạo ra một blockchain. Bạn sẽ học điều này trong bài học tiếp theo.
Một khối bao gồm một số lượng giao dịch khác nhau. Để đơn giản, trong trường hợp của chúng tôi, chúng tôi sẽ giả định rằng khối bao gồm một số lượng giao dịch cố định, trong trường hợp này là ba. Vì khối cần lưu trữ danh sách ba giao dịch này, chúng tôi sẽ khai báo một biến thể hiện được gọi làverified_transactions như sau -
self.verified_transactions = []
Chúng tôi đã đặt tên biến này là verified_transactionsđể chỉ ra rằng chỉ các giao dịch hợp lệ đã được xác minh mới được thêm vào khối. Mỗi khối cũng giữ giá trị băm của khối trước đó, để chuỗi khối trở nên bất biến.
Để lưu trữ hàm băm trước đó, chúng ta khai báo một biến thể hiện như sau:
self.previous_block_hash = ""
Cuối cùng, chúng tôi khai báo một biến nữa được gọi là Nonce để lưu trữ nonce do người khai thác tạo ra trong quá trình khai thác.
self.Nonce = ""
Định nghĩa đầy đủ của Block lớp học được đưa ra dưới đây -
class Block:
def __init__(self):
self.verified_transactions = []
self.previous_block_hash = ""
self.Nonce = ""
Vì mỗi khối cần giá trị băm của khối trước đó, chúng tôi khai báo một biến toàn cục được gọi là last_block_hash như sau -
last_block_hash = ""
Bây giờ chúng ta hãy tạo khối đầu tiên của mình trong blockchain.
Chúng tôi giả định rằng người khởi tạo TPCoins ban đầu cung cấp 500 TPCoins cho một khách hàng đã biết Dinesh. Đối với điều này, đầu tiên anh ta tạo một cá thể Dinesh -
Dinesh = Client()
Sau đó, chúng tôi tạo một giao dịch gốc và gửi 500 TPCoins đến địa chỉ công khai của Dinesh.
t0 = Transaction (
"Genesis",
Dinesh.identity,
500.0
)
Bây giờ, chúng tôi tạo một phiên bản của Block lớp và gọi nó block0.
block0 = Block()
Chúng tôi khởi tạo previous_block_hash và Nonce biến phiên bản thành None, vì đây là giao dịch đầu tiên được lưu trữ trong blockchain của chúng tôi.
block0.previous_block_hash = None
Nonce = None
Tiếp theo, chúng tôi sẽ thêm giao dịch t0 ở trên vào verified_transactions danh sách được duy trì trong khối -
block0.verified_transactions.append (t0)
Tại thời điểm này, khối đã được khởi tạo hoàn toàn và sẵn sàng được thêm vào blockchain của chúng tôi. Chúng tôi sẽ tạo ra blockchain cho mục đích này. Trước khi thêm khối vào chuỗi khối, chúng tôi sẽ băm khối và lưu trữ giá trị của nó trong biến toàn cục có tênlast_block_hashmà chúng tôi đã khai báo trước đây. Giá trị này sẽ được sử dụng bởi người khai thác tiếp theo trong khối của anh ta.
Chúng tôi sử dụng hai dòng mã sau đây để băm khối và lưu trữ giá trị thông báo.
digest = hash (block0)
last_block_hash = digest
Cuối cùng, chúng tôi tạo ra một blockchain như chúng ta thấy trong chương tiếp theo.
Một chuỗi khối chứa một danh sách các khối được liên kết với nhau. Để lưu trữ toàn bộ danh sách, chúng tôi sẽ tạo một biến danh sách được gọi là TPCoins -
TPCoins = []
Chúng tôi cũng sẽ viết một phương thức tiện ích được gọi là dump_blockchainđể bán nội dung của toàn bộ blockchain. Đầu tiên chúng tôi in chiều dài của blockchain để chúng tôi biết có bao nhiêu khối hiện đang tồn tại trong blockchain.
def dump_blockchain (self):
print ("Number of blocks in the chain: " + str(len (self)))
Lưu ý rằng khi thời gian trôi qua, số lượng khối trong blockchain sẽ rất cao để in. Do đó, khi bạn in nội dung của blockchain, bạn có thể phải quyết định phạm vi mà bạn muốn kiểm tra. Trong đoạn mã dưới đây, chúng tôi đã in toàn bộ blockchain vì chúng tôi sẽ không thêm quá nhiều khối trong bản demo hiện tại.
Để lặp lại chuỗi, chúng tôi thiết lập for vòng lặp như sau -
for x in range (len(TPCoins)):
block_temp = TPCoins[x]
Mỗi khối được tham chiếu được sao chép vào một biến tạm thời được gọi là block_temp.
Chúng tôi in số khối dưới dạng tiêu đề cho mỗi khối. Lưu ý rằng các số sẽ bắt đầu bằng 0, khối đầu tiên là khối gốc được đánh số bằng 0.
print ("block # " + str(x))
Trong mỗi khối, chúng tôi đã lưu trữ danh sách ba giao dịch (ngoại trừ khối gốc) trong một biến được gọi là verified_transactions. Chúng tôi lặp lại danh sách này trong mộtfor vòng lặp và đối với mỗi mục đã truy xuất, chúng tôi gọi display_transaction chức năng hiển thị chi tiết giao dịch.
for transaction in block_temp.verified_transactions:
display_transaction (transaction)
Toàn bộ định nghĩa hàm được hiển thị bên dưới:
def dump_blockchain (self):
print ("Number of blocks in the chain: " + str(len (self)))
for x in range (len(TPCoins)):
block_temp = TPCoins[x]
print ("block # " + str(x))
for transaction in block_temp.verified_transactions:
display_transaction (transaction)
print ('--------------')
print ('=====================================')
Lưu ý rằng ở đây chúng tôi đã chèn các dấu phân tách tại các điểm thích hợp trong mã để phân định các khối và giao dịch bên trong nó.
Vì bây giờ chúng ta đã tạo ra một blockchain để lưu trữ các khối, nhiệm vụ tiếp theo của chúng ta là tạo các khối và bắt đầu thêm nó vào blockchain. Vì mục đích này, chúng tôi sẽ thêm một khối genesis mà bạn đã tạo ở bước trước đó.
Thêm một khối vào chuỗi khối liên quan đến việc nối khối đã tạo vào TPCoins danh sách.
TPCoins.append (block0)
Lưu ý rằng không giống như các khối còn lại trong hệ thống, khối gốc chỉ chứa một giao dịch được khởi tạo bởi người khởi tạo hệ thống TPCoins. Bây giờ, bạn sẽ kết xuất nội dung của blockchain bằng cách gọi hàm toàn cầu của chúng tôidump_blockchain -
dump_blockchain(TPCoins)
Khi bạn thực thi chức năng này, bạn sẽ thấy kết quả sau:
Number of blocks in the chain: 1
block # 0
sender: Genesis
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100ed272b52ccb539
e2cd779c6cc10ed1dfadf5d97c6ab6de90ed0372b2655626fb79f62d0e01081c163b0864
cc68d426bbe9438e8566303bb77414d4bfcaa3468ab7febac099294de10273a816f7047d
4087b4bafa11f141544d48e2f10b842cab91faf33153900c7bf6c08c9e47a7df8aa7e60d
c9e0798fb2ba3484bbdad2e4430203010001
-----
value: 500.0
-----
time: 2019-01-14 16:18:02.042739
-----
--------------
=====================================
Tại thời điểm này, hệ thống blockchain đã sẵn sàng để sử dụng. Giờ đây, chúng tôi sẽ cho phép những khách hàng quan tâm trở thành thợ đào bằng cách cung cấp cho họ chức năng khai thác.
Để cho phép khai thác, chúng ta cần phát triển một chức năng khai thác. Chức năng khai thác cần tạo thông báo về một chuỗi thông báo nhất định và cung cấp bằng chứng công việc. Hãy để chúng tôi thảo luận về điều này trong chương này.
Chức năng thông báo thông báo
Chúng tôi sẽ viết một hàm tiện ích được gọi là sha256 để tạo thông báo về một tin nhắn nhất định -
def sha256(message):
return hashlib.sha256(message.encode('ascii')).hexdigest()
Các sha256 chức năng có một message dưới dạng một tham số, mã hóa nó thành ASCII, tạo một thông báo thập lục phân và trả về giá trị cho người gọi.
Chức năng khai thác
Bây giờ chúng tôi phát triển minechức năng thực hiện chiến lược khai thác của riêng chúng tôi. Chiến lược của chúng tôi trong trường hợp này sẽ là tạo một hàm băm trên thông điệp đã cho có tiền tố là số 1 cho trước. Số lượng nhất định của 1 được chỉ định làm tham số chomine chức năng được chỉ định như mức độ khó khăn.
Ví dụ: nếu bạn chỉ định mức độ khó là 2, hàm băm được tạo trên một tin nhắn nhất định phải bắt đầu bằng hai chữ 1 - như 11xxxxxxxx. Nếu mức độ khó là 3, hàm băm được tạo phải bắt đầu bằng ba số 1 - như 111xxxxxxxx. Với những yêu cầu này, bây giờ chúng ta sẽ phát triển chức năng khai thác như thể hiện trong các bước dưới đây.
Bước 1
Hàm khai thác nhận hai tham số - thông báo và mức độ khó.
def mine(message, difficulty=1):
Bước 2
Mức độ khó cần lớn hơn hoặc bằng 1, chúng tôi đảm bảo điều này bằng câu khẳng định sau:
assert difficulty >= 1
Bước 3
Chúng tôi tạo ra một prefix biến bằng cách sử dụng mức độ khó đã đặt.
prefix = '1' * difficulty
Lưu ý nếu mức độ khó là 2, tiền tố sẽ là “11” và nếu mức độ khó là 3, tiền tố sẽ là “111”, v.v. Chúng tôi sẽ kiểm tra xem tiền tố này có tồn tại trong thông báo đã tạo của thư hay không. Để thông báo chính nó, chúng tôi sử dụng hai dòng mã sau:
for i in range(1000):
digest = sha256(str(hash(message)) + str(i))
Chúng tôi tiếp tục thêm một số mới ibăm thông điệp trong mỗi lần lặp lại và tạo một thông báo mới về thông báo kết hợp. Là đầu vào chosha256 chức năng thay đổi trong mỗi lần lặp lại, digestgiá trị cũng sẽ thay đổi. Chúng tôi kiểm tra xem điều nàydigest giá trị đã đặt trên prefix.
if digest.startswith(prefix):
Nếu điều kiện được thỏa mãn, chúng tôi sẽ chấm dứt for lặp lại và trả về digest giá trị đối với người gọi.
Toàn bộ mine mã được hiển thị ở đây -
def mine(message, difficulty=1):
assert difficulty >= 1
prefix = '1' * difficulty
for i in range(1000):
digest = sha256(str(hash(message)) + str(i))
if digest.startswith(prefix):
print ("after " + str(i) + " iterations found nonce: "+ digest)
return digest
Để bạn hiểu, chúng tôi đã thêm print câu lệnh in ra giá trị thông báo và số lần lặp cần thiết để đáp ứng điều kiện trước khi trả về từ hàm.
Kiểm tra chức năng khai thác
Để kiểm tra chức năng khai thác của chúng tôi, chỉ cần thực hiện câu lệnh sau:
mine ("test message", 2)
Khi bạn chạy đoạn mã trên, bạn sẽ thấy đầu ra tương tự như bên dưới:
after 138 iterations found nonce:
11008a740eb2fa6bf8d55baecda42a41993ca65ce66b2d3889477e6bfad1484c
Lưu ý rằng thông báo được tạo bắt đầu bằng “11”. Nếu bạn thay đổi mức độ khó thành 3, thông báo được tạo sẽ bắt đầu bằng “111” và tất nhiên, nó có thể sẽ yêu cầu nhiều lần lặp hơn. Như bạn có thể thấy, một người khai thác có nhiều khả năng xử lý hơn sẽ có thể khai thác một tin nhắn nhất định sớm hơn. Đó là cách các thợ mỏ cạnh tranh với nhau để kiếm doanh thu của họ.
Bây giờ, chúng tôi đã sẵn sàng thêm nhiều khối hơn vào blockchain của mình. Hãy để chúng tôi tìm hiểu điều này trong chương tiếp theo của chúng tôi.
Mỗi người khai thác sẽ chọn các giao dịch từ một nhóm giao dịch đã tạo trước đó. Để theo dõi số lượng tin nhắn đã được khai thác, chúng ta phải tạo một biến toàn cục -
last_transaction_index = 0
Bây giờ chúng tôi sẽ có người khai thác đầu tiên của chúng tôi thêm một khối vào blockchain.
Thêm khối đầu tiên
Để thêm một khối mới, trước tiên chúng ta tạo một phiên bản của Block lớp học.
block = Block()
Chúng tôi chọn 3 giao dịch hàng đầu từ hàng đợi -
for i in range(3):
temp_transaction = transactions[last_transaction_index]
# validate transaction
Trước khi thêm giao dịch vào khối, người khai thác sẽ xác minh tính hợp lệ của giao dịch. Tính hợp lệ của giao dịch được xác minh bằng cách kiểm tra tính bình đẳng giữa hàm băm do người gửi cung cấp so với hàm băm do người khai thác tạo bằng khóa công khai của người gửi. Ngoài ra, người khai thác sẽ xác minh rằng người gửi có đủ số dư để thanh toán cho giao dịch hiện tại.
Để ngắn gọn, chúng tôi chưa đưa chức năng này vào hướng dẫn. Sau khi giao dịch được xác thực, chúng tôi thêm nó vàoverified_transactions danh sách trong block ví dụ.
block.verified_transactions.append (temp_transaction)
Chúng tôi tăng chỉ số giao dịch cuối cùng để người khai thác tiếp theo sẽ nhận các giao dịch tiếp theo trong hàng đợi.
last_transaction_index += 1
Chúng tôi thêm chính xác ba giao dịch vào khối. Khi điều này được thực hiện, chúng tôi sẽ khởi tạo phần còn lại của các biến phiên bản củaBlocklớp học. Đầu tiên chúng tôi thêm băm của khối cuối cùng.
block.previous_block_hash = last_block_hash
Tiếp theo, chúng tôi khai thác khối với độ khó là 2.
block.Nonce = mine (block, 2)
Lưu ý rằng tham số đầu tiên cho minehàm là một đối tượng nhị phân. Bây giờ chúng tôi băm toàn bộ khối và tạo thông báo về nó.
digest = hash (block)
Cuối cùng, chúng tôi thêm khối đã tạo vào blockchain và khởi tạo lại biến toàn cầu last_block_hash để sử dụng trong khối tiếp theo.
Toàn bộ mã để thêm khối được hiển thị bên dưới:
block = Block()
for i in range(3):
temp_transaction = transactions[last_transaction_index]
# validate transaction
# if valid
block.verified_transactions.append (temp_transaction)
last_transaction_index += 1
block.previous_block_hash = last_block_hash
block.Nonce = mine (block, 2)
digest = hash (block)
TPCoins.append (block)
last_block_hash = digest
Thêm các khối khác
Bây giờ chúng tôi sẽ thêm hai khối nữa vào blockchain của mình. Mã để thêm hai khối tiếp theo được đưa ra bên dưới:
# Miner 2 adds a block
block = Block()
for i in range(3):
temp_transaction = transactions[last_transaction_index]
# validate transaction
# if valid
block.verified_transactions.append (temp_transaction)
last_transaction_index += 1
block.previous_block_hash = last_block_hash
block.Nonce = mine (block, 2)digest = hash (block)
TPCoins.append (block)last_block_hash = digest
# Miner 3 adds a block
block = Block()
for i in range(3):
temp_transaction = transactions[last_transaction_index]
#display_transaction (temp_transaction)
# validate transaction
# if valid
block.verified_transactions.append (temp_transaction)
last_transaction_index += 1
block.previous_block_hash = last_block_hash
block.Nonce = mine (block, 2)
digest = hash (block)
TPCoins.append (block)
last_block_hash = digest
Khi bạn thêm hai khối này, bạn cũng sẽ thấy số lần lặp lại để tìm Nonce. Tại thời điểm này, blockchain của chúng tôi bao gồm hoàn toàn 4 khối bao gồm cả khối gốc.
Bán phá giá toàn bộ chuỗi khối
Bạn có thể xác minh nội dung của toàn bộ chuỗi khối bằng cách sử dụng câu lệnh sau:
dump_blockchain(TPCoins)
Bạn sẽ thấy đầu ra tương tự như hình dưới đây:
Number of blocks in the chain: 4
block # 0
sender: Genesis
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100ed272b52ccb539e2cd779
c6cc10ed1dfadf5d97c6ab6de90ed0372b2655626fb79f62d0e01081c163b0864cc68d426bbe943
8e8566303bb77414d4bfcaa3468ab7febac099294de10273a816f7047d4087b4bafa11f141544d4
8e2f10b842cab91faf33153900c7bf6c08c9e47a7df8aa7e60dc9e0798fb2ba3484bbdad2e44302
03010001
-----
value: 500.0
-----
time: 2019-01-14 16:18:02.042739
-----
--------------
=====================================
block # 1
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
value: 15.0
-----
time: 2019-01-14 16:18:01.859915
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
value: 6.0
-----
time: 2019-01-14 16:18:01.860966
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876f41338c
62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cce25be99452a81d
f4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47452590137869c25d9ff83
d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f00e321b65e4c33acaf6469e18e302
03010001
-----
value: 2.0
-----
time: 2019-01-14 16:18:01.861958
-----
--------------
=====================================
block # 2
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
value: 4.0
-----
time: 2019-01-14 16:18:01.862946
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876f41338c
62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cce25be99452a81d
f4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47452590137869c25d9ff83
d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f00e321b65e4c33acaf6469e18e302
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
value: 7.0
-----
time: 2019-01-14 16:18:01.863932
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
value: 3.0
-----
time: 2019-01-14 16:18:01.865099
-----
--------------
=====================================
block # 3
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001
-----
value: 8.0
-----
time: 2019-01-14 16:18:01.866219
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
value: 1.0
-----
time: 2019-01-14 16:18:01.867223
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876f41338c
62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cce25be99452a81d
f4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47452590137869c25d9ff83
d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f00e321b65e4c33acaf6469e18e302
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001
-----
value: 5.0
-----
time: 2019-01-14 16:18:01.868241
-----
--------------
=====================================
Trong hướng dẫn này, chúng ta đã học cách xây dựng một dự án blockchain bằng Python. Có rất nhiều khu vực mà bạn cần bổ sung thêm chức năng cho dự án này.
Ví dụ, bạn sẽ cần viết các hàm để quản lý hàng đợi giao dịch. Sau khi các giao dịch được khai thác và khối được khai thác được hệ thống chấp nhận, chúng không cần được lưu trữ nữa.
Ngoài ra, các thợ đào chắc chắn sẽ thích nhận các giao dịch với mức phí cao nhất. Đồng thời, bạn sẽ phải đảm bảo rằng các giao dịch có phí thấp hoặc miễn phí sẽ không bị chết đói mãi mãi.
Bạn sẽ cần phát triển các thuật toán để quản lý hàng đợi. Ngoài ra, hướng dẫn hiện tại không bao gồm mã giao diện máy khách. Bạn sẽ cần phải phát triển điều này cho cả khách hàng bình thường và thợ đào. Dự án blockchain chính thức sẽ chạy vào nhiều dòng mã hơn và nằm ngoài phạm vi của hướng dẫn này. Bạn đọc quan tâm có thể tải xuống nguồn bitcoin để nghiên cứu thêm.
Kết luận
Hướng dẫn rõ ràng này sẽ giúp bạn bắt đầu tạo dự án blockchain của riêng mình.
Để phát triển dự án blockchain chính thức, bạn có thể tìm hiểu thêm từ nguồn bitcoin .
Đối với các dự án thương mại hoặc phi thương mại lớn hơn, bạn có thể cân nhắc sử dụng Ethereum - một nền tảng ứng dụng blockchain sẵn sàng sử dụng.