Python Blockchain - คู่มือฉบับย่อ

ในบทช่วยสอนเกี่ยวกับ Blockchain เราได้เรียนรู้รายละเอียดเกี่ยวกับทฤษฎีเบื้องหลัง blockchain blockchain เป็นโครงสร้างพื้นฐานเบื้องหลัง Bitcoin สกุลเงินดิจิทัลที่ได้รับความนิยมมากที่สุดในโลก บทช่วยสอนนี้จัดการอย่างลึกซึ้งกับความซับซ้อนของ Bitcoin ซึ่งอธิบายถึงสถาปัตยกรรมบล็อกเชนอย่างครบถ้วน ขั้นตอนต่อไปคือการสร้างบล็อกเชนของเราเอง

Satoshi Nakamoto สร้างสกุลเงินเสมือนจริงสกุลแรกในโลกที่เรียกว่า Bitcoin เมื่อพิจารณาถึงความสำเร็จของ Bitcoin คนอื่น ๆ หลายคนได้สร้างสกุลเงินเสมือนของตนเอง เพื่อชื่อไม่กี่ - Litecoin, Zcash และอื่น ๆ

ตอนนี้คุณอาจต้องการเปิดตัวสกุลเงินของคุณเอง ให้เราเรียกสิ่งนี้ว่า TPCoin (TutorialsPoint Coin) คุณจะเขียนบล็อคเชนเพื่อบันทึกธุรกรรมทั้งหมดที่จัดการกับ TPCoin TPCoin สามารถใช้ซื้อพิซซ่าเบอร์เกอร์สลัด ฯลฯ อาจมีผู้ให้บริการรายอื่นที่จะเข้าร่วมเครือข่ายของคุณและเริ่มรับ TPCoin เป็นสกุลเงินสำหรับการให้บริการ ความเป็นไปได้ไม่มีที่สิ้นสุด

ในบทช่วยสอนนี้ให้เราเข้าใจวิธีสร้างระบบดังกล่าวและเปิดตัวสกุลเงินดิจิทัลของคุณเองในตลาด

ส่วนประกอบที่เกี่ยวข้องกับการพัฒนาโครงการ Blockchain

การพัฒนาโครงการ blockchain ทั้งหมดประกอบด้วยองค์ประกอบหลัก 3 ส่วน -

  • Client
  • Miners
  • Blockchain

ลูกค้า

ลูกค้าคือผู้ที่จะซื้อสินค้าจากผู้ขายรายอื่น ลูกค้าเองอาจกลายเป็นผู้ขายและจะรับเงินจากผู้อื่นจากสินค้าที่เขาจัดหา เราถือว่าลูกค้าสามารถเป็นซัพพลายเออร์และผู้รับ TPCoins ได้ ดังนั้นเราจะสร้างคลาสไคลเอนต์ในรหัสของเราที่มีความสามารถในการส่งและรับเงิน

คนงานเหมือง

คนงานเหมืองคือคนที่รับธุรกรรมจากกลุ่มธุรกรรมและรวบรวมไว้ในบล็อก ผู้ขุดจะต้องแสดงหลักฐานการทำงานที่ถูกต้องเพื่อรับรางวัลการขุด เงินทั้งหมดที่คนงานเหมืองเก็บเป็นค่าธรรมเนียมจะให้เขาเก็บไว้ เขาอาจใช้เงินนั้นในการซื้อสินค้าหรือบริการจากผู้ขายรายอื่นที่ลงทะเบียนบนเครือข่ายเช่นเดียวกับที่ลูกค้าอธิบายไว้ข้างต้น

บล็อกเชน

สุดท้าย Blockchain คือโครงสร้างข้อมูลที่เชื่อมโยงบล็อกที่ขุดได้ทั้งหมดตามลำดับเวลา โซ่นี้ไม่เปลี่ยนรูปและป้องกันอุณหภูมิได้

คุณสามารถทำตามบทช่วยสอนนี้ได้โดยพิมพ์โค้ดที่นำเสนอในแต่ละขั้นตอนในสมุดบันทึก Jupyter ใหม่ หรือคุณสามารถดาวน์โหลดโน้ตบุ๊ค Jupyter ทั้งหมดจากการwww.anaconda.com

ในบทต่อไปเราจะพัฒนาไคลเอนต์ที่ใช้ระบบบล็อกเชนของเรา

ลูกค้าคือคนที่ถือ TPCoins และทำธุรกรรมสำหรับสินค้า / บริการจากผู้ขายรายอื่นในเครือข่ายรวมถึงของเขาเองด้วย เราควรกำหนด aClientชั้นเรียนเพื่อการนี้ ในการสร้างรหัสประจำตัวที่ไม่ซ้ำกันทั่วโลกสำหรับไคลเอ็นต์เราใช้ PKI (Public Key Infrastructure) ในบทนี้ให้เราพูดถึงเรื่องนี้โดยละเอียด

ลูกค้าควรจะสามารถส่งเงินจากกระเป๋าเงินของเขาไปยังบุคคลอื่นที่รู้จักได้ ในทำนองเดียวกันลูกค้าควรสามารถรับเงินจากบุคคลที่สามได้ สำหรับการใช้จ่ายเงินลูกค้าจะสร้างธุรกรรมโดยระบุชื่อผู้ส่งและจำนวนเงินที่ต้องชำระ ในการรับเงินลูกค้าจะให้ข้อมูลประจำตัวของตนแก่บุคคลที่สามซึ่งโดยพื้นฐานแล้วเป็นผู้ส่งเงิน เราไม่เก็บยอดเงินที่ลูกค้าถือไว้ในกระเป๋าเงินของเขา ในระหว่างการทำธุรกรรมเราจะคำนวณยอดเงินจริงเพื่อให้แน่ใจว่าลูกค้ามียอดเงินเพียงพอที่จะชำระเงิน

