比特幣腳本實現邏輯
1. 4. 比特幣的密鑰、地址和錢包 - 精通比特幣筆記
比特幣的所有權是通過密鑰、比特幣地址和數字簽名共同確定的。密鑰不存在於比特幣網路中,而是用戶自己保存,或者利用管理私鑰的軟體-錢包來生成及管理。
比特幣的交易必須有有效簽名才會被存儲在區塊中,因此擁有密鑰就擁有對應賬戶中的比特幣。密鑰都是成對出現的,由一個公鑰和一個私鑰組成。公鑰相當於銀行賬號,私鑰就相當於銀行卡密碼。通常情況下密鑰由錢包軟體管理,用戶不直接使用密鑰。
比特幣地址通常是由公鑰計算得來,也可以由比特幣腳本得來。
比特幣私鑰通常是數字,由比特幣系統隨機( 因為演算法的可靠性與隨機性正相關,所以隨機性必須是真隨機,不是偽隨機,因此比特幣系統可以作為隨機源來使用 )生成,然後將私鑰作為輸入,使用橢圓曲線演算法這個單向加密函數生成對應的公鑰,再將公鑰作為輸入,使用單向加密哈希函數生成地址。例如,通過公鑰K得到地址A的計算方式為:
其中SHA256和PIPEMD160被稱為雙哈希或者HASH160,Base58Check是帶有驗證功能的Base58編碼,驗證方式為先計算原始數據(編碼前)的驗證碼,再比較編碼後數據的驗證碼,相同則地址有效,否則無效。而在使用Base58Check編碼前,需要對數據做處理。
處理方式為: 版本前綴 + 雙哈希後的數據 + 校驗碼
其中版本前綴是自定義的,如比特幣私鑰的前綴是0x80,校驗碼是把版本前綴和雙哈希後的數據拼接起來,進行兩次SHA256計算,取前4位元組。得到處理的數據後,再進行Base58編碼,得到最終的結果。
下圖是Base58Check版本前綴和Base58編碼後的結果
密鑰可以採用不同的編碼格式,得到的編碼後結果雖然不同,但密鑰本身沒有任何變化,採用哪種編碼格式,就看情況而論了,最終目的都是方便人們准確無誤的使用和識別密鑰。
下圖是相同私鑰採用不同編碼方式的結果:
公鑰也有很多種格式,不過最重要的是公鑰被分為壓縮格式和非壓縮格式,帶04前綴的公鑰為非壓縮格式的公鑰,而03,02開頭的標識壓縮格式的公鑰。
前面說過,公鑰是橢圓曲線上的一個點,由一對坐標(x, y)表示,再加上前綴,公鑰可以表示為:前綴 x y。
比如一個公鑰的坐標為:
以非壓縮格式為例,公鑰為(略長):
壓縮格式的公鑰可以節省一定的存儲,對於每天成千上萬的比特幣交易記錄來說,這一點點的節省能起到很大效果。
因為橢圓曲線實際上是一個方程(y2 mod p = (x3 + 7)mod P, y2是y的平方,x3是x的立方),而公鑰是橢圓曲線上的一個點,那麼公鑰即為方程的一個解,如果公鑰中只保留x,那麼可以通過解方程得到y,而壓縮公鑰格式有兩個前綴是因為對y2開方,會得到正負兩個解,在素數p階的有限域上使用二進制算術計算橢圓曲線的時候,y坐標或奇或偶,所以用02表示y為奇數,03表示y為偶數。
所以壓縮格式的公鑰可以表示為:前綴x
以上述公鑰的坐標為准,y為奇數為例,公鑰K為:
不知道大家發現沒有,這種壓縮方式存在一個問題,即一個私鑰可以得出兩個公鑰,壓縮和非壓縮公鑰,而這兩個公鑰都對應同一個私鑰,都合法,但生成的比特幣地址卻不相同,這就涉及到錢包軟體的實現方式,是使用壓縮公鑰還是非壓縮公鑰,或者二者皆用,這個問題後面來介紹。
比特幣錢包最主要的功能就是替用戶保管比特幣私鑰,比特幣錢包有很多種,比如非確定性(隨機)錢包,確定性(種子)錢包。所謂的非確定性是指錢包運行時會生成足夠的私鑰(比如100個私鑰),每個私鑰僅會使用一次,這樣私鑰管理就很麻煩。確定性錢包擁有一個公共種子,單向離散方程使用種子生成私鑰,種子足夠回收所有私鑰,所以在錢包創建時,簡單備份下,就可以在錢包之間轉移輸入。
這里要特別介紹下助記碼詞彙。助記碼詞彙是英文單詞序列,在BIP0039中提出。這些序列對應著錢包中的種子,種子可以生成隨機數,隨機數生成私鑰,私鑰生成公鑰,便有了你需要的一切。所以單詞的順序就是錢包的備份,通過助記碼詞彙能重建錢包,這比記下一串隨機數要強的多。
BIP0039定義助記碼和種子的創建過程如下:
另外一種重要的錢包叫做HD錢包。HD錢包提供了隨機(不確定性) 鑰匙有兩個主要的優勢。
第一,樹狀結構可以被用來表達額外的組織含義。比如當一個特定分支的子密鑰被用來接收交易收入並且有另一個分支的子密鑰用來負責支付花費。不同分支的密鑰都可以被用在企業環境中,這就可以支配不同的分支部門,子公司,具體功能以及會計類別。
第二,它可以允許讓使用者去建立一個公共密鑰的序列而不需要訪問相對應的私鑰。這可允許HD錢包在不安全的伺服器中使用或者在每筆交易中發行不同的公共鑰匙。公共鑰匙不需要被預先載入或者提前衍生,但是在伺服器中不具有可用來支付的私鑰。
BIP0038提出了一個通用標准,使用一個口令加密私鑰並使用Base58Check對加密的私鑰進行編碼,這樣加密的私鑰就可以安全地保存在備份介質里,安全地在錢包間傳輸,保持密鑰在任何可能被暴露情況下的安全性。這個加密標准使用了AES,這個標准由NIST建立,並廣泛應用於商業和軍事應用的數據加密。
BIP0038加密方案是: 輸入一個比特幣私鑰,通常使用WIF編碼過,base58chek字元串的前綴「5」。此外BIP0038加密方案需要一個長密碼作為口令,通常由多個單詞或一段復雜的數字字母字元串組成。BIP0038加密方案的結果是一個由base58check編碼過的加密私鑰,前綴為6P。如果你看到一個6P開頭的的密鑰,這就意味著該密鑰是被加密過,並需個口令來轉換(解碼) 該密鑰回到可被用在任何錢包WIF格式的私鑰(前綴為5)。許多錢包APP現在能夠識別BIP0038加密過的私鑰,會要求用戶提供口令解碼並導入密鑰。
最通常使用BIP0038加密的密鑰用例是紙錢包一一張紙張上備份私鑰。只要用戶選擇了強口令,使用BIP0038加密的私鑰的紙錢包就無比的安全,這也是一種很棒的比特幣離線存儲方式(也被稱作「冷存儲」)。
P2SH函數最常見的實現時用於多重簽名地址腳本。顧名思義,底層腳本需要多個簽名來證明所有權,然後才能消費資金。這類似在銀行開設一個聯合賬戶。
你可以通過計算,生成特殊的比特幣地址,例如我需要一個Hello開頭的地址,你可以通過腳本來生成這樣一個地址。但是每增加一個字元,計算量會增加58倍,超過7個字元,需要專門的硬體或者礦機來生成,如果是8~10個字元,那麼計算量將無法想像。
2. 以太坊是什麼丨以太坊開發入門指南
以太坊是什麼丨以太坊開發入門指南
很多同學已經躍躍欲試投入到區塊鏈開發隊伍當中來,可是又感覺無從下手,本文將基於以太坊平台,以通俗的方式介紹以太坊開發中涉及的各晦澀的概念,輕松帶大家入門。
以太坊是什麼
以太坊(Ethereum)是一個建立在區塊鏈技術之上, 去中心化應用平台。它允許任何人在平台中建立和使用通過區塊鏈技術運行的去中心化應用。
對這句話不理解的同學,姑且可以理解為以太坊是區塊鏈里的Android,它是一個開發平台,讓我們就可以像基於Android Framework一樣基於區塊鏈技術寫應用。
在沒有以太坊之前,寫區塊鏈應用是這樣的:拷貝一份比特幣代碼,然後去改底層代碼如加密演算法,共識機制,網路協議等等(很多山寨幣就是這樣,改改就出來一個新幣)。
以太坊平台對底層區塊鏈技術進行了封裝,讓區塊鏈應用開發者可以直接基於以太坊平台進行開發,開發者只要專注於應用本身的開發,從而大大降低了難度。
目前圍繞以太坊已經形成了一個較為完善的開發生態圈:有社區的支持,有很多開發框架、工具可以選擇。
智能合約
什麼是智能合約
以太坊上的程序稱之為智能合約, 它是代碼和數據(狀態)的集合。
智能合約可以理解為在區塊鏈上可以自動執行的(由事件驅動的)、以代碼形式編寫的合同(特殊的交易)。
在比特幣腳本中,我們講到過比特幣的交易是可以編程的,但是比特幣腳本有很多的限制,能夠編寫的程序也有限,而以太坊則更加完備(在計算機科學術語中,稱它為是「圖靈完備的」),讓我們就像使用任何高級語言一樣來編寫幾乎可以做任何事情的程序(智能合約)。
智能合約非常適合對信任、安全和持久性要求較高的應用場景,比如:數字貨幣、數字資產、投票、保險、金融應用、預測市場、產權所有權管理、物聯網、點對點交易等等。
目前除數字貨幣之外,真正落地的應用還不多(就像移動平台剛開始出來一樣),相信1到3年內,各種殺手級會慢慢出現。
編程語言:Solidity
智能合約的默認的編程語言是Solidity,文件擴展名以.sol結尾。
Solidity是和JavaScript相似的語言,用它來開發合約並編譯成以太坊虛擬機位元組代碼。
還有長像Python的智能合約開發語言:Serpent,不過建議大家還是使用Solidity。
Browser-Solidity是一個瀏覽器的Solidity IDE, 大家可以點進去看看,以後我們更多文章介紹Solidity這個語言。
運行環境:EVM
EVM(Ethereum Virtual Machine)以太坊虛擬機是以太坊中智能合約的運行環境。
Solidity之於EVM,就像之於跟JVM的關系一樣,這樣大家就容易理解了。
以太坊虛擬機是一個隔離的環境,在EVM內部運行的代碼不能跟外部有聯系。
而EVM運行在以太坊節點上,當我們把合約部署到以太坊網路上之後,合約就可以在以太坊網路中運行了。
合約的編譯
以太坊虛擬機上運行的是合約的位元組碼形式,需要我們在部署之前先對合約進行編譯,可以選擇Browser-Solidity Web IDE或solc編譯器。
合約的部署
在以太坊上開發應用時,常常要使用到以太坊客戶端(錢包)。平時我們在開發中,一般不接觸到客戶端或錢包的概念,它是什麼呢?
以太坊客戶端(錢包)
以太坊客戶端,其實我們可以把它理解為一個開發者工具,它提供賬戶管理、挖礦、轉賬、智能合約的部署和執行等等功能。
EVM是由以太坊客戶端提供的。
Geth是典型的開發以太坊時使用的客戶端,基於Go語言開發。 Geth提供了一個互動式命令控制台,通過命令控制台中包含了以太坊的各種功能(API)。Geth的使用我們之後會有文章介紹,這里大家先有個概念。
Geth控制台和Chrome瀏覽器開發者工具里的面的控制台是類似,不過是跑在終端里。
相對於Geth,Mist則是圖形化操作界面的以太坊客戶端。
如何部署
智能合約的部署是指把合約位元組碼發布到區塊鏈上,並使用一個特定的地址來標示這個合約,這個地址稱為合約賬戶。
以太坊中有兩類賬戶:
· 外部賬戶
該類賬戶被私鑰控制(由人控制),沒有關聯任何代碼。
· 合約賬戶
該類賬戶被它們的合約代碼控制且有代碼與之關聯。
和比特幣使用UTXO的設計不一樣,以太坊使用更為簡單的賬戶概念。
兩類賬戶對於EVM來說是一樣的。
外部賬戶與合約賬戶的區別和關系是這樣的:一個外部賬戶可以通過創建和用自己的私鑰來對交易進行簽名,來發送消息給另一個外部賬戶或合約賬戶。
在兩個外部賬戶之間傳送消息是價值轉移的過程。但從外部賬戶到合約賬戶的消息會激活合約賬戶的代碼,允許它執行各種動作(比如轉移代幣,寫入內部存儲,挖出一個新代幣,執行一些運算,創建一個新的合約等等)。
只有當外部賬戶發出指令時,合同賬戶才會執行相應的操作。
合約部署就是將編譯好的合約位元組碼通過外部賬號發送交易的形式部署到以太坊區塊鏈上(由實際礦工出塊之後,才真正部署成功)。
運行
合約部署之後,當需要調用這個智能合約的方法時只需要向這個合約賬戶發送消息(交易)即可,通過消息觸發後智能合約的代碼就會在EVM中執行了。
Gas
和雲計算相似,佔用區塊鏈的資源(不管是簡單的轉賬交易,還是合約的部署和執行)同樣需要付出相應的費用(天下沒有免費的午餐對不對!)。
以太坊上用Gas機制來計費,Gas也可以認為是一個工作量單位,智能合約越復雜(計算步驟的數量和類型,佔用的內存等),用來完成運行就需要越多Gas。
任何特定的合約所需的運行合約的Gas數量是固定的,由合約的復雜度決定。
而Gas價格由運行合約的人在提交運行合約請求的時候規定,以確定他願意為這次交易願意付出的費用:Gas價格(用以太幣計價) * Gas數量。
Gas的目的是限制執行交易所需的工作量,同時為執行支付費用。當EVM執行交易時,Gas將按照特定規則被逐漸消耗,無論執行到什麼位置,一旦Gas被耗盡,將會觸發異常。當前調用幀所做的所有狀態修改都將被回滾, 如果執行結束還有Gas剩餘,這些Gas將被返還給發送賬戶。
如果沒有這個限制,就會有人寫出無法停止(如:死循環)的合約來阻塞網路。
因此實際上(把前面的內容串起來),我們需要一個有以太幣余額的外部賬戶,來發起一個交易(普通交易或部署、運行一個合約),運行時,礦工收取相應的工作量費用。
以太坊網路
有些著急的同學要問了,沒有以太幣,要怎麼進行智能合約的開發?可以選擇以下方式:
選擇以太坊官網測試網路Testnet
測試網路中,我們可以很容易獲得免費的以太幣,缺點是需要發很長時間初始化節點。
使用私有鏈
創建自己的以太幣私有測試網路,通常也稱為私有鏈,我們可以用它來作為一個測試環境來開發、調試和測試智能合約。
通過上面提到的Geth很容易就可以創建一個屬於自己的測試網路,以太幣想挖多少挖多少,也免去了同步正式網路的整個區塊鏈數據。
使用開發者網路(模式)
相比私有鏈,開發者網路(模式)下,會自動分配一個有大量余額的開發者賬戶給我們使用。
使用模擬環境
另一個創建測試網路的方法是使用testrpc,testrpc是在本地使用內存模擬的一個以太坊環境,對於開發調試來說,更方便快捷。而且testrpc可以在啟動時幫我們創建10個存有資金的測試賬戶。
進行合約開發時,可以在testrpc中測試通過後,再部署到Geth節點中去。
更新:testrpc 現在已經並入到Truffle 開發框架中,現在名字是Ganache CLI。
Dapp:去中心化的應用程序
以太坊社區把基於智能合約的應用稱為去中心化的應用程序(DecentralizedApp)。如果我們把區塊鏈理解為一個不可篡改的資料庫,智能合約理解為和資料庫打交道的程序,那就很容易理解Dapp了,一個Dapp不單單有智能合約,比如還需要有一個友好的用戶界面和其他的東西。
Truffle
Truffle是Dapp開發框架,他可以幫我們處理掉大量無關緊要的小事情,讓我們可以迅速開始寫代碼-編譯-部署-測試-打包DApp這個流程。
總結
我們現在來總結一下,以太坊是平台,它讓我們方便的使用區塊鏈技術開發去中心化的應用,在這個應用中,使用Solidity來編寫和區塊鏈交互的智能合約,合約編寫好後之後,我們需要用以太坊客戶端用一個有餘額的賬戶去部署及運行合約(使用Truffle框架可以更好的幫助我們做這些事情了)。為了開發方便,我們可以用Geth或testrpc來搭建一個測試網路。
註:本文中為了方便大家理解,對一些概念做了類比,有些嚴格來不是准確,不過我也認為對於初學者,也沒有必要把每一個概念掌握的很細致和准確,學習是一個逐步深入的過程,很多時候我們會發現,過一段後,我們會對同一個東西有不一樣的理解。
3. 什麼是腳本挖礦
比特幣的核心原理是「區塊鏈」,每一個區塊對應一個帳單,將所有的區塊鏈接起來就是區塊鏈,任何交易信息和轉賬記錄都記錄在區塊鏈中。要注意的是區塊鏈存在於整個互聯網中,所以任何比特幣持有者都不擔心比特幣遭受損失。
每隔一個時間點,比特幣系統會在系統節點上生成一個隨機代碼,互聯網中的所有計算機都可以去尋找此代碼,誰找到此代碼,就會產生一個區塊,隨即得到一個比特幣,這個過程就是人們常說的挖礦。
比特幣挖礦。
就是用於賺取比特幣的電腦,這類電腦一般有專業的挖礦晶元,多採用燒顯卡的方式工作,耗電量較大。用戶用個人計算機下載軟體然後運行特定演算法,與遠方伺服器通訊後可得到相應比特幣,是獲取比特幣的方式之一。
據最新的外媒報道,隨著數字貨幣呈現不斷上漲的趨勢,為了獲取更多的數字貨幣。黑客入侵網站植入挖礦腳本後利用用戶的CPU挖掘數字貨幣的做法越來越流行。其相關數據統計,目前已有2,496家運行過時軟體的網站遭到黑客植入惡意代碼,並利用訪問者CPU挖掘。非法植入惡意挖礦腳本已成為了黑產的常見途徑。
4. 比特幣瘋狂上漲的邏輯是什麼
比特幣上漲的主要原因是法定貨幣零利息,資本無法保值,貨幣被政府操縱,從而導致機構把資產投入到去中心的加密貨幣中,當然也包括很多投機行為。
1. 稀缺的數量 。比特幣數量有限。現在已經有足夠多的人認可比特幣是一種資產,也就是占據了用戶心智,他實質上已經就是一種貨幣。物以稀為貴,比特幣有限,紙幣無限增多,所以存在上漲的必然動力。
2. 投機的存在 。比特幣也有其交易所。我們都知道,活躍的交易,一定離不開投機。就像我們的大A股,仔細想想有多少沖進去賺快錢的?有多少希望暴富的?有多少實際上淪為了韭菜的?這都是合法的交易平台,都充滿了投機!沒有投機的市場是缺乏生機的。
3. 猛烈的投機 。證券市場是有證監會作為專門的監管機構的,除此之外還有各種法律、協會保駕護航。數字貨幣是什麼情況?跨國家交易!絕大多數政府拒絕承認數字貨幣的合法性!這就意味著,能賺到多少錢,就看你自己的本事。法外之地,更是八仙過海,各顯神通!加上平台提供各種合約等杠桿工具,猛烈的投機行為,讓賺錢和虧錢都跟鬧著玩似的!
4. 現實的殘酷 。其實不少人在現實生活中已經極為艱難。數字貨幣提供了一個以小博大甚至輕松改變命運的機會,湧入了各色搏命下注的人。相信關注幣圈的人也知道有人一夜損失上億的。
5. 瘋狂的人,造就了瘋狂上漲的比特幣行情 。即便瘋狂上漲,還是有很多人虧得褲子都沒了。人還是要賺自己認知范圍以內的錢,認知之外的,可以買極少的玩一玩,比如買2元錢彩票。丟了無所謂,賺了也平常心看待,要知道自己的不懂。不懂的,不能沾身。
都是金融大鱷的肉
兜超發貨幣的底!
各國政府按捺不住印鈔的沖動,導致法幣不斷貶值是比特幣上漲的主要原因。[酷拽]
5. 你應該知道的區塊鏈運作7個核心技術嗎
區塊鏈運作的7個核心技術,你知道幾個?
1.區塊鏈的鏈接
顧名思義,區塊鏈即由一個個區塊組成的鏈。每個區塊分為區塊頭和區塊體(含交易數據)兩個部分。區塊頭包括用來實現區塊鏈接的前一區塊的哈希(PrevHash)值(又稱散列值)和用於計算挖礦難度的隨機數(nonce)。前一區塊的哈希值實際是上一個區塊頭部的哈希值,而計算隨機數規則決定了哪個礦工可以獲得記錄區塊的權力。
2.共識機制
區塊鏈是伴隨比特幣誕生的,是比特幣的基礎技術架構。可以將區塊鏈理解為一個基於互聯網的去中心化記賬系統。類似比特幣這樣的去中心化數字貨幣系統,要求在沒有中心節點的情況下保證各個誠實節點記賬的一致性,就需要區塊鏈來完成。所以區塊鏈技術的核心是在沒有中心控制的情況下,在互相沒有信任基礎的個體之間就交易的合法性等達成共識的共識機制。
區塊鏈的共識機制目前主要有4類:PoW、PoS、DPoS、分布式一致性演算法。
3.解鎖腳本
腳本是區塊鏈上實現自動驗證、自動執行合約的重要技術。每一筆交易的每一項輸出嚴格意義上並不是指向一個地址,而是指向一個腳本。腳本類似一套規則,它約束著接收方怎樣才能花掉這個輸出上鎖定的資產。
交易的合法性驗證也依賴於腳本。目前它依賴於兩類腳本:鎖定腳本與解鎖腳本。鎖定腳本是在輸出交易上加上的條件,通過一段腳本語言來實現,位於交易的輸出。解鎖腳本與鎖定腳本相對應,只有滿足鎖定腳本要求的條件,才能花掉這個腳本上對應的資產,位於交易的輸入。通過腳本語言可以表達很多靈活的條早譽襪件。解釋腳本是通過類似我們編程領域里的「虛擬機」,它分布式運行在區塊鏈網路里的每一個節點。
4.交易規則
區塊鏈的交易就是構成區塊的基本單位,也是區塊鏈負責記錄的實際有效內容。一個區塊鏈交易可以是一次轉賬,也可以是智能合約的部署等其他事務。
就比特幣而言,交易即指一次支付轉賬。其交易規則如下:
1)交易的輸入和輸出不能為空。
2)對交易的每個輸入,如果其對應的UTXO輸出能在當前交易池中找到,則拒絕該交易。因為當前交
易池是未被記錄在區塊鏈中的交易,而交易的每個輸入,應該來自確認的UTXO。如果在當前交易池中找到,那就是雙花交易。
3)交易中的每個輸入,其對應的輸出必須是UTXO。
4)每個輸入的解鎖腳本(unlocking script)必須和相應輸出的鎖定腳本(locking script)共同驗證交易的合規性。
5.交易優先順序
區塊鏈交易的優先順序由區塊鏈協議規則決定。對於比特幣而言,交易被區塊包含的優先次序由交易廣播到網路上的時間和交易額的大小決定。隨著交易廣播到網路上的時間的增長,交易的鏈齡增加,交易的優先順序就被提高,最終會被區塊包含。對於以太坊而言,交易的優先順序還與交易的發布者願意支付的交易費用有關,發布者願意支付的交易費用越高,交易被包含進區塊的優先順序就越高。
6.Merkle證明
Merkle證明的原始應用是比特幣系統(Bitcoin),它是由中本聰(Satoshi Nakamoto)在2009年描述並且創造的。比特幣區塊鏈使用了Merkle證明,為的是將交易存儲在每一個區塊中。使得交易不能被篡改,同時也容易驗證交易是否包含在一個特定區塊中。
7.RLP
RLP(Recursive Length Prefix,遞歸長度前綴編碼)是Ethereum中對象序列化的一個主要編碼方式,其目的是對任意嵌套的二進制虛消數據的序列進行編碼。陸激
6. 詳解比特幣挖礦原理
可以將區塊鏈看作一本記錄所有交易的公開總帳簿(列表),比特幣網路中的每個參與者都把它看作一本所有權的權威記錄。
比特幣沒有中心機構,幾乎所有的完整節點都有一份公共總帳的備份,這份總帳可以被視為認證過的記錄。
至今為止,在主幹區塊鏈上,沒有發生一起成功的攻擊,一次都沒有。
通過創造出新區塊,比特幣以一個確定的但不斷減慢的速率被鑄造出來。大約每十分鍾產生一個新區塊,每一個新區塊都伴隨著一定數量從無到有的全新比特幣。每開采210,000個塊,大約耗時4年,貨幣發行速率降低50%。
在2016年的某個時刻,在第420,000個區塊被「挖掘」出來之後降低到12.5比特幣/區塊。在第13,230,000個區塊(大概在2137年被挖出)之前,新幣的發行速度會以指數形式進行64次「二等分」。到那時每區塊發行比特幣數量變為比特幣的最小貨幣單位——1聰。最終,在經過1,344萬個區塊之後,所有的共20,999,999.9769億聰比特幣將全部發行完畢。換句話說, 到2140年左右,會存在接近2,100萬比特幣。在那之後,新的區塊不再包含比特幣獎勵,礦工的收益全部來自交易費。
在收到交易後,每一個節點都會在全網廣播前對這些交易進行校驗,並以接收時的相應順序,為有效的新交易建立一個池(交易池)。
每一個節點在校驗每一筆交易時,都需要對照一個長長的標准列表:
交易的語法和數據結構必須正確。
輸入與輸出列表都不能為空。
交易的位元組大小是小於MAX_BLOCK_SIZE的。
每一個輸出值,以及總量,必須在規定值的范圍內 (小於2,100萬個幣,大於0)。
沒有哈希等於0,N等於-1的輸入(coinbase交易不應當被中繼)。
nLockTime是小於或等於INT_MAX的。
交易的位元組大小是大於或等於100的。
交易中的簽名數量應小於簽名操作數量上限。
解鎖腳本(Sig)只能夠將數字壓入棧中,並且鎖定腳本(Pubkey)必須要符合isStandard的格式 (該格式將會拒絕非標准交易)。
池中或位於主分支區塊中的一個匹配交易必須是存在的。
對於每一個輸入,如果引用的輸出存在於池中任何的交易,該交易將被拒絕。
對於每一個輸入,在主分支和交易池中尋找引用的輸出交易。如果輸出交易缺少任何一個輸入,該交易將成為一個孤立的交易。如果與其匹配的交易還沒有出現在池中,那麼將被加入到孤立交易池中。
對於每一個輸入,如果引用的輸出交易是一個coinbase輸出,該輸入必須至少獲得COINBASE_MATURITY (100)個確認。
對於每一個輸入,引用的輸出是必須存在的,並且沒有被花費。
使用引用的輸出交易獲得輸入值,並檢查每一個輸入值和總值是否在規定值的范圍內 (小於2100萬個幣,大於0)。
如果輸入值的總和小於輸出值的總和,交易將被中止。
如果交易費用太低以至於無法進入一個空的區塊,交易將被拒絕。
每一個輸入的解鎖腳本必須依據相應輸出的鎖定腳本來驗證。
以下挖礦節點取名為 A挖礦節點
挖礦節點時刻監聽著傳播到比特幣網路的新區塊。而這些新加入的區塊對挖礦節點有著特殊的意義。礦工間的競爭以新區塊的傳播而結束,如同宣布誰是最後的贏家。對於礦工們來說,獲得一個新區塊意味著某個參與者贏了,而他們則輸了這場競爭。然而,一輪競爭的結束也代表著下一輪競爭的開始。
驗證交易後,比特幣節點會將這些交易添加到自己的內存池中。內存池也稱作交易池,用來暫存尚未被加入到區塊的交易記錄。
A節點需要為內存池中的每筆交易分配一個優先順序,並選擇較高優先順序的交易記錄來構建候選區塊。
一個交易想要成為「較高優先順序」,需滿足的條件:優先值大於57,600,000,這個值的生成依賴於3個參數:一個比特幣(即1億聰),年齡為一天(144個區塊),交易的大小為250個位元組:
High Priority > 100,000,000 satoshis * 144 blocks / 250 bytes = 57,600,000
區塊中用來存儲交易的前50K位元組是保留給較高優先順序交易的。 節點在填充這50K位元組的時候,會優先考慮這些最高優先順序的交易,不管它們是否包含了礦工費。這種機制使得高優先順序交易即便是零礦工費,也可以優先被處理。
然後,A挖礦節點會選出那些包含最小礦工費的交易,並按照「每千位元組礦工費」進行排序,優先選擇礦工費高的交易來填充剩下的區塊。
如區塊中仍有剩餘空間,A挖礦節點可以選擇那些不含礦工費的交易。有些礦工會竭盡全力將那些不含礦工費的交易整合到區塊中,而其他礦工也許會選擇忽略這些交易。
在區塊被填滿後,內存池中的剩餘交易會成為下一個區塊的候選交易。因為這些交易還留在內存池中,所以隨著新的區塊被加到鏈上,這些交易輸入時所引用UTXO的深度(即交易「塊齡」)也會隨著變大。由於交易的優先值取決於它交易輸入的「塊齡」,所以這個交易的優先值也就隨之增長了。最後,一個零礦工費交易的優先值就有可能會滿足高優先順序的門檻,被免費地打包進區塊。
UTXO(Unspent Transaction Output) : 每筆交易都有若干交易輸入,也就是資金來源,也都有若干筆交易輸出,也就是資金去向。一般來說,每一筆交易都要花費(spend)一筆輸入,產生一筆輸出,而其所產生的輸出,就是「未花費過的交易輸出」,也就是 UTXO。
塊齡:UTXO的「塊齡」是自該UTXO被記錄到區塊鏈為止所經歷過的區塊數,即這個UTXO在區塊鏈中的深度。
區塊中的第一筆交易是筆特殊交易,稱為創幣交易或者coinbase交易。這個交易是由挖礦節點構造並用來獎勵礦工們所做的貢獻的。假設此時一個區塊的獎勵是25比特幣,A挖礦的節點會創建「向A的地址支付25.1個比特幣(包含礦工費0.1個比特幣)」這樣一個交易,把生成交易的獎勵發送到自己的錢包。A挖出區塊獲得的獎勵金額是coinbase獎勵(25個全新的比特幣)和區塊中全部交易礦工費的總和。
A節點已經構建了一個候選區塊,那麼就輪到A的礦機對這個新區塊進行「挖掘」,求解工作量證明演算法以使這個區塊有效。比特幣挖礦過程使用的是SHA256哈希函數。
用最簡單的術語來說, 挖礦節點不斷重復進行嘗試,直到它找到的隨機調整數使得產生的哈希值低於某個特定的目標。 哈希函數的結果無法提前得知,也沒有能得到一個特定哈希值的模式。舉個例子,你一個人在屋裡打檯球,白球從A點到達B點,但是一個人推門進來看到白球在B點,卻無論如何是不知道如何從A到B的。哈希函數的這個特性意味著:得到哈希值的唯一方法是不斷的嘗試,每次隨機修改輸入,直到出現適當的哈希值。
需要以下參數
• block的版本 version
• 上一個block的hash值: prev_hash
• 需要寫入的交易記錄的hash樹的值: merkle_root
• 更新時間: ntime
• 當前難度: nbits
挖礦的過程就是找到x使得
SHA256(SHA256(version + prev_hash + merkle_root + ntime + nbits + x )) < TARGET
上式的x的范圍是0~2^32, TARGET可以根據當前難度求出的。
簡單打個比方,想像人們不斷扔一對色子以得到小於一個特定點數的游戲。第一局,目標是12。只要你不扔出兩個6,你就會贏。然後下一局目標為11。玩家只能扔10或更小的點數才能贏,不過也很簡單。假如幾局之後目標降低為了5。現在有一半機率以上扔出來的色子加起來點數會超過5,因此無效。隨著目標越來越小,要想贏的話,扔色子的次數會指數級的上升。最終當目標為2時(最小可能點數),只有一個人平均扔36次或2%扔的次數中,他才能贏。
如前所述,目標決定了難度,進而影響求解工作量證明演算法所需要的時間。那麼問題來了:為什麼這個難度值是可調整的?由誰來調整?如何調整?
比特幣的區塊平均每10分鍾生成一個。這就是比特幣的心跳,是貨幣發行速率和交易達成速度的基礎。不僅是在短期內,而是在幾十年內它都必須要保持恆定。在此期間,計算機性能將飛速提升。此外,參與挖礦的人和計算機也會不斷變化。為了能讓新區塊的保持10分鍾一個的產生速率,挖礦的難度必須根據這些變化進行調整。事實上,難度是一個動態的參數,會定期調整以達到每10分鍾一個新區塊的目標。簡單地說,難度被設定在,無論挖礦能力如何,新區塊產生速率都保持在10分鍾一個。
那麼,在一個完全去中心化的網路中,這樣的調整是如何做到的呢?難度的調整是在每個完整節點中獨立自動發生的。每2,016個區塊(2周產生的區塊)中的所有節點都會調整難度。難度的調整公式是由最新2,016個區塊的花費時長與20,160分鍾(兩周,即這些區塊以10分鍾一個速率所期望花費的時長)比較得出的。難度是根據實際時長與期望時長的比值進行相應調整的(或變難或變易)。簡單來說,如果網路發現區塊產生速率比10分鍾要快時會增加難度。如果發現比10分鍾慢時則降低難度。
為了防止難度的變化過快,每個周期的調整幅度必須小於一個因子(值為4)。如果要調整的幅度大於4倍,則按4倍調整。由於在下一個2,016區塊的周期不平衡的情況會繼續存在,所以進一步的難度調整會在下一周期進行。因此平衡哈希計算能力和難度的巨大差異有可能需要花費幾個2,016區塊周期才會完成。
舉個例子,當前A節點在挖277,316個區塊,A挖礦節點一旦完成計算,立刻將這個區塊發給它的所有相鄰節點。這些節點在接收並驗證這個新區塊後,也會繼續傳播此區塊。當這個新區塊在網路中擴散時,每個節點都會將它作為第277,316個區塊(父區塊為277,315)加到自身節點的區塊鏈副本中。當挖礦節點收到並驗證了這個新區塊後,它們會放棄之前對構建這個相同高度區塊的計算,並立即開始計算區塊鏈中下一個區塊的工作。
比特幣共識機制的第三步是通過網路中的每個節點獨立校驗每個新區塊。當新區塊在網路中傳播時,每一個節點在將它轉發到其節點之前,會進行一系列的測試去驗證它。這確保了只有有效的區塊會在網路中傳播。
每一個節點對每一個新區塊的獨立校驗,確保了礦工無法欺詐。在前面的章節中,我們看到了礦工們如何去記錄一筆交易,以獲得在此區塊中創造的新比特幣和交易費。為什麼礦工不為他們自己記錄一筆交易去獲得數以千計的比特幣?這是因為每一個節點根據相同的規則對區塊進行校驗。一個無效的coinbase交易將使整個區塊無效,這將導致該區塊被拒絕,因此,該交易就不會成為總賬的一部分。
比特幣去中心化的共識機制的最後一步是將區塊集合至有最大工作量證明的鏈中。一旦一個節點驗證了一個新的區塊,它將嘗試將新的區塊連接到到現存的區塊鏈,將它們組裝起來。
節點維護三種區塊:
· 第一種是連接到主鏈上的,
· 第二種是從主鏈上產生分支的(備用鏈),
· 第三種是在已知鏈中沒有找到已知父區塊的。
有時候,新區塊所延長的區塊鏈並不是主鏈,這一點我們將在下面「 區塊鏈分叉」中看到。
如果節點收到了一個有效的區塊,而在現有的區塊鏈中卻未找到它的父區塊,那麼這個區塊被認為是「孤塊」。孤塊會被保存在孤塊池中,直到它們的父區塊被節點收到。一旦收到了父區塊並且將其連接到現有區塊鏈上,節點就會將孤塊從孤塊池中取出,並且連接到它的父區塊,讓它作為區塊鏈的一部分。當兩個區塊在很短的時間間隔內被挖出來,節點有可能會以相反的順序接收到它們,這個時候孤塊現象就會出現。
選擇了最大難度的區塊鏈後,所有的節點最終在全網范圍內達成共識。隨著更多的工作量證明被添加到鏈中,鏈的暫時性差異最終會得到解決。挖礦節點通過「投票」來選擇它們想要延長的區塊鏈,當它們挖出一個新塊並且延長了一個鏈,新塊本身就代表它們的投票。
因為區塊鏈是去中心化的數據結構,所以不同副本之間不能總是保持一致。區塊有可能在不同時間到達不同節點,導致節點有不同的區塊鏈視角。解決的辦法是, 每一個節點總是選擇並嘗試延長代表累計了最大工作量證明的區塊鏈,也就是最長的或最大累計難度的鏈。
當有兩個候選區塊同時想要延長最長區塊鏈時,分叉事件就會發生。正常情況下,分叉發生在兩名礦工在較短的時間內,各自都算得了工作量證明解的時候。兩個礦工在各自的候選區塊一發現解,便立即傳播自己的「獲勝」區塊到網路中,先是傳播給鄰近的節點而後傳播到整個網路。每個收到有效區塊的節點都會將其並入並延長區塊鏈。如果該節點在隨後又收到了另一個候選區塊,而這個區塊又擁有同樣父區塊,那麼節點會將這個區塊連接到候選鏈上。其結果是,一些節點收到了一個候選區塊,而另一些節點收到了另一個候選區塊,這時兩個不同版本的區塊鏈就出現了。
分叉之前
分叉開始
我們看到兩個礦工幾乎同時挖到了兩個不同的區塊。為了便於跟蹤這個分叉事件,我們設定有一個被標記為紅色的、來自加拿大的區塊,還有一個被標記為綠色的、來自澳大利亞的區塊。
假設有這樣一種情況,一個在加拿大的礦工發現了「紅色」區塊的工作量證明解,在「藍色」的父區塊上延長了塊鏈。幾乎同一時刻,一個澳大利亞的礦工找到了「綠色」區塊的解,也延長了「藍色」區塊。那麼現在我們就有了兩個區塊:一個是源於加拿大的「紅色」區塊;另一個是源於澳大利亞的「綠色」。這兩個區塊都是有效的,均包含有效的工作量證明解並延長同一個父區塊。這個兩個區塊可能包含了幾乎相同的交易,只是在交易的排序上有些許不同。
比特幣網路中鄰近(網路拓撲上的鄰近,而非地理上的)加拿大的節點會首先收到「紅色」區塊,並建立一個最大累計難度的區塊,「紅色」區塊為這個鏈的最後一個區塊(藍色-紅色),同時忽略晚一些到達的「綠色」區塊。相比之下,離澳大利亞更近的節點會判定「綠色」區塊勝出,並以它為最後一個區塊來延長區塊鏈(藍色-綠色),忽略晚幾秒到達的「紅色」區塊。那些首先收到「紅色」區塊的節點,會即刻以這個區塊為父區塊來產生新的候選區塊,並嘗試尋找這個候選區塊的工作量證明解。同樣地,接受「綠色」區塊的節點會以這個區塊為鏈的頂點開始生成新塊,延長這個鏈。
分叉問題幾乎總是在一個區塊內就被解決了。網路中的一部分算力專注於「紅色」區塊為父區塊,在其之上建立新的區塊;另一部分算力則專注在「綠色」區塊上。即便算力在這兩個陣營中平均分配,也總有一個陣營搶在另一個陣營前發現工作量證明解並將其傳播出去。在這個例子中我們可以打個比方,假如工作在「綠色」區塊上的礦工找到了一個「粉色」區塊延長了區塊鏈(藍色-綠色-粉色),他們會立刻傳播這個新區塊,整個網路會都會認為這個區塊是有效的,如上圖所示。
所有在上一輪選擇「綠色」區塊為勝出者的節點會直接將這條鏈延長一個區塊。然而,那些選擇「紅色」區塊為勝出者的節點現在會看到兩個鏈: 「藍色-綠色-粉色」和「藍色-紅色」。 如上圖所示,這些節點會根據結果將 「藍色-綠色-粉色」 這條鏈設置為主鏈,將 「藍色-紅色」 這條鏈設置為備用鏈。 這些節點接納了新的更長的鏈,被迫改變了原有對區塊鏈的觀點,這就叫做鏈的重新共識 。因為「紅」區塊做為父區塊已經不在最長鏈上,導致了他們的候選區塊已經成為了「孤塊」,所以現在任何原本想要在「藍色-紅色」鏈上延長區塊鏈的礦工都會停下來。全網將 「藍色-綠色-粉色」 這條鏈識別為主鏈,「粉色」區塊為這條鏈的最後一個區塊。全部礦工立刻將他們產生的候選區塊的父區塊切換為「粉色」,來延長「藍色-綠色-粉色」這條鏈。
從理論上來說,兩個區塊的分叉是有可能的,這種情況發生在因先前分叉而相互對立起來的礦工,又幾乎同時發現了兩個不同區塊的解。然而,這種情況發生的幾率是很低的。單區塊分叉每周都會發生,而雙塊分叉則非常罕見。
比特幣將區塊間隔設計為10分鍾,是在更快速的交易確認和更低的分叉概率間作出的妥協。更短的區塊產生間隔會讓交易清算更快地完成,也會導致更加頻繁地區塊鏈分叉。與之相對地,更長的間隔會減少分叉數量,卻會導致更長的清算時間。
7. 『學概念找員外』門限密碼與多重簽名
密鑰分存還是有一個問題:密鑰分存之後,如果後面要用原密鑰來簽名,那就需要取得子密鑰,還原成原密鑰,然後才能簽名。這個過程有可能被黑客乘虛而入,盜取密鑰。
密碼學可以解決這個問題。如果子密鑰儲存在不同的設備中,可以以去中心化的方式還原原密鑰,而不是在某台設備上完成,這種技術叫門限簽名(threshold signature)技術。典型的例子就是使用雙重安全機制的電子錢包(N=2且K=2),如果兩個子密鑰分別保存在個人電腦和手機上,你可以在電腦上發起付款,這時,電腦會生成一個簽名片段,並發送到你的手機上,然後,手機會提示你付款信息(包括收款人、金額等),然後等待你確認。如果你確認了付款信息,這時,手機會利用它的子密鑰完成整個簽名,然後廣播到區塊鏈上。萬一黑客控制了你的電腦,試圖把比特幣轉到他的賬戶,你根據手機上的付款信息就知道有問題了,從而不會確認這筆交易。門限密碼涉及的數學細節比較復雜,員外也看不懂,所以就不展開討論了。
門限簽名是密碼學中的一項技術,將一個密鑰切分成不同片段,分別儲存,在交易簽名時無須還原原密鑰。而多重簽名是比特幣腳本的特性,把一個比特幣賬戶的控制權交給多個密鑰,這些密鑰共同保障賬戶安全。門限簽名和多重簽名都能克服密鑰單點保存的缺陷。
還有另外一種方法可以克服密鑰單點保存的缺陷,即多重簽名(multisignatures),這個名詞在第3章曾出現過。通過比特幣腳本,可以直接把一個比特幣賬戶的控制權交給多個密鑰,而不是將密鑰分存。這些密鑰可以保存在不同的地點,並分別生成簽名。當然,最終完成的交易的信息還是會保存在某台設備上,但即使黑客控制了這台設備,他所能做的也只不過阻止這個交易被廣播到整個網路上去。沒有其他設備參與,他無法生成出一個正當有效的多重簽名。
舉例來說,假設A、B、C、D、E是一家公司的創始人,這家公司有許多的比特幣。我們可能會用多重簽名來保護這些比特幣。這5個人,每人都有一對密鑰,我們可以用其中的3個簽名來保護冷儲存,一筆交易需要5個人中至少3個人的簽名才能完成。
這樣,只要我們5個人在不同地方且使用不同的安全措施保存各自的密鑰,那麼比特幣就會相當安全。黑客必須盜取我們當中3個人的密鑰,才能盜取比特幣。即便我們其中一個或兩個背棄了我們,他(們)也無法捲款而逃,因為他們還需要另一個簽名。同時,如果我們其中一個遺失了密鑰,其他人還是可以取出比特幣,並轉到新的賬戶,重新設置密碼。總而言之,多重簽名可以比較妥善地管理在冷儲存端的大額比特幣,任何重大事項都需要多人的參與才能實現。
上文中,我們說到,人們使用門限簽名技術的原因是為了實現雙重安全機制或多重安全機制,使用多重簽名技術的原因是為了實現多人對共同財產實現共同控制。實際上,這兩種技術都可以實現上述兩種目的。
8. 區塊鏈本質是什麼比特幣原理又是什麼二者究竟有何區別
一枚比特幣價格從2萬多美元狂漲到4萬美元。這不由得引起了我的研究興趣,或者說簡單了解了一下比特幣到底是什麼,它的機理具體是什麼樣子的,揭開它的神秘面紗。因此,簡單搜索了一些資料,也對比特幣有些了解,便把手頭上的資料整理了一下。
(3)目的:去中心化,減少風險
中心式網路只有中央伺服器能夠存儲和處理數據,其缺點是工作量大,一旦癱瘓則整個系統癱瘓;數據存儲量大;中央管理者許可權大。
分布式網路中的所有伺服器均能夠存儲和處理數據,各伺服器之間地位平等,可以存儲更多的數據和具有更高的安全性。
大致的科普內容就是這樣,如果還想多了解一些,可以看看中本聰的論文和下面的官方科普視頻。