寫在前面
寫這篇文章的動(dòng)機(jī)屿讽,緣于一次對比特幣原理科普性質(zhì)的分享鹊奖。講的過程中發(fā)現(xiàn),想把比特幣真正講明白养篓,是非常困難的秃流。所以決定把分享的內(nèi)容記錄下來,也力求把比特幣這一新事物講清楚柳弄。對于比特幣中用到很多專業(yè)技術(shù)舶胀,我也盡量用通俗的說法來解釋概说。如果最后沒能達(dá)到目的,就權(quán)當(dāng)是自己的一次總結(jié)了吧嚣伐。
最原始的比特幣模型
從最簡單的角度看糖赔,比特幣的功能有點(diǎn)類似銀行或者支付寶這類支付機(jī)構(gòu),它為每個(gè)賬戶記錄了余額轩端,并且提供了讓大家相互轉(zhuǎn)帳的功能放典。
在沒有比特幣之前,我們的支付機(jī)構(gòu)是怎么做的呢基茵?
- 如果A想給B轉(zhuǎn)帳奋构,他會把這條消息發(fā)送給支付機(jī)構(gòu)
-
支付機(jī)構(gòu)對二人賬戶的余額進(jìn)行調(diào)整,并且作為見證人拱层,對二人間的這一交易行為提供保證弥臼。
傳統(tǒng)的轉(zhuǎn)賬方式
然而在一些場景下,我們并不想要這樣的一個(gè)“支付機(jī)構(gòu)”根灯。比如:
- 涉及到跨國的轉(zhuǎn)賬時(shí)醋火,雙方可能會因?yàn)榛ゲ恍湃味辉甘褂萌魏我粐闹Ц稒C(jī)構(gòu);
- 兩個(gè)犯罪分子要進(jìn)行一些非法買賣箱吕,通過銀行轉(zhuǎn)賬會有被攔截交易和凍結(jié)賬號的風(fēng)險(xiǎn)芥驳。
盡管這兩個(gè)例子稍嫌極端,但它們?nèi)耘f提出了一個(gè)技術(shù)上非常務(wù)實(shí)的問題:“假如不依賴任何一個(gè)中介機(jī)構(gòu)茬高,構(gòu)建在互聯(lián)網(wǎng)上的轉(zhuǎn)賬系統(tǒng)是可行的嗎兆旬?”
面對這一問題,許多先輩進(jìn)行了不懈的努力怎栽。在2009年丽猬,隨著比特幣系統(tǒng)橫空出世,這一問題總算才有了一個(gè)可行的解決方案熏瞄。
那么比特幣究竟是怎么解決這一問題的呢脚祟?概括來說,它的思路如下:
- 如果要通過網(wǎng)絡(luò)轉(zhuǎn)賬强饮,那么“公立的由桌、轉(zhuǎn)賬雙方都認(rèn)可的第三方賬本”是絕對不可避免的。
- 既然“第三方賬本”不能由某一個(gè)機(jī)構(gòu)來提供邮丰,那么就只能由廣大的人群來作為一個(gè)整體提供行您。
將“人群集體提供賬本”這一想法展開,就可以勾勒出最雛形的比特幣轉(zhuǎn)賬過程來:
- A給B轉(zhuǎn)賬時(shí)剪廉,要在人群中大喊一聲“我是A娃循,我要給B轉(zhuǎn)10塊錢”;
- 眾人在聽到A的消息時(shí)斗蒋,會在各自的賬本上記錄這筆交易捌斧,并各自對A和B的余額做相應(yīng)的調(diào)整笛质;
-
對B而言呢,他會向人群確認(rèn)捞蚂,如果大家都認(rèn)同這筆交易妇押,那么B就會認(rèn)可這次轉(zhuǎn)賬行為。
依靠人群進(jìn)行轉(zhuǎn)賬
那么這樣的一種轉(zhuǎn)賬模型意味著什么呢洞难?如果和紙幣對比一下舆吮,我們更能看出比特幣系統(tǒng)的不同來:
- 對于紙幣揭朝,所有拿在你手里的錢都屬于你自己队贱,不需要任何人證明。轉(zhuǎn)賬過程也相當(dāng)簡單:把你手里的錢給別人就行了潭袱。
- 對于銀行的數(shù)字資產(chǎn)柱嫌,所有記在你銀行賬戶的資產(chǎn)都屬于你,你有多少錢銀行說了算屯换。轉(zhuǎn)賬過程由銀行來操作编丘。
- 而對于比特幣,你有多少錢彤悔,以及你有沒有給別人轉(zhuǎn)過賬嘉抓,是由別人的賬本共同說了算的。這也就意味著晕窑,人群手上的賬本都維持一致是非常重要的抑片。
另外需要強(qiáng)調(diào)的是,上面在描述轉(zhuǎn)賬時(shí)杨赤,用的是“人群”和“大喊”這樣的方式來類比的敞斋。在真正的比特幣網(wǎng)絡(luò)中,這兩種方式都是不存在的疾牲。所謂人群植捎,其實(shí)是運(yùn)行在世界各地的計(jì)算機(jī)節(jié)點(diǎn);而所謂“人手一份的賬本”阳柔,也是記錄在計(jì)算機(jī)節(jié)點(diǎn)之上的電子文件焰枢;而“大喊”,則是對“利用互聯(lián)網(wǎng)傳播消息”的一種形象描述舌剂。在本文后面的內(nèi)容中医咨,這種比喻的形式仍舊會不時(shí)的出現(xiàn),大家讀到時(shí)架诞,一定要對應(yīng)到真正的計(jì)算機(jī)世界中去拟淮。
困難在哪里
在上面我們提到的模型中,有幾個(gè)非常致命的問題必須得正視:
- 轉(zhuǎn)賬發(fā)起方的身份認(rèn)證:當(dāng)人群收到A的付款消息時(shí)谴忧,怎么確定是A本人發(fā)出的很泊,而不是別人假冒的角虫。
- 如何維持人群中每個(gè)記賬人賬本的一致,這點(diǎn)在前面也強(qiáng)調(diào)過委造。這種一致性體現(xiàn)在兩個(gè)方面:每個(gè)人賬戶余額的一致和轉(zhuǎn)賬行為的一致戳鹅。
對于保持一致的問題,重要性是不言而喻的昏兆。但初看一下枫虏,似乎也沒有那么難:“A給B轉(zhuǎn)10塊,大家聽到A的消息后爬虱,一起修改賬本就行了嘛隶债。”
但事實(shí)卻是跑筝,這一問題的復(fù)雜程度死讹,遠(yuǎn)非這句輕描淡寫的“一起修改賬本”可以概括。根本原因就在于曲梗,消息廣播和記錄都是發(fā)生在互聯(lián)網(wǎng)世界的計(jì)算機(jī)節(jié)點(diǎn)上的赞警。例如:
- 可能只有部分節(jié)點(diǎn)收到了A的廣播,其他節(jié)點(diǎn)因?yàn)榫W(wǎng)絡(luò)或者自身原因錯(cuò)失了這條信息
- 如果A賬上只有10塊錢虏两,他向一部分節(jié)點(diǎn)聲稱給B轉(zhuǎn)10塊愧旦,再向另一部分聲稱給C轉(zhuǎn)10塊。大家在記賬時(shí)怎么保證只有一筆成功定罢?
- 如果有一部分節(jié)點(diǎn)故意不記賬怎么辦笤虫,篡改交易記錄又怎么辦?
賬本“一致性”的問題引颈,上面我也只大致給了一部分場景耕皮。在真正實(shí)現(xiàn)和部署這樣的一個(gè)計(jì)算機(jī)系統(tǒng)時(shí),遇到的問題和挑戰(zhàn)只會更多蝙场。概括來說的話凌停,分布在世界各地的計(jì)算機(jī)節(jié)點(diǎn)對這樣一個(gè)“賬本”的一致性問題一般會分成兩類:
- 假設(shè)所有的節(jié)點(diǎn)都是誠信善良的。在這樣的前提下售滤,設(shè)計(jì)系統(tǒng)一般考慮的問題就是消息傳輸時(shí)的丟失罚拟、亂序,以及某個(gè)節(jié)點(diǎn)的停止服務(wù)(停電完箩、關(guān)機(jī)赐俗、網(wǎng)絡(luò)欠費(fèi)、網(wǎng)線壞掉)等弊知。
- 假設(shè)有一些節(jié)點(diǎn)會從中作梗阻逮。這里面就包括對消息的篡改、無視秩彤、偽造叔扼、以訛傳訛等等事哭。在業(yè)內(nèi),大家一般用“拜占庭錯(cuò)誤”這一行話來指代這類問題瓜富。相應(yīng)的鳍咱,能容忍這類問題的系統(tǒng),也被叫做“拜占庭容錯(cuò)”的系統(tǒng)与柑。
此外谤辜,把“擔(dān)保交給人群”的比特幣系統(tǒng)還會有第三個(gè)問題:隱私性。因?yàn)槿耸忠环葙~本价捧,所以各個(gè)賬戶下余額多少自然是盡人皆知了丑念。雖然和賬戶安全的問題比起來,這似乎并不算個(gè)事兒干旧∏郏可真正開了戶后妹蔽,我相信有錢人還是更喜歡低調(diào)做人的:-)
總的來看椎眯,對于比特幣的模型,會有三類問題擺在系統(tǒng)設(shè)計(jì)者的面前:
- 身份認(rèn)證
- 拜占庭容錯(cuò)的一致性(在其他一些資料中胳岂,會把這一問題叫做“共識問題”编整,相應(yīng)的解決方案叫“共識機(jī)制”);以及在這種情況下乳丰,收發(fā)雙方如何確認(rèn)交易已完成掌测。
- 隱私性
身份認(rèn)證
上面的幾個(gè)問題中,身份認(rèn)證是最容易解決的产园。就像我們平常用簽名字跡來辨識人一樣汞斧;在比特幣系統(tǒng)中,我們通過“數(shù)字簽名”來確認(rèn)消息發(fā)起方的真?zhèn)问惭唷:妥舟E所不同的是粘勒,“數(shù)字簽名”更可靠,更難以被偽造屎即。
如果想真正弄明白數(shù)字簽名的原理庙睡,需要涉及到一些數(shù)論和抽象代數(shù)的知識。作為一個(gè)科普性質(zhì)的文章技俐,我覺得還是很有義務(wù)把這些艱深的知識扔到一邊的(雖然真正的原因乘陪,是我對這些知識也一知半解)。但既然科普的牛皮已經(jīng)吹出去了雕擂,不管怎樣還是得像模像樣的找個(gè)例子來解釋下的啡邑。
在我的例子里,我們需要首先把自己的數(shù)學(xué)水平下拉到三年級左右的層次井赌。在這樣的水平下谤逼,我們能讀募寨、寫、理解很大的數(shù)字森缠,也會做位數(shù)比較高的乘法拔鹰,而對于最簡單的除法,我們都沒有任何概念贵涵。
那么列肢,在這樣的一個(gè)前提下,面對這樣的計(jì)算任務(wù):
31 × 32 = ?
我們能很快計(jì)算出結(jié)果992宾茂;而對于這樣的計(jì)算任務(wù):
? × 32 = 992
我們就近乎無能為力了瓷马。
如果每個(gè)人都只有三年級的數(shù)學(xué)水平,那么A就可以充分利用這一點(diǎn)進(jìn)行轉(zhuǎn)帳了:
- 首先跨晴,在轉(zhuǎn)賬前他會生成這樣的一對算式:31 × 32 = 992
- 然后欧聘,他會通過各種渠道把(32, 992)這對數(shù)字告訴大家,而把31牢牢記在自己的心里端盆。眾人皆知的(32, 992)叫做公鑰怀骤,而自己守口如瓶的31叫私鑰。
- 假如他要給別人轉(zhuǎn)賬15塊焕妙,他會把轉(zhuǎn)賬金額15廣播出去蒋伦。與之相對應(yīng),他還會把15和私鑰31的乘積465也一起廣播出去焚鹊。而465痕届,就叫A對轉(zhuǎn)賬金額15的數(shù)字簽名。所以最后的發(fā)出的消息就是:轉(zhuǎn)帳者A末患,金額15研叫,簽名465
- 為什么把465叫做簽名呢?首先璧针,465是A拿私鑰31計(jì)算出來的嚷炉。而別人拿到(金額15, 簽名465)這一消息后,可以利用A的公鑰(32, 992)進(jìn)行校驗(yàn):大家會計(jì)算15 × 992和32 × 465的結(jié)果是否相同陈莽。如果相同渤昌,就說明消息是A發(fā)的;否則走搁,消息是偽造的独柑。
- 換句話說,任何的轉(zhuǎn)賬消息都是“轉(zhuǎn)賬人私植,金額忌栅,簽名”這種格式,收到交易消息的記賬人,會依據(jù)轉(zhuǎn)賬人的公鑰對簽名按照公開的計(jì)算規(guī)則進(jìn)行驗(yàn)證索绪,如果驗(yàn)證通過湖员,才認(rèn)可這筆交易。
形式化一下上面的過程就是:
- 轉(zhuǎn)賬者生成一對數(shù)字(a, b), 并計(jì)算:a × b = sum
- 轉(zhuǎn)賬者牢記私鑰a, 并公開公鑰(b, sum)
- 交易時(shí)瑞驱,A廣播本次交易金額d和簽名sig娘摔,sig由a和d相乘所得。
- 分散在世界各地的記賬者唤反,每收到轉(zhuǎn)賬消息(轉(zhuǎn)賬人A, 額度d, 簽名sig)時(shí)凳寺,會拿A的公鑰(b, sum)校驗(yàn)消息。如果和sig × b = d × sum彤侍,則確認(rèn)消息是A本人發(fā)的肠缨;反之則認(rèn)定這是一條偽造的消息。
這個(gè)驗(yàn)證過程為什么可行盏阶,也可以簡單總結(jié)下了:
- A雖然沒有透露自己的密碼a晒奕,但通過(b, sum),暗示出了自己的身份是能乘以b等于sum的那個(gè)人名斟。但別人不會計(jì)算除法脑慧,所以哪怕看著b和sum, 也不知道a到底是多少
- 在收到d和簽名乘積sig后,記賬人就可以想:既然發(fā)消息的這個(gè)人說自己是A蒸眠,那么乘積sig一定是用他的a和余額d相乘算出來的漾橙;我手頭已經(jīng)有(b, sum)了杆融,簡單驗(yàn)證下sig/d 和sum/b是不是一樣就行了嘛楞卡。除法我是不會算的,那么只好變通下脾歇,檢驗(yàn)sig × b = sum × d也可以蒋腮。
- 一個(gè)偽造者想要仿冒A的身份,只能嘗試把a找出來藕各。由于不會計(jì)算除法池摧,想尋找a也只能從1開始挨個(gè)試了,直到試出一個(gè)數(shù)字乘以b等于sum為止激况。如果我們把a(bǔ)從整數(shù)擴(kuò)充到小數(shù)作彤,位數(shù)也調(diào)到非常高。挨個(gè)試的成本也會陡增而甚至變得不可能了乌逐。
好竭讳,例子舉完了。雖然和真正的數(shù)字簽名謬以千里浙踢,但講解其中的概念也足夠了绢慢。概括來說,在數(shù)字簽名中涉及的技術(shù)理念有如下這些:
- 利用一種計(jì)算體系中正向和逆向計(jì)算的難度不同
- 對一些計(jì)算過程做部分公開洛波,公開的部分叫公鑰胰舆,保持私密的部分叫私鑰骚露。消息發(fā)送者本人用私鑰對消息進(jìn)行簽名。任何人都可以用公鑰對消息進(jìn)行驗(yàn)證缚窿。
- 偽造者獲取私鑰后才可以偽造消息棘幸。如果不考慮其他坑蒙拐騙的手段,獲取私鑰唯一的好方法就是挨個(gè)對私鑰進(jìn)行猜測倦零。而這一過程所耗費(fèi)的時(shí)間非彻换埃恐怖。就現(xiàn)在人類的知識體系和計(jì)算力而言光绕,幾乎可以認(rèn)為是不可能的女嘲。
把數(shù)字簽名的技術(shù)應(yīng)用到比特幣系統(tǒng)中后,公鑰就對應(yīng)著我們的的賬戶地址诞帐,對所有人是公開可見的欣尼;而私鑰則是我們的賬戶密碼,只有我們自己知道停蕉。當(dāng)給別人轉(zhuǎn)賬時(shí)愕鼓,我們會拿密碼來簽名我們的轉(zhuǎn)賬消息,并且指定別人的賬戶地址慧起。而別人想再次把這筆收到的款項(xiàng)轉(zhuǎn)給別人時(shí)菇晃,也只有提供的出對應(yīng)的簽名才行。
所以最后總結(jié)一下蚓挤,一筆轉(zhuǎn)賬交易的幾個(gè)重要部分如下:
- 付款方的公鑰磺送,標(biāo)記付款賬戶
- 收款人的公鑰,標(biāo)記收款賬戶
- 交易金額
- 付款人用私鑰對這筆交易的簽名
雖然數(shù)字簽名這一技術(shù)要比比特幣本身古老得多灿意,但把這一技術(shù)應(yīng)用到這種非中心式的賬本體系中時(shí)估灿,我們?nèi)阅芸吹剿豌y行有多么的不同。在有銀行的世界里缤剧,我們是完全相信銀行的馅袁。去銀行開通賬號和設(shè)置密碼后,我們個(gè)人和銀行之間就分享了一個(gè)小秘密荒辕;在每次交易前汗销,銀行也通過驗(yàn)證這個(gè)共同的秘密來認(rèn)證我們的身份。這頗有一點(diǎn)各種諜戰(zhàn)劇中接頭暗號的味道抵窒,整個(gè)過程所利用的弛针,是交易參與者和攻擊者之間信息上的不對稱。而數(shù)字簽名的交易過程則完全不同估脆。除了交易發(fā)起者之外钦奋,身份驗(yàn)證方和攻擊者之間擁有的信息是完全相同的。整個(gè)過程利用的,是簽名交易和認(rèn)證交易在計(jì)算上的不對稱付材。
這種形式上的轉(zhuǎn)變朦拖,使得我們不用再信任其他的第三方機(jī)構(gòu),似乎非常美好厌衔。但壞處也顯而易見:一旦私鑰丟失了璧帝,想拿著自己的身份證去重置密碼就是不可能的了。因?yàn)樵谡麄€(gè)交易環(huán)節(jié)中富寿,除了私鑰產(chǎn)生的簽名睬隶,我們沒有任何的手段可以證明“我就是我”;那個(gè)和私鑰所匹配的公鑰页徐,既不是姓名苏潜,也不是身份證號,也不是住址变勇,而是一串恰好和別人不一樣的數(shù)字而已恤左。更進(jìn)一步看,一旦私鑰泄露了出去搀绣,我們也不可能指望銀行和公安機(jī)關(guān)來幫忙凍結(jié)交易以及追回?fù)p失了飞袋。
說到這里,你也許會認(rèn)為比特幣這種技術(shù)實(shí)在太過“冷冰冰”链患。但從另一個(gè)角度而言巧鸭,這完全是“求仁得仁”:放棄了對第三方機(jī)構(gòu)的信賴,也就得放棄這種信賴可能帶來的好處麻捻。