比特币钱包私钥_如何通过私钥创建比特币钱包地址
比特幣錢包私鑰
In the previous article, we looked at different methods to generate a private key. Whatever method you choose, you’ll end up with 32 bytes of data. Here’s the one that we got at the end of that article:
在上一篇文章中 ,我們研究了生成私鑰的不同方法。 無論選擇哪種方法,最終都會得到32個字節的數據。 這是我們在本文結尾處得到的:
60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2
60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2
We’ll use this private key throughout the article to derive both a public key and the address for the Bitcoin wallet.
在整篇文章中,我們將使用此私鑰導出公鑰和比特幣錢包的地址。
What we want to do is to apply a series of conversions to the private key to get a public key and then a wallet address. Most of these conversions are called hash functions. These hash functions are one-way conversions that can’t be reversed. We won’t go to the mechanics of the functions themselves — there are plenty of great articles that cover that. Instead, we will look at how using these functions in the correct order can lead you to the Bitcoin wallet address that you can use.
我們要做的是對私鑰進行一系列轉換,以獲取公鑰,然后獲取錢包地址。 這些轉換中的大多數被稱為哈希函數。 這些散列函數是不可逆的單向轉換。 我們不會去探討函數本身的機制-涵蓋了很多很棒的文章。 取而代之的是,我們將研究如何以正確的順序使用這些功能如何將您引導至可以使用的比特幣錢包地址。
橢圓曲線密碼學 (Elliptic Curve Cryptography)
The first thing we need to do is to apply the ECDSA or Elliptic Curve Digital Signature Algorithm to our private key. An elliptic curve is a curve defined by the equation y2 = x3 + ax + b with a chosen a and b. There is a whole family of such curves that are widely known and used. Bitcoin uses the secp256k1 curve. If you want to learn more about Elliptic Curve Cryptography, I’ll refer you to this article.
我們需要做的第一件事是將ECDSA或橢圓曲線數字簽名算法應用于我們的私鑰。 橢圓曲線是由等式y2 = x3 + ax + b定義的曲線,其中a和b被選擇。 此類曲線有一個完整的家族,已廣為人知和使用。 比特幣使用secp256k1曲線。 如果您想了解有關橢圓曲線密碼學的更多信息,請參考本文 。
By applying the ECDSA to the private key, we get a 64-byte integer. This consists of two 32-byte integers that represent the X and Y of the point on the elliptic curve, concatenated together.
通過將ECDSA應用于私鑰,我們得到一個64字節的整數。 它由兩個32個字節的整數組成,它們分別代表橢圓曲線上該點的X和Y。
For our example, we got: 1e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7b73ff919898c836396a6b0c96812c3213b99372050853bd1678da0ead14487d7.
對于我們的示例,我們得到: 1e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7b73ff919898c836396a6b0c96812c3213b99372050853bd1678da0ead14487d7 。
In Python, it would look like this:
在Python中,它看起來像這樣:
public_key_bytes = codecs.decode(public_key, ‘hex’) # Run SHA-256 for the public key sha256_bpk = hashlib.sha256(public_key_bytes) sha256_bpk_digest = sha256_bpk.digest() # Run RIPEMD-160 for the SHA-256 ripemd160_bpk = hashlib.new(‘ripemd160’) ripemd160_bpk.update(sha256_bpk_digest) ripemd160_bpk_digest = ripemd160_bpk.digest() ripemd160_bpk_hex = codecs.encode(ripemd160_bpk_digest, ‘hex’)Note: as you can see from the code, before I used a method from the ecdsa module, I decoded the private key using codecs. This is relevant more to the Python and less to the algorithm itself, but I will explain what are we doing here to remove possible confusion.
注意:從代碼中可以看到,在使用ecdsa模塊中的方法之前,我先使用codecs解碼了私鑰。 這與Python無關,而與算法本身無關,但我將在此說明我們在做什么以消除可能的混淆。
In Python, there are at least two classes that can keep the private and public keys: “str” and “bytes”. The first is a string and the second is a byte array. Cryptographic methods in Python work with a “bytes” class, taking it as input and returning it as the result.
在Python中,至少有兩個可以保留私鑰和公鑰的類:“ str”和“ bytes”。 第一個是字符串,第二個是字節數組。 Python中的加密方法與“ bytes”類一起使用,將其作為輸入并作為結果返回。
Now, there’s a little catch: a string, say, 4f3c does not equal the byte array 4f3c, it equals the byte array with two elements, O<. And that’s what codecs.decode method does: it converts a string into a byte array. That will be the same for all cryptographic manipulations that we’ll do in this article.
現在,有一個小問題:一個字符串,例如4f3c不等于字節數組4f3c ,它等于具有兩個元素O& lt;的字節數組。 這就是at codecs.dec ode方法的作用:它將字符串轉換為字節數組。 對于本文中將進行的所有加密操作,這都是相同的。
公鑰 (Public key)
Once we’re done with the ECDSA, all we need to do is to add the bytes 0x04 at the start of our public key. The result is a Bitcoin full public key, which is equal to: 041e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7b73ff919898c836396a6b0c96812c3213b99372050853bd1678da0ead14487d7 for us.
一旦完成ECDSA,我們要做的就是在公共密鑰的開頭添加字節0x04 。 結果是一個比特幣完整的公共密鑰,它等于: 041e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7b73ff919898c836396a6b0c96812c3213b99372050853bd1678da0ead14487d7 。
壓縮的公鑰 (Compressed public key)
But we can do better. As you might remember, the public key is some point (X, Y) on the curve. We know the curve, and for each X there are only two Ys that define the point which lies on that curve. So why keep Y? Instead, let’s keep X and the sign of Y. Later, we can derive Y from that if needed.
但是我們可以做得更好。 您可能還記得,公鑰是曲線上的某個點(X,Y)。 我們知道曲線,對于每個X,只有兩個Y定義該曲線上的點。 那為什么要保留Y呢? 相反,讓我們保留X和Y的符號。稍后,如果需要,我們可以從中得出Y。
The specifics are as follows: we take X from the ECDSA public key. Now, we add the 0x02 if the last byte of Y is even, and the byte 0x03 if the last byte is odd.
具體如下:我們從ECDSA公鑰中獲取X。 現在,如果Y的最后一個字節為偶數,則添加0x02如果最后一個字節為奇數,則添加字節0x03 。
In our case, the last byte is odd, so we add 0x03 to get the compressed public key: 031e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7. This key contains the same information, but it’s almost twice as short as the uncompressed key. Cool!
在我們的例子中,最后一個字節為奇數,因此我們添加0x03以獲得壓縮的公共密鑰: 031e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7 。 該密鑰包含相同的信息,但幾乎是未壓縮密鑰的兩倍。 涼!
Previously, wallet software used long, full versions of public keys, but now most of it has switched to compressed keys.
以前,錢包軟件使用的是完整完整版的公共密鑰,但現在大多數軟件已切換為壓縮密鑰。
加密公鑰 (Encrypting the public key)
From now on, we need to make a wallet address. Whatever method of getting the public key you choose, it goes through the same procedure. Obviously, the addresses will differ. In this article, we will go with the compressed version.
從現在開始,我們需要創建一個錢包地址。 不管選擇哪種獲取公鑰的方法,都要經過相同的過程。 顯然,地址會有所不同。 在本文中,我們將使用壓縮版本。
What we need to do here is to apply SHA-256 to the public key, and then apply RIPEMD-160 to the result. The order is important.
我們需要在此處將SHA-256應用于公鑰,然后將RIPEMD-160應用于結果。 順序很重要。
SHA-256 and RIPEMD-160 are two hash functions, and again, we won’t go into the details of how they work. What matters is that now we have 160-bit integer, which will be used for further modifications. Let’s call that an encrypted public key. For our example, the encrypted public key is 453233600a96384bb8d73d400984117ac84d7e8b.
SHA-256和RIPEMD-160是兩個哈希函數,同樣,我們將不介紹它們如何工作的細節。 重要的是,現在我們有160位整數,將用于進一步修改。 我們稱其為加密的公共密鑰。 對于我們的示例,加密的公共密鑰為453233600a96384bb8d73d400984117ac84d7e8b 。
Here’s how we encrypt the public key in Python:
這是我們在Python中加密公鑰的方式:
public_key_bytes = codecs.decode(public_key, ‘hex’)# Run SHA-256 for the public keysha256_bpk = hashlib.sha256(public_key_bytes)sha256_bpk_digest = sha256_bpk.digest()# Run RIPEMD-160 for the SHA-256ripemd160_bpk = hashlib.new(‘ripemd160’)ripemd160_bpk.update(sha256_bpk_digest)ripemd160_bpk_digest = ripemd160_bpk.digest()ripemd160_bpk_hex = codecs.encode(ripemd160_bpk_digest, ‘hex’)添加網絡字節 (Adding the network byte)
The Bitcoin has two networks, main and test. The main network is the network that all people use to transfer the coins. The test network was created — you guessed it — to test new features and software.
比特幣有兩個網絡,主要網絡和測試網絡。 主要網絡是所有人用來轉移硬幣的網絡。 創建了測試網絡(您猜對了),以測試新功能和軟件。
We want to generate an address to use it on the mainnet, so we need to add 0x00 bytes to the encrypted public key. The result is 00453233600a96384bb8d73d400984117ac84d7e8b. For the testnet, that would be 0x6f bytes.
我們想要生成一個地址以在主網上使用,因此我們需要向加密的公共密鑰添加0x00字節。 結果是00453233600a96384bb8d73d400984117ac84d7e8b 。 對于測試網,這將是0x6f字節。
校驗和 (Checksum)
Now we need to calculate the checksum of our mainnet key. The idea of checksum is to make sure that the data (in our case, the key) wasn’t corrupted during transmission. The wallet software should look at the checksum and mark the address as invalid if the checksum mismatches.
現在我們需要計算主網密鑰的校驗和。 校驗和的思想是確保數據(在我們的例子中是密鑰)在傳輸過程中沒有被破壞。 錢包軟件應查看校驗和,如果校驗和不匹配,則將地址標記為無效。
To calculate the checksum of the key, we need to apply SHA-256 twice and then take first 4 bytes of the result. For our example, the double SHA-256 is 512f43c48517a75e58a7ec4c554ecd1a8f9603c891b46325006abf39c5c6b995 and therefore the checksum is 512f43c4 (note that 4 bytes is 8 hex digits).
要計算密鑰的校驗和,我們需要兩次應用SHA-256,然后取結果的前4個字節。 對于我們的示例,雙SHA-256為512f43c48517a75e58a7ec4c554ecd1a8f9603c891b46325006abf39c5c6b995 ,因此校驗和為512f43c4 (請注意,4個字節為8個十六進制數字)。
The code to calculate an address checksum is the following:
計算地址校驗和的代碼如下:
# Double SHA256 to get checksum sha256_nbpk = hashlib.sha256(network_bitcoin_public_key_bytes) sha256_nbpk_digest = sha256_nbpk.digest() sha256_2_nbpk = hashlib.sha256(sha256_nbpk_digest) sha256_2_nbpk_digest = sha256_2_nbpk.digest() sha256_2_hex = codecs.encode(sha256_2_nbpk_digest, ‘hex’) checksum = sha256_2_hex[:8]取得地址 (Getting the address)
Finally, to make an address, we just concatenate the mainnet key and the checksum. That makes it 00453233600a96384bb8d73d400984117ac84d7e8b512f43c4 for our example.
最后,要創建一個地址,我們只需將主網密鑰和校驗和連接在一起。 在我們的示例中,使其為00453233600a96384bb8d73d400984117ac84d7e8b512f43c4 。
That’s it! That’s the wallet address for the private key at the start of the article.
而已! 那是文章開頭的私鑰的錢包地址。
But you may notice that something is off. You’ve probably seen a handful of Bitcoin addresses and they didn’t look like that. Well, the reason is that they are encoded with Base58. It’s a little bit odd.
但是您可能會注意到有些問題。 您可能已經看到了少數比特幣地址,但它們看起來并非如此。 好吧,原因是它們是使用Base58編碼的。 有點奇怪。
Here’s the algorithm to convert a hex address to the Base58 address:
這是將十六進制地址轉換為Base58地址的算法:
def base58(address_hex):alphabet = ‘123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz’b58_string = ‘’# Get the number of leading zerosleading_zeros = len(address_hex) — len(address_hex.lstrip(‘0’))# Convert hex to decimaladdress_int = int(address_hex, 16)# Append digits to the start of stringwhile address_int > 0:digit = address_int % 58digit_char = alphabet[digit]b58_string = digit_char + b58_stringaddress_int //= 58# Add ‘1’ for each 2 leading zerosones = leading_zeros // 2for one in range(ones):b58_string = ‘1’ + b58_stringreturn b58_stringWhat we get is 17JsmEygbbEUEpvt4PFtYaTeSqfb9ki1F1, a compressed Bitcoin wallet address.
我們得到的是17JsmEygbbEUEpvt4PFtYaTeSqfb9ki1F1 ,這是一個壓縮的比特幣錢包地址。
結論 (Conclusion)
The wallet key generation process can be split into four steps:
錢包密鑰生成過程可以分為四個步驟:
- creating a public key with ECDSA 使用ECDSA創建公鑰
- encrypting the key with SHA-256 and RIPEMD-160 使用SHA-256和RIPEMD-160加密密鑰
- calculating the checksum with double SHA-256 用雙SHA-256計算校驗和
- encoding the key with Base58. 使用Base58對密鑰進行編碼。
Depending on the form of public key (full or compressed), we get different addresses, but both are perfectly valid.
根據公鑰的形式(完整或壓縮),我們獲得不同的地址,但兩者都是完全有效的。
Here’s the full algorithm for the uncompressed public key:
這是未壓縮公鑰的完整算法:
If you want to play with the code, I published it to the Github repository.
如果您想使用這些代碼,我將其發布到了Github倉庫 。
I am making a course on cryptocurrencies here on freeCodeCamp News. The first part is a detailed description of the blockchain.
我正在freeCodeCamp News上開設有關加密貨幣的課程。 第一部分是對區塊鏈的詳細描述。
I also post random thoughts about crypto on Twitter, so you might want to check it out.
我還在Twitter上發布了關于加密的隨機想法,因此您可能需要檢查一下。
翻譯自: https://www.freecodecamp.org/news/how-to-create-a-bitcoin-wallet-address-from-a-private-key-eca3ddd9c05f/
比特幣錢包私鑰
總結
以上是生活随笔為你收集整理的比特币钱包私钥_如何通过私钥创建比特币钱包地址的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 回复邮件时如何不要邮件头_如何为阅读,点
- 下一篇: 梦到棺材打什么奖