區塊鏈基礎認識-BTC

一、什麼是區塊鏈html

a.定義:node

         從本質上來講區塊鏈就是一種經過將用戶的某種特定信息(好比交易信息),經過不少臺計算機記錄保存並同步的過程,每一個區塊都記錄了對應的交易信息,將這些交易信息串聯起來就造成了所謂的區塊鏈,區塊鏈也就是存儲在不少計算機節點中的數據庫同樣的文件db。python

         從技術上來講,區塊鏈是分佈式數據存儲、點對點傳輸、共識機制、加密算法等計算機技術的新型應用模式,區塊鏈技術設計了當今世界上基本全部的計算機相關問題。區塊鏈技術推進着計算機計算速度的發展,不斷更新迭代優化計算機的軟硬件性能。git

         從用途上來講,區塊鏈是一套以幾乎沒法僞造或篡改的方式構建而成的數據存儲數學架構,可用於存儲各種有價值數據。算法

b.特色:數據庫

  • 去中心化:因爲使用分佈式覈算和存儲,不存在中心化的硬件或管理機構,任意節點的權利和義務都是均等。
  • 去信任:系統中全部節點之間無需信任也能夠進行交易,由於數據庫和整個系統的運做是公開透明的,在系統的規則和時間範圍內,節點之間沒法欺騙彼此。
  • 開放性:系統是開放的,除了交易各方私有信息被加密外,區塊鏈的數據對全部人公開,任何人均可以經過公開的接口查詢區塊鏈數據。
  • 自治性:區塊鏈採用基於協商一致的規範和協議,使得整個系統中的全部節點可以在去信任的環境自由安全的交換數據。
  • 信息不可篡改:一旦信息通過驗證並添加至區塊鏈,就會永久存儲,除非可以同時控制住系統中超過51%的節點,不然單個節點上對數據庫的修改是無效。
  • 匿名性:因爲節點之間的交換遵循固定的算法,其數據交互是無需信任的。

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

代碼運行結果:

總共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()
View Code

三、BTC-Address:

定義:比特幣地址由數字和字母組成的字符串,由公鑰生成的比特幣地址以數字1開頭 eg:1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy

比特幣地址能夠由公鑰經過單向哈希加密算法獲得:

  1. SHA256()
  2. RIPEMD160()
  3. SHA160()  1和2合併在一塊兒:SHA160(data) = RIPEDMD(SHA256(data))

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))
View Code

運行咱們所獲得的代碼,結果以下:(取了5個Block)

Block的Hash值都知足要求,併成功加入了區塊鏈中

五、參考文章

區塊鏈通俗漫畫介紹Reference001http://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 
相關文章
相關標籤/搜索