เพื่อพัฒนา Clientคลาสและโค้ดที่เหลือในโปรเจ็กต์เราจะต้องนำเข้าไลบรารี Python จำนวนมาก เหล่านี้แสดงไว้ด้านล่าง -

# 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

นอกเหนือจากไลบรารีมาตรฐานข้างต้นเราจะลงนามในธุรกรรมของเราสร้างแฮชของอ็อบเจ็กต์ ฯลฯ สำหรับสิ่งนี้คุณจะต้องนำเข้าไลบรารีต่อไปนี้ -

# 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

ในบทถัดไปให้เราพูดถึงคลาสไคลเอนต์

Client คลาสสร้างไฟล์ private และ public คีย์โดยใช้ Python ในตัว RSAอัลกอริทึม ผู้อ่านที่สนใจอาจอ้างถึงthis tutorialสำหรับการใช้งาน RSA ในระหว่างการเริ่มต้นอ็อบเจ็กต์เราจะสร้างคีย์ส่วนตัวและคีย์สาธารณะและเก็บค่าไว้ในตัวแปรอินสแตนซ์

self._private_key = RSA.generate(1024, random)
self._public_key = self._private_key.publickey()

โปรดทราบว่าคุณไม่ควรทำคีย์ส่วนตัวหาย สำหรับการเก็บบันทึกคีย์ส่วนตัวที่สร้างขึ้นอาจถูกคัดลอกไปยังที่จัดเก็บข้อมูลภายนอกที่ปลอดภัยหรือคุณอาจจดการแสดง ASCII ลงบนกระดาษ

ที่สร้างขึ้น publicคีย์จะถูกใช้เป็นข้อมูลประจำตัวของลูกค้า สำหรับสิ่งนี้เรากำหนดคุณสมบัติที่เรียกว่าidentity ที่ส่งคืนการแสดง HEX ของคีย์สาธารณะ

@property
   def identity(self):
      return
binascii.hexlify(self._public_key.exportKey(format='DER'))
.decode('ascii')

identityไม่ซ้ำกันสำหรับลูกค้าแต่ละรายและสามารถเผยแพร่สู่สาธารณะได้ ใคร ๆ ก็สามารถส่งสกุลเงินเสมือนจริงให้คุณได้โดยใช้สิ่งนี้identity และจะถูกเพิ่มลงในกระเป๋าเงินของคุณ

รหัสเต็มสำหรับ Client คลาสแสดงที่นี่ -

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

ลูกค้าทดสอบ

ตอนนี้เราจะเขียนโค้ดที่จะแสดงวิธีการใช้ Client ชั้นเรียน -

Dinesh = Client()
print (Dinesh.identity)

โค้ดด้านบนสร้างอินสแตนซ์ของ Client และกำหนดให้กับตัวแปร Dinesh. เราพิมพ์คีย์สาธารณะของDinesh โดยเรียกมันว่า identityวิธี. ผลลัพธ์จะแสดงที่นี่ -

30819f300d06092a864886f70d010101050003818d0030818902818100b547fafceeb131e07
0166a6b23fec473cce22c3f55c35ce535b31d4c74754fecd820aa94c1166643a49ea5f49f72
3181ff943eb3fdc5b2cb2db12d21c06c880ccf493e14dd3e93f3a9e175325790004954c34d3
c7bc2ccc9f0eb5332014937f9e49bca9b7856d351a553d9812367dc8f2ac734992a4e6a6ff6
6f347bd411d07f0203010001

ตอนนี้เราให้เราไปสร้างธุรกรรมในบทถัดไป

ในบทนี้ให้เราสร้างไฟล์ Transactionชั้นเรียนเพื่อที่ลูกค้าจะสามารถส่งเงินให้ใครก็ได้ โปรดทราบว่าลูกค้าสามารถเป็นทั้งผู้ส่งหรือผู้รับเงิน เมื่อคุณต้องการรับเงินผู้ส่งรายอื่นจะสร้างธุรกรรมและระบุpublicที่อยู่ในนั้น เรากำหนดการเริ่มต้นของคลาสธุรกรรมดังนี้ -

def __init__(self, sender, recipient, value):
   self.sender = sender
   self.recipient = recipient
   self.value = value
   self.time = datetime.datetime.now()

init วิธีการใช้สามพารามิเตอร์ - ของผู้ส่ง public ที่สำคัญผู้รับ publicคีย์และจำนวนเงินที่จะส่ง สิ่งเหล่านี้ถูกเก็บไว้ในตัวแปรอินสแตนซ์เพื่อใช้โดยวิธีการอื่น นอกจากนี้เรายังสร้างตัวแปรอีกหนึ่งตัวสำหรับจัดเก็บเวลาในการทำธุรกรรม

ต่อไปเราจะเขียนวิธียูทิลิตี้ที่เรียกว่า to_dictที่รวมตัวแปรอินสแตนซ์ทั้งสี่ที่กล่าวถึงข้างต้นในออบเจ็กต์พจนานุกรม นี่เป็นเพียงการใส่ข้อมูลธุรกรรมทั้งหมดที่สามารถเข้าถึงได้ผ่านตัวแปรเดียว

