網(wǎng)站首頁 編程語言 正文
人工智能和區(qū)塊鏈誕生至今已經(jīng)有了十幾年,當(dāng)這些技術(shù)出現(xiàn)時,人們都說他們會改變世界,但至今為止,這兩項技術(shù)對現(xiàn)實(shí)的影響依然有限。從技術(shù)上看人工智能的原理其實(shí)是從大量數(shù)據(jù)中尋找規(guī)律或模式,但區(qū)塊鏈的技術(shù)原理是什么呢?在我看來區(qū)塊鏈的原理一直處于云里霧里,有很多近乎玄學(xué)的解釋將其籠罩,有人從經(jīng)濟(jì)學(xué)解釋,有人從社會學(xué)解釋,從”人文“角度解釋的區(qū)塊鏈總是過于夸大其詞,這些說法中往往又包含不良用心。
由此我想去蕪存真,我們不用關(guān)心區(qū)塊鏈如何”改變世界“,我們就從純技術(shù)角度去探討,其實(shí)區(qū)塊鏈和人工智能一樣,從技術(shù)的角度看去,他們都有著極為美妙的設(shè)計思想,這些設(shè)計的美妙就像唐詩宋詞,就像畢加索的話,如果我們沒有去欣賞它的美,那豈不可惜。相比于人工智能,我認(rèn)為區(qū)塊鏈在技術(shù)上更容易被普通人觸碰,因?yàn)榍罢咝枰罅康臄?shù)據(jù)和算力,而后者只要我們掌握其技術(shù)原理就能參與其中,不需要太高的硬件門檻。
話不多說,我們看看如何用python代碼把最基本的區(qū)塊鏈原理編寫出來。首先我們看區(qū)塊鏈的數(shù)據(jù)結(jié)構(gòu),它包含三部分信息,一是用于標(biāo)志自己的id,它是一個整數(shù),第二個是用于記錄前一個區(qū)塊的id,也是一個整數(shù),由于區(qū)塊用于記錄信息,因此它還包含一個字段,我們用history來表示,這個字段用來記錄當(dāng)前發(fā)生了的信息,區(qū)塊鏈最大的作用就是讓這段信息可驗(yàn)證而且不可更改,我們先看數(shù)據(jù)結(jié)構(gòu)的定義,先創(chuàng)建文件block.:
class Block: def __init__(self): self.id = None self.history = None self.parent_id = None
接下來我們看看區(qū)塊如何行成”鏈“,同時如何記錄信息。假設(shè)我們想要記錄這么一個事件:張三想跟李四用一百塊買三條魚,李四收到一百塊后給了張三三條魚”,那么我們可以使用下面代碼用區(qū)塊鏈進(jìn)行記錄,創(chuàng)建main.py,然后給出如下代碼:
from block import * block_A = Block() block_A.id = 1 block_A.history = '張三想要三條魚' block_B = Block() block_B.id = 2 block_B.parent_id = block_A.id block_B.history = '張三跟李四買三條魚' block_C = Block() block_C.id = 3 block_C.parent_id = block_B.id block_C.history = '張三給李四一百塊' block_D = Block() block_D.id = 3 block_D.parent_id = block_B.id block_D.history = '李四收到張三一百塊' block_E = Block() block_E.id = 3 block_E.parent_id = block_B.id block_E.history = '李四給張三三條魚'
從代碼上看不同區(qū)塊之間通過parent_id形成了前后連接關(guān)系,這就是區(qū)塊鏈中的“鏈”,但現(xiàn)在還有一個嚴(yán)重問題,那就是信息可以更改,假設(shè)張三想來著,他把block_E里面的history改成李四給張三兩條魚,然后找李四算賬那怎辦,或者李四想賴賬,把block_D中的history改成“李四收到張三五十塊”,然后又找張三要錢,那怎么辦。
為了確保信息不被更改,我們需要對每個區(qū)塊的內(nèi)容進(jìn)行加密或者哈希,因此上面代碼修改如下:
# This is a sample Python script. # Press ?R to execute it or replace it with your code. # Press Double ? to search everywhere for classes, files, tool windows, actions, and settings. from block import * import hashlib import json block_A = Block() block_A.id = 1 block_A.history = '張三想要三條魚' block_B = Block() block_B.id = 2 block_B.parent_id = block_A.id block_B.history = '張三跟李四買三條魚' block_B.parent_hash = hashlib.sha256(json.dumps(block_A.__dict__).encode('utf-8')).hexdigest() block_C = Block() block_C.id = 3 block_C.parent_id = block_B.id block_C.history = '張三給李四一百塊' block_C.parent_hash = hashlib.sha256(json.dumps(block_B.__dict__).encode('utf-8')).hexdigest() block_D = Block() block_D.id = 4 block_D.parent_id = block_C.id block_D.history = '李四收到張三一百塊' block_D.parent_hash = hashlib.sha256(json.dumps(block_C.__dict__).encode('utf-8')).hexdigest() block_E = Block() block_E.id = 5 block_E.parent_id = block_B.id block_E.history = '李四給張三三條魚' block_E.parent_hash = hashlib.sha256(json.dumps(block_D__dict__).encode('utf-8')).hexdigest()
有了哈希,如何任何一個區(qū)塊被修改,那么當(dāng)前區(qū)塊和后續(xù)區(qū)塊的哈希都得修改,例如李四把block_C的history改成“張三給李四五十塊”,那么我們看到李四必須要把block_C到block_E的哈希全部改了,如果這條鏈很長的話,李四改起來就非常吃力。同時為了確保信息的可靠性,
張三和李四需要把上面的區(qū)塊鏈發(fā)送給其他一百個人進(jìn)行存儲,這樣一來張三或李四想要賴賬那就更加困難,因?yàn)橛幸话賯€見證者。
區(qū)塊鏈信息記錄的特點(diǎn)是只增不刪,因此張三想要賴賬的話,他只能在上面基礎(chǔ)上再增加一個區(qū)塊,也就是block_F, 里面的history寫上了“張三收到李四兩條魚”,然后將這個區(qū)塊發(fā)給其他100個人,為了防止隨意添加區(qū)塊造成信息混亂的情況,在區(qū)塊鏈中有一個專門的角色負(fù)責(zé)將新增的區(qū)塊添加到現(xiàn)有的區(qū)塊鏈上,這個角色拿到區(qū)塊數(shù)據(jù)后,,在不考慮parent_hash字段的情況下將數(shù)據(jù)序列化,接著找到一個特定字符串,這個字符串必須滿足給定要求,那就是它與區(qū)塊序列化的數(shù)據(jù)合并后,算出來的哈希值必須以5個0開頭,我們從代碼上看看這是什么意思:
#proof-of-work block_F = Block() block_F.id = 6 block_E.parent_id = block_E.id block_E.history = '李四給張三三條魚' #注意我們這里沒有設(shè)置parent_hash字段 block_F_serialized = json.dumps(block_F.__dict__).encode('utf-8') print(block_F_serialized) for i in range(10000000): proof_of_work = str(i).encode('utf-8') result = hashlib.sha256(block_F_serialized + proof_of_work).hexdigest() if result[:5] == '00000': #哈希結(jié)果只有以5個0開頭才能添加區(qū)塊到公鏈 print(proof_of_work) print(result) break #找到特定字符串后獲取回報,所謂挖礦就是干這個事情
上面代碼運(yùn)行后所得結(jié)果為:
b'{"id": 6, "history": null, "parent_id": null, "parent_hash": null}'
b'553448'
0000034ba1dabbf794212082b47a6bcc98cb33eed86d363993270ca58e243bb9
也就是說特定字符串內(nèi)容為"553448",它能使得新區(qū)塊內(nèi)容和它結(jié)合后算出來的哈希以5個0開頭,專門負(fù)責(zé)給區(qū)塊查找這種字符串的角色就叫“礦工”,這個查找過程就叫挖礦,一旦找到這個特定字符串后他就能獲取回報,也就是加密貨幣。
現(xiàn)在我們實(shí)現(xiàn)了數(shù)據(jù)的修改很困難,同時區(qū)塊的添加也需要付出一定成本,但假設(shè)李四就是拼了老命也想把以前記錄的信息修改掉,并為此愿意付出一切代價,假設(shè)當(dāng)前區(qū)塊鏈有1000個數(shù)據(jù)塊,他想修改第一個塊記錄的信息,于是他修改了后面999個數(shù)據(jù)塊的數(shù)據(jù),但原始數(shù)據(jù)被其他人掌握著,因此他自己修改的數(shù)據(jù)就不會被采納。由于區(qū)塊鏈數(shù)據(jù)被分布存儲在不同地方,于是在某項地方數(shù)據(jù)可能會被修改,這樣就會出現(xiàn)數(shù)據(jù)不一致的情況,區(qū)塊鏈還有一個重要任務(wù)就是在這種情況下達(dá)成共識。
同時當(dāng)有新的區(qū)塊需要加入公鏈時,我們需要將新增區(qū)塊通過廣播的方式通知所有人,于是就有個問題,那就是有些人較早獲得通知,有些獲得通知較晚,更有可能你會同時收到多個消息,假設(shè)現(xiàn)在公鏈上最后一個消息編號為5,此時你同時收到了兩個消息東邊發(fā)來的消息為history:王五想跟李四買一斤蝦;西邊發(fā)來的消息為history:李六想跟張三買兩條魚,那么我們應(yīng)該將哪個消息作為編號6呢,此時的做法是先等等,如果過了一會西邊發(fā)來了5條消息,同時東邊只發(fā)來2條消息,那么就把消息少的拋棄,將消息多的經(jīng)過處理后添加到公鏈。
通過選擇數(shù)據(jù)多的添加到公鏈有個好處就是讓數(shù)據(jù)的修改變得幾乎不可能,例如李四辛辛苦苦花了半小時修改了999個區(qū)塊,然后想要廣播給其他人,但是很可能這段時間內(nèi)有10000個新區(qū)塊生成,于是他修改的999個區(qū)塊就會被丟棄掉,這樣他就無法進(jìn)行任何修改。這個過程其實(shí)涉及到非常復(fù)雜的分布式計算理論,我們無法簡單使用代碼實(shí)現(xiàn)。
區(qū)塊鏈的設(shè)計思想非常偉大,它集合了很多智慧的結(jié)晶,例如加密算法,分布式算法,心理學(xué),經(jīng)濟(jì)學(xué)等,由于它跨越領(lǐng)域太多,這也是它特別“玄學(xué)”的原因,我們后面僅從技術(shù)的角度進(jìn)行思考,看看區(qū)塊鏈采用的算法原理,同時也逐步探討如何基于區(qū)塊鏈的基礎(chǔ)上進(jìn)行應(yīng)用開發(fā)。
原文鏈接:https://blog.csdn.net/tyler_download/article/details/122648174
相關(guān)推薦
- 2022-04-18 ASP.Net?Core?MVC基礎(chǔ)系列之獲取配置信息_基礎(chǔ)應(yīng)用
- 2022-06-20 Python使用PyAudio制作錄音工具的實(shí)現(xiàn)代碼_python
- 2022-06-16 Zabbix自定義腳本監(jiān)控nginx以及微信告警的全過程_zabbix
- 2022-10-16 實(shí)例詳解Python中的numpy.abs和abs函數(shù)_python
- 2022-09-13 C++17使用std::optional表示可能存在的值_C 語言
- 2022-10-12 Nginx?403?forbidden錯誤的原因以及解決方法_nginx
- 2022-07-06 C語言中#pragma?once的作用_C 語言
- 2022-07-21 數(shù)據(jù)庫之函數(shù)的使用
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支