在交易中,比特幣地址通常以收款方出現(xiàn)。如果把比特幣交易比作一張支票, 比特幣地址就是收款人,也就是我們要寫入收款人 一欄的內(nèi)容。一張支票的收款人可能是某個銀行賬戶,也可能是某個公司、機構(gòu),甚至是現(xiàn)金支票。支票不需要指定一個特定的賬戶,而是用一個普通的名字作為收 款人,這使它成為一種相當(dāng)靈活的支付工具。與此類似,比特幣地址的使用也使比特幣交易變得很靈活。比特幣地址可以代表一對公鑰和私鑰的所有者,也可以代表其它東西,比如付款腳本。現(xiàn)在,讓我們來看一個簡單的例子,由公鑰生成比特幣地址。
比特幣地址可由公鑰經(jīng)過單向的加密哈希算法得到。哈希算法是一種單向函數(shù),接收任意長度的輸入產(chǎn)生指紋摘要。加密哈希函數(shù)在比特幣中被廣泛使用: 比特幣地址、腳本地址以及在挖礦中的工作量證明算法。由公鑰生成比特幣地址時使 用 的 算 法 是 Secure Hash Algorithm (SHA) 和 the RACE Integrity Primitives evaluation Message Digest (RIPEMD), 特 別 是 SHA256 和RIPEMD160。
以公鑰 K 為輸入,計算其 SHA256 哈希值,并以此結(jié)果計算 RIPEMD160 哈希值,得到一個長度為 160 比特(20 字節(jié))的數(shù)字:
A = RIPEMD160(SHA256(K))
公式中,K 是公鑰,A 是生成的比特幣地址。
比特幣地址與公鑰不同。比特幣地址是由公鑰經(jīng)過單向的哈希函數(shù)生成的。
通常用戶見到的比特幣地址是經(jīng)過"base58Check"編碼的,這種編碼使用 了 58 個字符(一種base58 數(shù)字系統(tǒng))和校驗碼,提高了可讀性、避免歧義并有效防止了在地址轉(zhuǎn)錄和輸入中產(chǎn)生的錯誤。base58Check 編碼也被 用于比特幣的其它地方,例如比特幣地址、私鑰、加密的密鑰和腳本哈希中,用來提高可讀性和錄入的正確性。下一節(jié)中我們會詳細(xì)解釋 base58Check 的 編碼機制,以及它產(chǎn)生的結(jié)果。下圖描述了如何從公鑰生成比特幣地址。
為了更簡潔方便地表示長串的數(shù)字,許多計算機系統(tǒng)會使用一種以數(shù)字和字母組成的大于十進制的表示法。例如,傳統(tǒng)的十進制計數(shù)系統(tǒng)使用 0-9 十個數(shù)字,而十六進制系統(tǒng)使用了額外的 A-F 六個字母。一個同樣的數(shù)字,它的十六進制表示就會比十進制表示更短。更進一步,base64 使用了 26 個小寫字母、
26 個大寫字母、10 個數(shù)字以及兩個符 號(例如"+"和"/"),用于在電子郵件這樣的基于文本的媒介中傳輸二進制數(shù)據(jù)。base64 通常用于編碼郵件中的附件。base58 是一種基于文本的 二進制編碼格式,用在比特幣和其它的加密貨幣中。這種編碼格式不僅實現(xiàn)了數(shù)據(jù)壓縮,保持了易讀性,還具有錯誤診斷功能。base58 是 base64 編碼格 式的子集,同樣使用大小寫字母和 10 個數(shù)字, 但舍棄了一些容易錯讀和在特定字體中容易混淆的字符。具體地,base58 不含
base64 中的 0(數(shù)字 0)、O(大寫字母 o)、l(小寫字母 L)、I(大寫字母i),以及"+"和"/"兩個字符。簡而言之,base58 就是由不包括(0,O,l,I)的大 小寫字母和數(shù)字組成。例 4-1 比特幣的 base58 字母表
123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxy z
base58Check 是一種常用在比特幣中的 base58 編碼格式,增加了錯誤校驗碼來檢查數(shù)據(jù)在轉(zhuǎn)錄中出現(xiàn)的錯誤。 校驗碼長 4 個字節(jié),添加到需要編碼的數(shù)據(jù)之后。校驗碼是從需要編碼的數(shù)據(jù)的哈希值中得到的,所以可以用來檢測并避免轉(zhuǎn)錄和輸入中產(chǎn)生的錯誤。使用 base58check 編碼格式時,編碼軟件會計算原始數(shù)據(jù)的校驗碼并和結(jié)果數(shù)據(jù)中自帶的校驗碼進行對比。二者不匹配則表明有錯誤產(chǎn)生,那么這個 base58Check 格式的數(shù)據(jù)就是無效的。例如,一個錯誤比特幣地址就不會被錢包認(rèn)為是有效的地址,否則這種錯誤會造成資金的丟失。為了使用 base58Check 編碼格式對數(shù)據(jù)(數(shù)字)進行編碼,首先我們要對數(shù)據(jù)添加一個稱作"版本字節(jié)"的前綴,這個前綴用來明確需要編碼的數(shù) 據(jù)的類型。例如,比特幣地址的前綴是 0(十六進制是 0x00),而對私鑰編碼時前綴是 128(十六進制是 0x80)。 表會列出一些常見版本的前綴。
接下來,我們計算"雙哈希"校驗碼,意味著要對之前的結(jié)果(前綴和數(shù)據(jù))運行兩次 SHA256 哈希算法:
checksum = SHA256(SHA256(prefix+data))在產(chǎn)生的長 32 個字節(jié)的哈希值(兩次哈希運算)中,我們只取前 4 個字節(jié)。這4 個字節(jié)就作為校驗碼。校驗碼會添加到數(shù)據(jù)之后。
結(jié)果由三部分組成:前綴、數(shù)據(jù)和校驗碼。這個結(jié)果采用之前描述的 base58 字母表編碼。下圖描述了 base58Check 編碼的過程。
base58Check 編碼:一種 base58 格式的、有版本的、經(jīng)過校驗的格式,可以明確的對比特幣數(shù)據(jù)編碼的編碼格式,在比特幣中,大多數(shù)需要向用戶展示的數(shù)據(jù)都使用 base58Check 編碼,可以實現(xiàn)數(shù)據(jù)壓縮,易讀而且有錯誤檢驗。base58Check 編碼中 的版本前綴是數(shù)據(jù)的格式易于辨別,編碼之后的數(shù)據(jù)頭包含了明確的屬性。這些屬性使用戶可以輕松明確被編碼的數(shù)據(jù)的類型以及如何使用它們。例如我們可以看到 他們的不同,base58Check 編碼的比特幣地址是以 1 開頭的,而 base58Check 編碼的私鑰 WIF 是以 5 開頭的。表 4-1 展示了一些版本前綴 和他們對應(yīng)的 base58 格式。
表 4-1 base58Check 版本前綴和編碼后的結(jié)果種類版本前綴 (hex)base58 格式Bitcoin Address0x001
Pay-to-script-Hash Address 0x053
Bitcoin Testnet Address0x6Fm or n Private Key WIF0x805, K or L BIP38 Encrypted Private Key0x01426P BIP32 Extended Public Key 0x0488B21Expub
我們回顧比特幣地址產(chǎn)生的完整過程,從私鑰、到公鑰(橢圓曲線上某個點)、再到兩次哈希的地址,最終產(chǎn)生 base58Check 格式的比特幣地址。之前C++代碼完整詳細(xì)的展示了從私鑰到 base58Check 編碼后的比特幣地址的步驟。代碼中使用"其他客戶端、資料庫、工具包 "中介紹的 libbitcoinlibrary 來實現(xiàn)某些輔助功能。