ดังที่คุณทราบจากบทช่วยสอนก่อนหน้านี้ว่าบล็อกแรกในบล็อกเชนคือไฟล์ Genesisบล็อก. Genesis block มีธุรกรรมแรกที่ริเริ่มโดยผู้สร้าง blockchain ข้อมูลประจำตัวของบุคคลนี้อาจถูกเก็บเป็นความลับเช่นในกรณีของ Bitcoins ดังนั้นเมื่อมีการสร้างธุรกรรมครั้งแรกนี้ผู้สร้างอาจส่งข้อมูลประจำตัวของเขาเป็นGenesis. ดังนั้นในขณะที่สร้างพจนานุกรมเราจะตรวจสอบว่าผู้ส่งคือใครGenesisและถ้าเป็นเช่นนั้นเราก็กำหนดค่าสตริงให้กับตัวแปรเอกลักษณ์ มิฉะนั้นเรากำหนดตัวตนของผู้ส่งให้กับไฟล์identity ตัวแปร.

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

รหัสทั้งหมดสำหรับ to_dict วิธีการแสดงด้านล่าง -

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

สุดท้ายเราจะเซ็นชื่อวัตถุพจนานุกรมนี้โดยใช้คีย์ส่วนตัวของผู้ส่ง ก่อนหน้านี้เราใช้ PKI ในตัวพร้อมอัลกอริทึม SHA ลายเซ็นที่สร้างขึ้นจะถูกถอดรหัสเพื่อรับการแสดง ASCII สำหรับการพิมพ์และจัดเก็บไว้ในบล็อกเชนของเรา sign_transaction รหัสวิธีแสดงที่นี่ -

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

ตอนนี้เราจะทดสอบสิ่งนี้ Transaction ชั้นเรียน

การทดสอบคลาสธุรกรรม

เพื่อจุดประสงค์นี้เราจะสร้างผู้ใช้สองคนเรียกว่า Dinesh และ Ramesh. Dinesh จะส่ง 5 TPCoins ไปยัง Ramesh สำหรับสิ่งแรกนี้เราสร้างไคลเอนต์ชื่อ Dinesh และ Ramesh

Dinesh = Client()
Ramesh = Client()

จำไว้ว่าเมื่อคุณสร้างอินสแตนซ์ไฟล์ Client ชั้น public andคีย์ส่วนตัวเฉพาะสำหรับไคลเอ็นต์จะถูกสร้างขึ้น ในขณะที่ Dinesh ส่งการชำระเงินไปยัง Ramesh เขาจะต้องใช้กุญแจสาธารณะของ Ramesh ซึ่งได้มาจากการใช้คุณสมบัติประจำตัวของลูกค้า

ดังนั้นเราจะสร้างอินสแตนซ์ธุรกรรมโดยใช้รหัสต่อไปนี้ -

t = Transaction(
   Dinesh,
   Ramesh.identity,
   5.0
)

โปรดทราบว่าพารามิเตอร์แรกคือผู้ส่งพารามิเตอร์ที่สองคือคีย์สาธารณะของผู้รับและพารามิเตอร์ที่สามคือจำนวนเงินที่จะโอน sign_transaction วิธีดึงคีย์ส่วนตัวของผู้ส่งจากพารามิเตอร์แรกสำหรับการร้องเพลงธุรกรรม

หลังจากสร้างวัตถุธุรกรรมแล้วคุณจะเซ็นชื่อโดยเรียกใช้ sign_transactionวิธี. วิธีนี้ส่งคืนลายเซ็นที่สร้างขึ้นในรูปแบบที่พิมพ์ได้ เราสร้างและพิมพ์ลายเซ็นโดยใช้โค้ดสองบรรทัดต่อไปนี้ -

signature = t.sign_transaction()
print (signature)

เมื่อคุณรันโค้ดด้านบนคุณจะเห็นผลลัพธ์ที่คล้ายกับสิ่งนี้ -

7c7e3c97629b218e9ec6e86b01f9abd8e361fd69e7d373c38420790b655b9abe3b575e343c7
13703ca1aee781acd7157a0624db3d57d7c2f1172730ee3f45af943338157f899965856f6b0
0e34db240b62673ad5a08c8e490f880b568efbc36035cae2e748f1d802d5e8e66298be826f5
c6363dc511222fb2416036ac04eb972

เมื่อโครงสร้างพื้นฐานของเราในการสร้างลูกค้าและธุรกรรมพร้อมแล้วตอนนี้เราจะมีลูกค้าหลายรายที่ทำธุรกรรมหลายรายการเหมือนในสถานการณ์จริง

ธุรกรรมที่ทำโดยลูกค้าหลายรายจะอยู่ในคิวในระบบ คนงานเหมืองรับธุรกรรมจากคิวนี้และเพิ่มลงในบล็อก จากนั้นพวกเขาจะขุดบล็อกและนักขุดที่ชนะจะมีสิทธิพิเศษในการเพิ่มบล็อกลงในบล็อกเชนและจะได้รับเงินจำนวนหนึ่งสำหรับตัวเขาเอง

เราจะอธิบายกระบวนการขุดนี้ในภายหลังเมื่อเราพูดถึงการสร้างบล็อกเชน ก่อนที่เราจะเขียนโค้ดสำหรับธุรกรรมหลายรายการให้เราเพิ่มฟังก์ชันยูทิลิตี้ขนาดเล็กเพื่อพิมพ์เนื้อหาของธุรกรรมที่กำหนด

