一、什麼是區塊鏈html
a.定義:node
從本質上來講區塊鏈就是一種經過將用戶的某種特定信息(好比交易信息),經過不少臺計算機記錄保存並同步的過程,每一個區塊都記錄了對應的交易信息,將這些交易信息串聯起來就造成了所謂的區塊鏈,區塊鏈也就是存儲在不少計算機節點中的數據庫同樣的文件db。python
從技術上來講,區塊鏈是分佈式數據存儲、點對點傳輸、共識機制、加密算法等計算機技術的新型應用模式,區塊鏈技術設計了當今世界上基本全部的計算機相關問題。區塊鏈技術推進着計算機計算速度的發展,不斷更新迭代優化計算機的軟硬件性能。git
從用途上來講,區塊鏈是一套以幾乎沒法僞造或篡改的方式構建而成的數據存儲數學架構,可用於存儲各種有價值數據。算法
b.特色:數據庫
c.區塊鏈圖示:json
二、區塊鏈中BTC的基本組成部分安全
以下圖所示,這是BTC的四大基本組成模塊網絡
a.BTC區塊鏈Block Chain:數據結構
區塊鏈用來將生成的全部的區塊串聯起來,區塊鏈的高度表示了當前總共擁有的區塊數量,區塊鏈每間隔十分鐘就會廣播一次,將完成的區塊交易信息內容添加到區塊鏈當中,同時給完成區塊ID尋找的礦機進行獎勵,每格四年,產生區塊的礦機獎勵的BTC就會減半,所以比特幣是收斂幣種,不存在通貨膨脹的狀況(BTC產生狀況看下圖),比特幣可以維持到2140年的緣由是因爲比特幣系統會根據計算機的算力變化調整挖礦的難度,從而控制了BTC的發行速度!
代碼以下:
1 import matplotlib.pyplot as plt 2 from PIL import Image 3 import time 4 import sys 5 import os 6 7 # 初始獎勵50BTC 8 start_block_reward = 50 9 # 以10分鐘爲一個區塊間隔,210000塊=4Year*365Day*24Hour*6,須要4年 10 reward_interval = 210000 11 12 Year = [] 13 Satoshis = [] 14 15 def max_money(): 16 # 50 BTC = 50 0000 0000 Satoshis 17 current_reward = 50 * 10**8 18 total = 0 19 year = 2008 20 while current_reward > 0: 21 total += reward_interval * current_reward 22 Satoshis.append(total) 23 current_reward /= 2 24 Year.append(year) 25 year += 4 26 return total 27 print("Total BTC to ever be created:", max_money(), "Satoshis") 28 print("1 BTC = 100000000 Satoshis!") 29 30 plt.xlim((2008,2140)) 31 plt.plot(Year,Satoshis) 32 plt.show()
代碼運行結果:
總共2100萬個BTC截至2140年
notice:區塊鏈分叉是因爲世界範圍內的網絡情況不一樣,可能同時有兩個區塊同時產生了,一個在歐洲A,一個在南美洲B,那麼距離節點nodeA近的先收到了A的廣播,一樣的距離nodeB近的節點先收到了B的廣播,所以在兩部分結點確認數增多以後,就會發生區塊鏈的分叉,分叉的狀況會暫時保存下來,等到下一個區塊的出來,甚至下下一個區塊的出現,最終區塊鏈長的那一邊做爲最終的區塊鏈,這樣區塊鏈又會收斂到同一個區塊鏈之上,保證了區塊鏈的惟一性。
b.BTC區塊Block:
區塊Block中存儲了當前大部分的交易的內容,那麼區塊由誰來產生呢,那就是礦工miners(礦機),礦機經過收集網絡節點上的全部的交易信息,根據每一筆交易提供的交易費用來完成優先級排序,交易費越高越容易被快速處理,在確認這些高優先級的交易信息以後,miners將會將這些交易信息進行打包,將打包好的數據存放起來,開始生成區塊對應的區塊ID(一個很難計算的HASH值),如若某個miners優先找到了知足要求的HASH-Value,那麼它將獲得此次的比特幣獎勵,以及交易收取的手續費。下面簡單的看一下如何計算知足要求的HASH值:
代碼以下:
1 import numpy as np 2 # Hash哈希運算庫-SHA128 SHA256 MD5 3 import hashlib 4 import time 5 import sys 6 import os 7 # 工做量證實算法 8 max_nonce = 2**32 # 4 billion 9 10 def proof_of_work(header,difficulty_bits): 11 # calc the difficulty target 12 target = 2**(256-difficulty_bits) 13 for nonce in range(max_nonce): 14 temp = str(header)+str(nonce) 15 hash_result = hashlib.sha256(temp.encode('utf-8')).hexdigest() 16 # check if this is a valid result,below the target 17 if int(hash_result,16) < target: 18 print("Success with nonce %d" % nonce) 19 print("Hash is %s" % hash_result) 20 return hash_result,nonce 21 print("Failed after %d (max_nonce) tries" % max_nonce) 22 23 Start_time = time.time() 24 proof_of_work('Hash_val',22) 25 End_time = time.time() 26 print('The time cost:', End_time-Start_time, 's')
代碼運行結果:
咱們能夠看到,當難度爲22時,計算出一個知足要求的Hash值須要的時間約爲6.7s,隨着難度的增長,這個時間將會呈指數級增加!
c.BTC交易exchange:
在BTC交易的過程當中,咱們能夠用比特幣兌換咱們想要的物品,也能夠將比特幣轉移給別人,不管哪種方式,都須要將指定的BTC輸送到對應的錢包的地址上。
在BTC未交易的時候,BTC處於UTXO的狀態,這種狀態一直被阻塞,直到BTC的所屬者經過他的私鑰和數字簽名釋放BTC,完成轉帳的功能,BTC在完成轉帳以後可能還會存在找零,找零的BTC又會處於UTXO狀態,而接收者的比特幣地址,也就是錢包的地址處於的狀態時URTX狀態,等待對應的轉帳功能!
d.BTC錢包Wallet:
BTC錢包主要涉及一下的三個部分:
一、私鑰Private-Key:
定義:一個隨機生成數,比特幣地址中資金控制權都對應於私鑰的全部權和控制權,私鑰用於支付比特幣所必須的簽名以證實資金的所屬權,私鑰必須保持機密。
私鑰建立:生成密鑰的第一步,就是要找到足夠安全的熵源,即隨機性來源,咱們可使用python中的random函數生成咱們的密鑰,或者咱們也可使用橢圓曲線密碼學中的ECC函數來生成咱們的密鑰。函數以下:
1 numpy:key = np.random.random() 2 Key = EEC_Encrypte()
二、公鑰Public-Key:
定義:經過橢圓曲線乘法來獲得咱們須要的公鑰,這ge過程是不可逆轉的,將私鑰做爲ECC函數的輸入,從而獲得公鑰輸出結果 。
橢圓曲線方程:
BTC採用的EEC方程爲secp256k1標準所定義 的一條特殊的曲線以及一系列的數學常數,該 標準由NIST設立:
Function:y^2 mod p = (x^3+7) mod p 素數p:2^256-2^32-2^9-2^8-2^7-2^6-2^4-1 G點:稱爲生成點的常數點 加法運算:P1+P2=P3(P3爲曲線上P1和P2兩點 連線與橢圓曲線的交點) 乘法運算:k*P=P+P+...+P(k個P相加)
橢圓曲線的離散圖像的繪製:
1 import matplotlib.pyplot as plt 2 from PIL import Image 3 import numpy as np 4 # Hash哈希運算庫-SHA128 SHA256 MD5 5 import hashlib 6 # OepnSSL加密庫-EEC橢圓曲線加密函數計算公鑰 7 import OpenSSL 8 import random 9 import time 10 import sys 11 import os 12 13 # 學習如何使用EEC橢圓曲線加密問題,ECC函數的實現方式等等 14 # The ecc function is: (x^3+7) mod P = y^2 mod P 15 P = 17 16 x= np.linspace(0,P,P,dtype='int') 17 y = list() 18 for i in x: 19 temp = (i**3 + 7) % P 20 append_flag = 0 21 for j in range(0,P): 22 if j**2 % P == temp: 23 y.append(j) 24 append_flag = 1 25 break 26 if append_flag == 0: 27 y.append(-1) 28 Y = np.array(y) 29 X = x 30 plt.xlim( (0, P) ) 31 plt.ylim( (0, P) ) 32 plt.scatter(X, Y) 33 # Y^2 mod P==0 ==> (Y-P)^2 mod P==0 ==> (Y^2-2*Y*P+P^2) mod P = Y^2 mod P 34 plt.scatter(X, P-Y) 35 plt.show() 36 37 I = Image.open(os.path.join('.vscode\Bitmain_Miner_Ref\EEC_Vector_Graph.png')) 38 I.show() 39 40 # -8除以3的餘數:商-3餘數1(餘數是不能爲負數的!) 41 print(-8 % 3) 42 43 x = np.linspace(-0.7,5,1000) 44 y = np.sqrt(x**3+x+1) 45 46 plt.xlim(-5,5) 47 plt.ylim(-6,6) 48 plt.plot(x,y) 49 plt.plot(x,-y) 50 plt.show() 51 52 x = np.linspace(-1,5,1000) 53 y1 = np.sqrt(x**3-x) 54 plt.xlim(-5,5) 55 plt.ylim(-6,6) 56 plt.plot(x,y1) 57 plt.plot(x,-y1) 58 plt.show()
三、BTC-Address:
定義:比特幣地址由數字和字母組成的字符串,由公鑰生成的比特幣地址以數字1開頭 eg:1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
比特幣地址能夠由公鑰經過單向哈希加密算法獲得:
BTC-Address生成流程圖:
三、深刻分析BTC中區塊鏈技術 & 區塊特性
咱們主要分析區塊鏈以及區塊的相關內容:
四、使用python來實現上述相關API和數據結構:
1 import numpy as np 2 # Hash哈希運算庫-SHA128 SHA256 MD5 3 import hashlib 4 # OepnSSL加密庫-EEC橢圓曲線加密函數計算公鑰 5 import OpenSSL 6 import random 7 import json 8 import time 9 import sys 10 import os 11 12 max_nonce = 2**32 # 4 billion 13 difficulty_bits = 12 14 target = 2**(256-difficulty_bits) 15 16 class block: 17 def __init__(self): 18 self.data = {'Magicno':0xD9B4BEF9, 'Blocksize':0, \ 19 'Blockheader':[0,0,0,0,0,0], 'Transition_counter':0, \ 20 'transitions':[]} 21 self.edition = 1.0 22 self.time = 0.0 23 self.Hash = 0 24 self.PreHash = 0 25 self.Nonce = 0 26 27 def proof_of_work(header): 28 # calc the difficulty target 29 for nonce in range(max_nonce): 30 temp = header+str(nonce) 31 hash_result = hashlib.sha256(temp.encode('utf-8')).hexdigest() 32 print(str(hash_result), end='\r') 33 # check if this is a valid result,below the target 34 if int(hash_result,16) < target: 35 # print("Success with nonce %d" % nonce) 36 # print("Hash is %s" % hash_result) 37 return hash_result,nonce 38 print("Failed after %d (max_nonce) tries" % max_nonce) 39 40 def Self_Hash_Get(PreHash, time, data): 41 header = str(PreHash) + str(time) + str(data) 42 hash_result,nonce = proof_of_work(header) 43 return hash_result,nonce 44 45 def New_block(transitions, PreBlockHash, block): 46 block.data['Transition_counter'] = len(transitions) 47 block.data['transitions'] = transitions 48 block.data['Blocksize'] = sys.getsizeof(block.data) 49 block.time = time.time() 50 block.PreHash = PreBlockHash 51 hash_result, hash_nonce = Self_Hash_Get(block.PreHash, block.time, block.data) 52 block.Hash = hash_result 53 block.Nonce = hash_nonce 54 55 def NewGenesisBlock(block): 56 New_block('NewGenesisBlock', b'', block) 57 58 class block_chain: 59 def __init__(self): 60 self.block = [] 61 62 chain = block_chain() 63 64 def AddBlockChain(block,chain): 65 if int(block.Hash, 16) < target: 66 chain.block.append(block) 67 else: 68 print('Invalid block!') 69 70 def CreateBlockChain(chain): 71 Block = block() 72 NewGenesisBlock(Block) 73 AddBlockChain(Block,chain) 74 75 def GetLastBlockHash(chain): 76 return chain.block[len(chain.block)-1].Hash 77 78 CreateBlockChain(chain) 79 for i in range(10): 80 transitions = ['Li Send 10BTC to You', 'Ni Get 2BTC from Dian'] 81 PreBlockHash = GetLastBlockHash(chain) 82 Block = block() 83 print('Calculating Hash...') 84 New_block(transitions, PreBlockHash, Block) 85 AddBlockChain(Block,chain) 86 87 for i in range(len(chain.block)): 88 print('Block%d\'HashVal=%s' %(i ,chain.block[i].Hash))
運行咱們所獲得的代碼,結果以下:(取了5個Block)
Block的Hash值都知足要求,併成功加入了區塊鏈中
五、參考文章
區塊鏈通俗漫畫介紹Reference001:http://www.javashuo.com/article/p-ypzdetyu-hh.html
區塊鏈Go語言實現Step-byStep-Reference002:https://liuchengxu.gitbook.io/blockchain/
加密算法Reference003:http://www.javashuo.com/article/p-pcqckpvv-bq.html
BTC Donation Thanks a lot!
3Jvg6ao53eCnj7EgapEa7arxsouLVxxQ4F