區(qū)塊鏈錢包科普:如何通過私鑰創(chuàng)建以太坊錢包地址?
編者注:我們翻譯和出版與密碼學(xué)貨幣的私鑰、地址和錢包有關(guān)的內(nèi)容,無非希望傳達(dá)清楚幾個(gè)要點(diǎn):
1. 密碼學(xué)貨幣不同于傳統(tǒng)的銀行,你有很多工具可以生成一把私鑰來持有密碼學(xué)貨幣,既不需要向銀行申請,也不需要給誰報(bào)備,沒有任何人能阻止你擁有自己的私鑰和錢包;
2. 公鑰和用來接收轉(zhuǎn)賬的地址都是由私鑰使用單向的數(shù)學(xué)運(yùn)算推導(dǎo)出來的,如果不信任現(xiàn)有的工具,你完全可以自己使用這些數(shù)學(xué)運(yùn)算來生成地址;同時(shí),公開地址不會產(chǎn)生安全問題,因?yàn)榈刂窡o法反推出公鑰,也無法反推出私鑰;
3. 使用第三方提供的服務(wù)時(shí),弄清楚服務(wù)的性質(zhì),不要向任何人暴露自己的私鑰,并且定期備份。
在本系列文章的第一篇中,我們得到了如下的比特幣私鑰:
60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2
編者注:這里沒有寫出私鑰的生成過程。簡單來說,私鑰就是一串隨機(jī)的十六進(jìn)制字符串,為了安全(私鑰不暴露、不被他人重現(xiàn)出來),這串隨機(jī)數(shù)的生成環(huán)境應(yīng)盡可能滿足隨機(jī)性、不可預(yù)測性、不可重現(xiàn)性。
所以,不要自己寫一串?dāng)?shù)字來當(dāng)私鑰,因?yàn)槟阕砸詾榈?ldquo;隨機(jī)”往往并不怎么隨機(jī),很不安全。
(理論上來說你確實(shí)可以自己連拋 256 次硬幣產(chǎn)生符合長度要求(64 位)的隨機(jī)數(shù),但還是很不推薦。)
在本文中,我們會演示使用這個(gè)私鑰來獲得公開地址,以及與該私鑰對應(yīng)的以太坊錢包地址。
通過私鑰來獲得比特幣錢包地址的具體流程有些復(fù)雜,因此我們會描述簡化后的版本。我們需要使用一個(gè)哈希函數(shù)去獲得公鑰,還需要使用另一個(gè)函數(shù)去獲得地址。
現(xiàn)在,讓我們開始吧。
公鑰
這部分內(nèi)容和之前討論比特幣的文章中所說的相同,所以如果你已經(jīng)讀完了,那么就可以跳過(除非你想要復(fù)習(xí)一下)。
首先,我們需要在私鑰上使用 ECDSA,即橢圓曲線數(shù)字簽名算法。橢圓曲線是通過 y² = x³ + ax + b 公式得出的,其中 a 和 b 可以自定義。橢圓曲線家族有很多知名并且廣泛應(yīng)用的案例。比特幣使用了 secp256k1 曲線,關(guān)于橢圓曲線密碼學(xué),如果你想了解更多,可以參考此文章。
以太坊使用了同樣的橢圓曲線,secp256k1,因此對于比特幣和以太坊來說,獲得公鑰的流程是相同的。
對私鑰作了 ECDSA 運(yùn)算之后,我們得到了 64 字節(jié)的整數(shù),這是由兩個(gè) 32 字節(jié)的整數(shù)串聯(lián)組成,代表了橢圓曲線上某個(gè)點(diǎn)的 X 值和 Y 值。
在 Python 程序中,代碼顯示如下:
private_key_bytes = codecs.decode(private_key, ‘hex’) # Get ECDSA public key key = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1).verifying_key key_bytes = key.to_string() key_hex = codecs.encode(key_bytes, ‘hex’)
注意:從上面的代碼可以看出,我使用了 ecdsa 模塊并通過編碼器解碼了私鑰。這樣寫更多是因?yàn)?Python 的關(guān)系,而與算法本身無關(guān),為免誤解,讓我來好好解釋一下。
Python 語言中,至少有兩種數(shù)據(jù)類型可以保存私鑰和公鑰:“str”和“bytes”。前者對應(yīng)的是 string(字符串),后者則是 byte array(數(shù)值)。Python 語言中的密碼學(xué)運(yùn)算只能對“bytes”類操作,將 byte 型數(shù)據(jù)作為輸入,并且將輸出作為結(jié)果。
但是,這里面有個(gè)小問題:作為字符串的“4f3c”和作為 byte array 的 4f3c 是不等同的,string 等于 byte array 和兩個(gè)元素 O< 的結(jié)合。codecs.decode 方法就是將字符串轉(zhuǎn)換為 byte array。本文中使用的密碼學(xué)操作都要進(jìn)行這一步驟。
錢包地址
一旦獲得公鑰,我們就可以計(jì)算出錢包地址,和比特幣不同,以太坊在主網(wǎng)和所有測試網(wǎng)都有相同的地址。當(dāng)用戶發(fā)起轉(zhuǎn)賬和簽名的時(shí)候,他們需要選擇相應(yīng)的網(wǎng)絡(luò)。
為了通過公鑰得出地址,我們需要做的就是在公鑰上應(yīng)用 Keccak-256 加密算法,然后拿出結(jié)果的后 20 個(gè)字節(jié),這樣就可以了。整個(gè)過程不需要其他的哈希函數(shù),無需 Base58 編碼,也不用其他任何轉(zhuǎn)換,你唯一需要做的事情就是在地址的開頭添加“0x”。
Python代碼如下:
public_key_bytes = codecs.decode(public_key, ‘hex’) keccak_hash = keccak.new(digest_bits=256) keccak_hash.update(public_key_bytes) keccak_digest = keccak_hash.hexdigest() # Take the last 20 bytes wallet_len = 40 wallet = ‘0x’ + keccak_digest[-wallet_len:]
校驗(yàn)和(checksum)
我們都知道,比特幣是對公鑰使用哈希算法,然后取結(jié)果的前 4 個(gè)數(shù)字,以此創(chuàng)建校驗(yàn)和。這對于所有比特幣地址來說都是適用的,因此在沒有添加 checksum 字節(jié)之前,用戶無法獲得有效地址。
編者注:校驗(yàn)和(checksum)是一種較為簡單的驗(yàn)證數(shù)據(jù)完整性的方法,具體方法有很多種,比如說對一段數(shù)據(jù)逐次取 4 個(gè)比特,把取出的數(shù)全部加起來,最后得到一個(gè) 4 個(gè)比特的值作為校驗(yàn)和。如果兩段數(shù)據(jù)不一樣,產(chǎn)生的校驗(yàn)和有極大概率是不一樣的。跟哈希函數(shù)的原理有相似之處,但夠不上密碼學(xué)哈希函數(shù)那樣的強(qiáng)度。)
例:
MD5(cvsoiu687y0adbfiq7et5tgho0) = a277a316d38c21786eac518b83af898f
MD5(wysoiu687y0adbfiq7et5tgho0) = becd314fb8d277cfe20aaadc2b52c177
在以太坊中,產(chǎn)生地址的流程與此并不相同。最初的時(shí)候,以太坊中沒有校驗(yàn)和這樣的機(jī)制來驗(yàn)證秘鑰的完整性。但是在 2016 年,Vitalik Buterin 引進(jìn)了 checksum 機(jī)制,現(xiàn)在已經(jīng)被錢包提供商和交易所使用。
在以太坊錢包地址上添加 checksum 使得我們可以通過大小寫來校驗(yàn)地址的有效性。
首先,你需要獲得地址的 Keccak-256 哈希值。注意,將地址放入哈希函數(shù)的時(shí)候不可以添加 0x 部分。
其次,你需要迭代初始地址的字符,如果哈希值中的第 i 個(gè)字節(jié)(byte)大于或者等于 8,那么你要將地址中的第 i 個(gè)字符變?yōu)榇髮?,否則就還是保持小寫。
最后,你需要把 0x 添加到結(jié)果的開頭。如果忽略大小寫,那么校驗(yàn)和地址與初始地址是相同的。但是,這種使用大寫字母的做法讓人們可以隨時(shí)隨地檢查地址是否有效。你可以通過這個(gè)網(wǎng)頁找到有效驗(yàn)證 checksum 的算法。
通過 checksum 驗(yàn)證方法,我們可以得到下面的結(jié)論:
“平均來看每個(gè)地址有 15 個(gè)校驗(yàn)位,并且隨機(jī)得出的錯誤地址能夠偶然通過檢驗(yàn)的概率為 0.0247%。”
下面是將 checksum 添加到以太坊地址的代碼:
checksum = ‘0x’ # Remove ‘0x’ from the address address = address[2:] address_byte_array = address.encode(‘utf-8’) keccak_hash = keccak.new(digest_bits=256) keccak_hash.update(address_byte_array) keccak_digest = keccak_hash.hexdigest() for i in range(len(address)): address_char = address[i] keccak_char = keccak_digest[i] if int(keccak_char, 16) >= 8: checksum += address_char.upper() else: checksum += str(address_char)
結(jié)論
如文中所述,和比特幣相比,創(chuàng)建以太坊地址要容易地多。我們需要做的事情就是用私鑰在 ECDSA 上找出公鑰,然后使用 Keccak-256 算法,并以最終哈希值的后 20 個(gè)字節(jié)作為地址。
如果你想使用這些代碼,我已經(jīng)把它們發(fā)布到這個(gè) GitHub repository 上了.
編者注:如上圖所示,以太坊的公鑰和地址都由私鑰生成,并且其生成所需的數(shù)學(xué)運(yùn)算都是完全公開的。
以上就是區(qū)塊鏈錢包科普:如何通過私鑰創(chuàng)建以太坊錢包地址的詳細(xì)內(nèi)容,更多關(guān)于通過私鑰創(chuàng)建以太坊錢包地址的資料請關(guān)注腳本之家其它相關(guān)文章!
你可能感興趣的文章
-
區(qū)塊鏈錢包原理科普:關(guān)于錢包的基礎(chǔ)密碼學(xué)
這篇文章主要介紹了區(qū)塊鏈錢包原理科普:關(guān)于錢包的基礎(chǔ)密碼學(xué)的相關(guān)資料,希望這篇關(guān)于錢包的基礎(chǔ)密碼學(xué)的文章,能夠幫助到各位朋友對區(qū)塊鏈錢包原理的理解?!?/p> 2021-12-13
-
區(qū)塊鏈錢包是什么意思?區(qū)塊鏈錢包的技術(shù)原理分析
這篇文章主要介紹了區(qū)塊鏈錢包是什么意思?區(qū)塊鏈錢包的技術(shù)原理分析的相關(guān)資料,希望這篇關(guān)于通俗解釋區(qū)塊鏈錢包的文章,能夠幫助各位投資者對區(qū)塊鏈錢包這一個(gè)概念有一個(gè)…
2024-02-04 -
區(qū)塊鏈錢包有哪些?區(qū)塊鏈?zhǔn)箦X包優(yōu)缺點(diǎn)
這篇文章主要介紹了區(qū)塊鏈錢包有哪些?區(qū)塊鏈?zhǔn)箦X包優(yōu)缺點(diǎn)的相關(guān)資料,錢包就是存儲和使用數(shù)字貨幣的工具,一個(gè)幣對應(yīng)一個(gè)錢包。用來存儲幣種,或者“交易”幣種。還不太…
2021-08-27 -
2021年區(qū)塊鏈錢包排名榜TOP10盤點(diǎn)
這篇文章主要介紹了2021年區(qū)塊鏈錢包排名榜TOP10盤點(diǎn)的相關(guān)資料,目前市面上區(qū)塊鏈錢包很多,很多幣圈小白想要使用數(shù)字錢包,結(jié)果在第一步如何選擇上就犯了難,今天小編就…
2021-08-16 -
區(qū)塊鏈錢包怎么用?一文玩轉(zhuǎn)區(qū)塊鏈錢包
這篇文章主要介紹了區(qū)塊鏈錢包怎么用?一文玩轉(zhuǎn)區(qū)塊鏈錢包的相關(guān)資料,區(qū)塊鏈錢包,最重要的就是安全性,很多投資者不會用區(qū)塊鏈錢包,今天小編帶大家一起詳細(xì)的解讀一下區(qū)…
2021-08-16 -
區(qū)塊鏈錢包介紹科普內(nèi)容賬戶管理
區(qū)塊鏈錢包是用于存儲虛擬貨幣的工具或者APP,它原理上是記錄公鑰和私鑰的工具…
2021-04-25 -
區(qū)塊鏈錢包的基本知識點(diǎn)
今天為大家?guī)韰^(qū)塊鏈錢包的基本知識點(diǎn),感興趣的朋友可以一起看看…
2021-04-22 -
區(qū)塊鏈錢包發(fā)展史
今天小編為大家?guī)韰^(qū)塊鏈錢包發(fā)展史,感興趣的朋友一起看看吧…
2021-04-22 -
區(qū)塊鏈錢包分類 區(qū)塊鏈錢包有哪幾類錢包?
這篇文章主要介紹了區(qū)塊鏈錢包分類,區(qū)塊鏈錢包有哪幾類錢包?我們將從私鑰的存儲和私鑰的生成兩個(gè)方向?qū)﹀X包進(jìn)行分類。需要的朋友可以參考下?!?/p> 2025-02-01
-
以太坊錢包轉(zhuǎn)賬失敗是怎么回事?ETH錢包轉(zhuǎn)賬失敗的原因
這篇文章主要介紹了ETH錢包轉(zhuǎn)賬失敗的原因的相關(guān)資料,希望這篇關(guān)于ETH錢包轉(zhuǎn)賬失敗的原因的文章,能夠幫助各位朋友對ETH錢包轉(zhuǎn)賬有個(gè)更加深入的了解。…
2021-12-09