การแสดงธุรกรรม

display_transactionฟังก์ชันยอมรับพารามิเตอร์ชนิดเดียวของธุรกรรม อ็อบเจ็กต์พจนานุกรมภายในธุรกรรมที่ได้รับจะถูกคัดลอกไปยังตัวแปรชั่วคราวที่เรียกว่าdict และโดยใช้ปุ่มพจนานุกรมค่าต่างๆจะถูกพิมพ์บนคอนโซล

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

ต่อไปเราจะกำหนดคิวธุรกรรมสำหรับจัดเก็บวัตถุธุรกรรมของเรา

คิวการทำธุรกรรม

ในการสร้างคิวเราประกาศทั่วโลก list ตัวแปรที่เรียกว่า transactions ดังต่อไปนี้ -

transactions = []

เราจะต่อท้ายธุรกรรมที่สร้างขึ้นใหม่แต่ละรายการเข้ากับคิวนี้ โปรดทราบว่าเพื่อความรวดเร็วเราจะไม่ใช้ตรรกะการจัดการคิวในบทช่วยสอนนี้

การสร้างลูกค้าหลายราย

ตอนนี้เราจะเริ่มสร้างธุรกรรม ขั้นแรกเราจะสร้างลูกค้าสี่รายที่จะส่งเงินให้กันเพื่อขอรับบริการหรือสินค้าต่างๆจากผู้อื่น

Dinesh = Client()
Ramesh = Client()
Seema = Client()
Vijay = Client()

ณ จุดนี้เรามีลูกค้า 4 รายชื่อ Dinesh, Ramesh, Seema และ Vijay ขณะนี้เราถือว่าลูกค้าแต่ละรายถือ TPCoins บางส่วนไว้ในกระเป๋าสตางค์เพื่อทำธุรกรรม ข้อมูลประจำตัวของแต่ละไคลเอ็นต์เหล่านี้จะถูกระบุโดยใช้คุณสมบัติเอกลักษณ์ของอ็อบเจ็กต์เหล่านี้

การสร้างธุรกรรมครั้งแรก

ตอนนี้เราเริ่มต้นการทำธุรกรรมครั้งแรกของเราดังนี้ -

t1 = Transaction(
   Dinesh,
   Ramesh.identity,
   15.0
)

ในการทำธุรกรรมนี้ Dinesh จะส่ง 5 TPCoins ไปยัง Ramesh เพื่อให้การทำธุรกรรมประสบความสำเร็จเราจะต้องตรวจสอบให้แน่ใจว่า Dinesh มีเงินเพียงพอในกระเป๋าสตางค์ของเขาสำหรับการชำระเงินนี้ โปรดทราบว่าเราจำเป็นต้องมีการทำธุรกรรมขั้นต้นเพื่อเริ่มการหมุนเวียน TPCoin ในระบบ คุณจะเขียนรหัสธุรกรรมสำหรับธุรกรรมการกำเนิดนี้ในไม่ช้าเมื่อคุณอ่าน

เราจะลงนามในธุรกรรมนี้โดยใช้คีย์ส่วนตัวของ Dinesh และเพิ่มลงในคิวธุรกรรมดังนี้ -

t1.sign_transaction()
transactions.append(t1)

หลังจากการทำธุรกรรมครั้งแรกของ Dinesh เราจะสร้างธุรกรรมเพิ่มเติมอีกหลายรายการระหว่างลูกค้าต่างๆที่เราสร้างไว้ข้างต้น

การเพิ่มธุรกรรมเพิ่มเติม

ตอนนี้เราจะสร้างธุรกรรมอีกหลายรายการโดยแต่ละธุรกรรมจะให้ TPCoins สองสามรายการแก่บุคคลอื่น เมื่อมีคนใช้จ่ายเงินไม่จำเป็นที่เขาจะต้องตรวจสอบว่ามียอดคงเหลือเพียงพอในกระเป๋าเงินนี้หรือไม่ อย่างไรก็ตามผู้ขุดจะตรวจสอบความถูกต้องของธุรกรรมแต่ละรายการสำหรับยอดคงเหลือที่ผู้ส่งมีในขณะที่เริ่มต้นธุรกรรม

ในกรณีที่ยอดเงินไม่เพียงพอนักขุดจะทำเครื่องหมายธุรกรรมนี้ว่าไม่ถูกต้องและจะไม่เพิ่มลงในบล็อกนี้

รหัสต่อไปนี้สร้างและเพิ่มธุรกรรมอีกเก้ารายการในคิวของเรา

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)

เมื่อคุณรันโค้ดด้านบนคุณจะมีธุรกรรมสิบรายการในคิวเพื่อให้นักขุดสร้างบล็อกของพวกเขา

ธุรกรรมการทุ่มตลาด

ในฐานะผู้จัดการบล็อกเชนคุณอาจต้องการตรวจสอบเนื้อหาของคิวธุรกรรมเป็นระยะ เพื่อจุดประสงค์นี้คุณสามารถใช้ไฟล์display_transactionฟังก์ชันที่เราพัฒนาก่อนหน้านี้ ในการถ่ายโอนข้อมูลธุรกรรมทั้งหมดในคิวเพียงแค่วนซ้ำรายการธุรกรรมและสำหรับธุรกรรมที่อ้างถึงแต่ละรายการให้เรียกไฟล์display_transaction ฟังก์ชันดังแสดงที่นี่ -

for transaction in transactions:
   display_transaction (transaction)
   print ('--------------')

ธุรกรรมจะถูกคั่นด้วยเส้นประเพื่อความแตกต่าง หากคุณเรียกใช้รหัสด้านบนคุณจะเห็นรายการธุรกรรมดังที่แสดงด้านล่าง -

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

เพื่อความกะทัดรัดฉันได้พิมพ์ธุรกรรมเพียงไม่กี่รายการแรกในรายการ ในรหัสด้านบนเราจะพิมพ์ธุรกรรมทั้งหมดที่เริ่มต้นด้วยธุรกรรมแรกยกเว้นธุรกรรมการกำเนิดซึ่งไม่เคยถูกเพิ่มลงในรายการนี้ เนื่องจากมีการเพิ่มธุรกรรมลงในบล็อกเป็นระยะโดยทั่วไปคุณจะสนใจดูเฉพาะรายการธุรกรรมที่ยังไม่ต้องขุด ในกรณีนี้คุณจะต้องสร้างไฟล์for วนซ้ำเพื่อทำธุรกรรมที่ยังไม่ได้ขุด

จนถึงตอนนี้คุณได้เรียนรู้วิธีสร้างลูกค้าเปิดโอกาสให้พวกเขารวมกลุ่มกันและรักษาคิวของธุรกรรมที่รอดำเนินการซึ่งจะถูกขุด ตอนนี้เป็นส่วนที่สำคัญที่สุดของบทช่วยสอนนี้และนั่นคือการสร้างบล็อกเชนเอง คุณจะได้เรียนรู้สิ่งนี้ในบทเรียนถัดไป

บล็อกประกอบด้วยจำนวนธุรกรรมที่แตกต่างกัน เพื่อความง่ายในกรณีของเราเราจะถือว่าบล็อกประกอบด้วยจำนวนธุรกรรมคงที่ซึ่งเป็นสามในกรณีนี้ เนื่องจากบล็อกต้องการจัดเก็บรายการของธุรกรรมทั้งสามนี้เราจะประกาศตัวแปรอินสแตนซ์ที่เรียกว่าverified_transactions ดังต่อไปนี้ -

self.verified_transactions = []

เราได้ตั้งชื่อตัวแปรนี้ว่า verified_transactionsเพื่อระบุว่าเฉพาะธุรกรรมที่ตรวจสอบแล้วเท่านั้นที่จะถูกเพิ่มลงในบล็อก แต่ละบล็อกยังเก็บค่าแฮชของบล็อกก่อนหน้าเพื่อให้ห่วงโซ่ของบล็อกไม่เปลี่ยนรูป

ในการจัดเก็บแฮชก่อนหน้านี้เราประกาศตัวแปรอินสแตนซ์ดังนี้ -

self.previous_block_hash = ""

ในที่สุดเราก็ประกาศอีกหนึ่งตัวแปรที่เรียกว่า Nonce สำหรับจัดเก็บ nonce ที่ผู้ขุดสร้างขึ้นในระหว่างกระบวนการขุด

self.Nonce = ""

คำจำกัดความที่สมบูรณ์ของ Block ชั้นเรียนได้รับด้านล่าง -

class Block:
   def __init__(self):
      self.verified_transactions = []
      self.previous_block_hash = ""
      self.Nonce = ""

เนื่องจากแต่ละบล็อกต้องการค่าแฮชของบล็อกก่อนหน้าเราจึงประกาศตัวแปรส่วนกลางที่เรียกว่า last_block_hash ดังต่อไปนี้ -

last_block_hash = ""

ตอนนี้ให้เราสร้างบล็อกแรกของเราในบล็อกเชน

เราสันนิษฐานว่าผู้ริเริ่ม TPCoins ในตอนแรกให้ 500 TPCoins แก่ลูกค้าที่รู้จัก Dinesh. สำหรับสิ่งนี้เขาสร้างอินสแตนซ์ Dinesh เป็นครั้งแรก -

Dinesh = Client()

จากนั้นเราจะสร้างธุรกรรมการสร้างและส่ง 500 TPCoins ไปยังที่อยู่สาธารณะของ Dinesh

t0 = Transaction (
   "Genesis",
   Dinesh.identity,
   500.0
)

ตอนนี้เราสร้างอินสแตนซ์ของ Block ชั้นเรียนและโทร block0.

block0 = Block()

เราเริ่มต้นไฟล์ previous_block_hash และ Nonce ตัวแปรอินสแตนซ์เป็น Noneเนื่องจากนี่เป็นธุรกรรมแรกที่ถูกเก็บไว้ในบล็อกเชนของเรา

block0.previous_block_hash = None
Nonce = None

ต่อไปเราจะเพิ่มธุรกรรม t0 ข้างต้นในไฟล์ verified_transactions รายการที่อยู่ในบล็อก -

block0.verified_transactions.append (t0)

ณ จุดนี้บล็อกได้รับการเริ่มต้นอย่างสมบูรณ์และพร้อมที่จะเพิ่มลงในบล็อกเชนของเรา เราจะสร้าง blockchain เพื่อจุดประสงค์นี้ ก่อนที่เราจะเพิ่มบล็อกใน blockchain เราจะแฮชบล็อกและเก็บค่าไว้ในตัวแปรส่วนกลางที่เรียกว่าlast_block_hashที่เราประกาศไว้ก่อนหน้านี้ ค่านี้จะถูกใช้โดยนักขุดคนถัดไปในบล็อกของเขา

เราใช้การเข้ารหัสสองบรรทัดต่อไปนี้สำหรับการแฮชบล็อกและเก็บค่าไดเจสต์

digest = hash (block0)
last_block_hash = digest

ในที่สุดเราก็สร้าง blockchain ตามที่เราเห็นในบทต่อไป

บล็อกเชนประกอบด้วยรายการบล็อกที่เชื่อมโยงกัน ในการจัดเก็บรายการทั้งหมดเราจะสร้างตัวแปรรายการที่เรียกว่า TPCoins -

TPCoins = []

เราจะเขียนวิธียูทิลิตี้ที่เรียกว่า dump_blockchainสำหรับการทิ้งเนื้อหาของบล็อคเชนทั้งหมด ก่อนอื่นเราพิมพ์ความยาวของบล็อกเชนเพื่อให้เราทราบว่าปัจจุบันมีบล็อกเชนอยู่กี่บล็อก

def dump_blockchain (self):
   print ("Number of blocks in the chain: " + str(len (self)))

โปรดทราบว่าเมื่อเวลาผ่านไปจำนวนบล็อกในบล็อกเชนจะสูงเป็นพิเศษสำหรับการพิมพ์ ดังนั้นเมื่อคุณพิมพ์เนื้อหาของ blockchain คุณอาจต้องตัดสินใจเกี่ยวกับช่วงที่คุณต้องการตรวจสอบ ในโค้ดด้านล่างนี้เราได้พิมพ์บล็อคเชนทั้งหมดเนื่องจากเราจะไม่เพิ่มบล็อกมากเกินไปในการสาธิตปัจจุบัน

เราตั้งค่าไฟล์ for วนดังนี้ -

for x in range (len(TPCoins)):
   block_temp = TPCoins[x]

แต่ละบล็อกที่อ้างอิงจะถูกคัดลอกไปยังตัวแปรชั่วคราวที่เรียกว่า block_temp.

เราพิมพ์หมายเลขบล็อกเป็นหัวเรื่องสำหรับแต่ละบล็อก โปรดทราบว่าตัวเลขจะเริ่มต้นด้วยศูนย์บล็อกแรกคือบล็อกการกำเนิดที่มีหมายเลขศูนย์

print ("block # " + str(x))

ภายในแต่ละบล็อกเราได้จัดเก็บรายการธุรกรรมสามรายการ (ยกเว้นบล็อกการกำเนิด) ในตัวแปรที่เรียกว่า verified_transactions. เราทำซ้ำรายการนี้ในไฟล์for วนซ้ำและสำหรับแต่ละรายการที่ดึงมาเราเรียก display_transaction เพื่อแสดงรายละเอียดธุรกรรม

for transaction in block_temp.verified_transactions:
   display_transaction (transaction)

คำจำกัดความของฟังก์ชันทั้งหมดแสดงอยู่ด้านล่าง -

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

โปรดทราบว่าที่นี่เราได้แทรกตัวคั่นตามจุดที่เหมาะสมในรหัสเพื่อแบ่งเขตการบล็อกและธุรกรรมภายใน

เนื่องจากตอนนี้เราได้สร้าง blockchain สำหรับจัดเก็บบล็อกแล้วงานต่อไปของเราคือการสร้างบล็อกและเริ่มเพิ่มลงใน blockchain เพื่อจุดประสงค์นี้เราจะเพิ่มบล็อกการกำเนิดที่คุณได้สร้างไว้แล้วในขั้นตอนก่อนหน้านี้

การเพิ่มบล็อกใน blockchain เกี่ยวข้องกับการผนวกบล็อกที่สร้างขึ้นกับไฟล์ TPCoins รายการ.

TPCoins.append (block0)

โปรดทราบว่าแตกต่างจากบล็อกอื่น ๆ ในระบบบล็อกการกำเนิดมีเพียงธุรกรรมเดียวที่เริ่มต้นโดยผู้ริเริ่มระบบ TPCoins ตอนนี้คุณจะถ่ายโอนเนื้อหาของ blockchain โดยเรียกใช้ฟังก์ชันส่วนกลางของเราdump_blockchain -

dump_blockchain(TPCoins)

เมื่อคุณเรียกใช้ฟังก์ชันนี้คุณจะเห็นผลลัพธ์ต่อไปนี้ -

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
-----
--------------
=====================================

ณ จุดนี้ระบบบล็อกเชนพร้อมใช้งานแล้ว ตอนนี้เราจะช่วยให้ลูกค้าที่สนใจสามารถเป็นคนงานเหมืองได้โดยมอบฟังก์ชันการขุด

สำหรับการเปิดใช้งานการขุดเราจำเป็นต้องพัฒนาฟังก์ชันการขุด ฟังก์ชั่นการขุดจำเป็นต้องสร้างข้อมูลย่อยในสตริงข้อความที่กำหนดและให้หลักฐานการทำงาน ให้เราพิจารณาเรื่องนี้ในบทนี้

ฟังก์ชันย่อยข้อความ

เราจะเขียนฟังก์ชันยูทิลิตี้ที่เรียกว่า sha256 สำหรับการสร้างสรุปข้อความที่กำหนด -

def sha256(message):
return hashlib.sha256(message.encode('ascii')).hexdigest()

sha256 ฟังก์ชันใช้เวลา a message เป็นพารามิเตอร์เข้ารหัสเป็น ASCII สร้างการย่อยเลขฐานสิบหกและส่งคืนค่าให้กับผู้เรียก

ฟังก์ชั่นการขุด

ตอนนี้เราพัฒนาไฟล์ mineฟังก์ชันที่ใช้กลยุทธ์การขุดของเราเอง กลยุทธ์ของเราในกรณีนี้คือการสร้างแฮชบนข้อความที่กำหนดซึ่งขึ้นต้นด้วยจำนวน 1 ที่กำหนด จำนวน 1 ที่กำหนดถูกระบุเป็นพารามิเตอร์สำหรับmine ฟังก์ชันที่ระบุเป็นระดับความยาก

ตัวอย่างเช่นหากคุณระบุระดับความยากเป็น 2 แฮชที่สร้างขึ้นในข้อความหนึ่ง ๆ ควรเริ่มต้นด้วย 1 สองตัว - เช่น 11xxxxxxxx หากระดับความยากคือ 3 แฮชที่สร้างขึ้นควรเริ่มต้นด้วยสาม 1 เช่น 111xxxxxxxx ด้วยข้อกำหนดเหล่านี้เราจะพัฒนาฟังก์ชันการขุดดังที่แสดงในขั้นตอนด้านล่าง

ขั้นตอนที่ 1

ฟังก์ชั่นการขุดใช้สองพารามิเตอร์ - ข้อความและระดับความยาก

def mine(message, difficulty=1):

ขั้นตอนที่ 2

ระดับความยากจะต้องมากกว่าหรือเท่ากับ 1 เรารับรองสิ่งนี้ด้วยข้อความยืนยันต่อไปนี้ -

assert difficulty >= 1

ขั้นตอนที่ 3

เราสร้างไฟล์ prefix ตัวแปรโดยใช้ระดับความยากที่ตั้งไว้

prefix = '1' * difficulty

โปรดทราบว่าระดับความยากคือ 2 หรือไม่คำนำหน้าจะเป็น“ 11” และหากระดับความยากคือ 3 คำนำหน้าจะเป็น“ 111” เป็นต้น เราจะตรวจสอบว่าคำนำหน้านี้มีอยู่ในส่วนย่อยที่สร้างขึ้นของข้อความหรือไม่ ในการย่อยข้อความเราใช้โค้ดสองบรรทัดต่อไปนี้ -

for i in range(1000):
   digest = sha256(str(hash(message)) + str(i))

เรายังคงเพิ่มหมายเลขใหม่ iไปยังแฮชข้อความในการวนซ้ำแต่ละครั้งและสร้างไดเจสต์ใหม่ในข้อความที่รวมกัน เป็นอินพุตไปยังไฟล์sha256 ฟังก์ชันจะเปลี่ยนไปในทุกๆการวนซ้ำไฟล์ digestมูลค่าก็จะเปลี่ยนไปเช่นกัน เราตรวจสอบว่าสิ่งนี้digest มีค่าที่ตั้งไว้ด้านบน prefix.

if digest.startswith(prefix):

หากเงื่อนไขเป็นที่พอใจเราจะยุติการใช้งาน for วนซ้ำและส่งคืนไฟล์ digest มูลค่าให้กับผู้โทร

ทั้งหมด mine รหัสแสดงที่นี่ -

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

เพื่อความเข้าใจของคุณเราได้เพิ่มไฟล์ print คำสั่งที่พิมพ์ค่าการย่อยและจำนวนการทำซ้ำที่ต้องใช้เพื่อให้เป็นไปตามเงื่อนไขก่อนที่จะกลับจากฟังก์ชัน

การทดสอบฟังก์ชั่นการขุด

หากต้องการทดสอบฟังก์ชันการขุดของเราเพียงดำเนินการตามคำสั่งต่อไปนี้ -

mine ("test message", 2)

เมื่อคุณรันโค้ดด้านบนคุณจะเห็นผลลัพธ์คล้ายกับโค้ดด้านล่าง -

after 138 iterations found nonce:
11008a740eb2fa6bf8d55baecda42a41993ca65ce66b2d3889477e6bfad1484c

สังเกตว่าไดเจสต์ที่สร้างขึ้นเริ่มต้นด้วย“ 11” หากคุณเปลี่ยนระดับความยากเป็น 3 ไดเจสต์ที่สร้างขึ้นจะเริ่มต้นด้วย“ 111” และแน่นอนว่าอาจต้องใช้การทำซ้ำหลายครั้ง อย่างที่คุณเห็นนักขุดที่มีพลังในการประมวลผลมากกว่าจะสามารถขุดข้อความที่ระบุได้ก่อนหน้านี้ นั่นเป็นวิธีที่คนงานเหมืองแข่งขันกันเพื่อหารายได้

ตอนนี้เราพร้อมที่จะเพิ่มบล็อกให้กับบล็อกเชนของเราแล้ว ให้เราเรียนรู้สิ่งนี้ในบทต่อไปของเรา

นักขุดแต่ละคนจะรับธุรกรรมจากกลุ่มธุรกรรมที่สร้างขึ้นก่อนหน้านี้ ในการติดตามจำนวนข้อความที่ถูกขุดเราต้องสร้างตัวแปรส่วนกลาง -

last_transaction_index = 0

ตอนนี้เราจะมีนักขุดคนแรกของเราที่เพิ่มบล็อกในบล็อกเชน

การเพิ่มบล็อกแรก

ในการเพิ่มบล็อกใหม่เราต้องสร้างอินสแตนซ์ของไฟล์ Block ชั้นเรียน

block = Block()

เราเลือกธุรกรรม 3 อันดับแรกจากคิว -

for i in range(3):
   temp_transaction = transactions[last_transaction_index]
   # validate transaction

ก่อนที่จะเพิ่มธุรกรรมลงในบล็อกผู้ขุดจะตรวจสอบความถูกต้องของธุรกรรม ความถูกต้องของธุรกรรมได้รับการตรวจสอบโดยการทดสอบความเท่าเทียมกันของแฮชที่ผู้ส่งมอบให้กับแฮชที่สร้างโดยผู้ขุดโดยใช้คีย์สาธารณะของผู้ส่ง นอกจากนี้ผู้ขุดจะตรวจสอบว่าผู้ส่งมียอดเงินเพียงพอที่จะจ่ายสำหรับธุรกรรมปัจจุบัน

เพื่อความกะทัดรัดเราไม่ได้รวมฟังก์ชันนี้ไว้ในบทช่วยสอน หลังจากตรวจสอบความถูกต้องของธุรกรรมแล้วเราจะเพิ่มลงในไฟล์verified_transactions รายการใน block ตัวอย่าง.

block.verified_transactions.append (temp_transaction)

เราเพิ่มดัชนีธุรกรรมสุดท้ายเพื่อให้คนงานเหมืองคนต่อไปรับธุรกรรมที่ตามมาในคิว

last_transaction_index += 1

เราเพิ่มธุรกรรมสามรายการลงในบล็อก เมื่อเสร็จแล้วเราจะเริ่มต้นตัวแปรอินสแตนซ์ที่เหลือของไฟล์Blockชั้นเรียน ก่อนอื่นเราเพิ่มแฮชของบล็อกสุดท้าย

block.previous_block_hash = last_block_hash

ต่อไปเราขุดบล็อกด้วยระดับความยาก 2

block.Nonce = mine (block, 2)

โปรดทราบว่าพารามิเตอร์แรกของ mineฟังก์ชันเป็นวัตถุไบนารี ตอนนี้เราแฮชบล็อกทั้งหมดและสร้างข้อมูลย่อย

digest = hash (block)

สุดท้ายเราเพิ่มบล็อกที่สร้างขึ้นในบล็อกเชนและเริ่มต้นตัวแปรส่วนกลางอีกครั้ง last_block_hash เพื่อใช้ในบล็อกถัดไป

รหัสทั้งหมดสำหรับการเพิ่มบล็อกแสดงอยู่ด้านล่าง -

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

เมื่อคุณเพิ่มสองบล็อกนี้คุณจะเห็นจำนวนการทำซ้ำที่ใช้ในการค้นหา Nonce ณ จุดนี้บล็อกเชนของเราประกอบด้วยบล็อกทั้งหมด 4 บล็อกรวมถึงบล็อกกำเนิด

การทิ้งบล็อกเชนทั้งหมด

คุณสามารถตรวจสอบเนื้อหาของ blockchain ทั้งหมดโดยใช้คำสั่งต่อไปนี้ -

dump_blockchain(TPCoins)

คุณจะเห็นผลลัพธ์คล้ายกับที่แสดงด้านล่าง -

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
-----
--------------
=====================================

ในบทช่วยสอนนี้เราได้เรียนรู้วิธีสร้างโครงการบล็อกเชนใน Python มีหลายพื้นที่ที่คุณต้องเพิ่มฟังก์ชันเพิ่มเติมให้กับโครงการนี้

ตัวอย่างเช่นคุณจะต้องเขียนฟังก์ชันสำหรับจัดการคิวธุรกรรม หลังจากการทำธุรกรรมถูกขุดและระบบยอมรับบล็อกการขุดแล้วไม่จำเป็นต้องจัดเก็บอีกต่อไป

นอกจากนี้คนงานเหมืองมักต้องการรับธุรกรรมที่มีค่าธรรมเนียมสูงสุด ในขณะเดียวกันคุณจะต้องมั่นใจว่าธุรกรรมที่มีค่าธรรมเนียมต่ำหรือไม่มีเลยจะไม่อดตายตลอดไป

คุณจะต้องพัฒนาอัลกอริทึมสำหรับจัดการคิว นอกจากนี้บทช่วยสอนปัจจุบันยังไม่มีรหัสอินเทอร์เฟซไคลเอ็นต์ คุณจะต้องพัฒนาสิ่งนี้สำหรับทั้งลูกค้าปกติและคนงานเหมือง โครงการบล็อกเชนเต็มรูปแบบจะทำงานในโค้ดอีกหลายบรรทัดและอยู่นอกเหนือขอบเขตของบทช่วยสอนนี้ ผู้อ่านที่สนใจสามารถดาวน์โหลดแหล่ง bitcoinเพื่อศึกษาเพิ่มเติม

ข้อสรุป

บทช่วยสอนที่คมชัดนี้ควรช่วยให้คุณเริ่มสร้างโครงการบล็อกเชนของคุณเอง

สำหรับการพัฒนาโครงการที่เต็มเปี่ยม blockchain คุณสามารถเรียนรู้เพิ่มเติมจากแหล่ง Bitcoin

สำหรับโครงการเชิงพาณิชย์หรือไม่ใช่เชิงพาณิชย์ขนาดใหญ่คุณอาจพิจารณาใช้Ethereumซึ่งเป็นแพลตฟอร์มแอปบล็อกเชนที่พร้อมใช้งาน