Altcoin

我想為 Namecoin 和其他山寨幣生成 BIP32 版本號

  • July 20, 2019

我想為 Namecoin 和其他山寨幣製作一個 BIP32 錢包。我只需要弄清楚如何生成一個公共和私人版本號,以便 BIP32 擴展密鑰前綴是有意義的,例如 Namecoin 私鑰的“nprv”和公鑰的“npub”。

一直在努力解決這個問題

我無法真正告訴您如何生成它們,但為了部分回答您的問題,這裡列出了已知的比特幣和山寨幣前綴,包括萊特幣和暗幣:

EXT_SECRET_KEY, EXT_PUBLIC_KEY # Network                 : Prefixes
----------------------------------------------------------------------
0x0488ADE4,     0x0488B21E     # BTC  Bitcoin    mainnet : xprv / xpub
0x04358394,     0x043587CF     # BTC  Bitcoin    testnet : tprv / tpub
0x019D9CFE,     0x019DA462     # LTC  Litecoin   mainnet : Ltpv / Ltub
0x0436EF7D,     0x0436F6E1     # LTC  Litecoin   testnet : ttpv / ttub
0x02FE52F8,     0x02FE52CC     # DRK  Darkcoin   mainnet : drkv / drkp
0x3A8061A0,     0x3A805837     # DRK  Darkcoin   testnet : DRKV / DRKP
0x0488ADE4,     0x0488B21E     # VIA  Viacoin    mainnet : xprv / xpub
0x04358394,     0x043587CF     # VIA  Viacoin    testnet : tprv / tpub
0x02FAC398,     0x02FACAFD     # DOGE Dogecoin   mainnet : dgpv / dgub
0x0488ADE4,     0x0488B21E     # VTC  Vertcoin   mainnet : vtcv / vtcp
0x02CFBF60,     0x02CFBEDE     # BC   Blackcoin  mainnet : bcpv / bcpb
0x03A04DB7,     0x03A04D8B     # MEC  Megacoin   mainnet : mecv / mecp
0x0488ADE4,     0x0488B21E     # MYR  Myriadcoin mainnet : myrv / myrp
0x0488ADE4,     0x0488B21E     # UNO  Unobtanium mainnet : unov / unop
0x037A6460,     0x037A689A     # JBS  Jumbucks   mainnet : jprv / jpub
0x0488ADE4,     0x0488B21E     # MZC  Mazacoin   mainnet : xprv / xpub

我從支持 HD 錢包的 pycoin api 實現中獲取它們。 <https://github.com/richardkiss/pycoin/blob/master/pycoin/networks.py>

我意識到這是一個相當老的問題,但我想我還是會回答的。

xpub/xprv/等。字元串只是用 base-58 表示的大數字,而不是我們都熟悉的 base-10。如果我們想取一個“普通”的 5 位數字並889在前面加上,比如說,我們只需添加88900000到 5 位數字:

    12345
+ 88900000
----------
 88912345

在 base-58 中工作本質上是相同的,但總是魔鬼在細節中,因為我們必須從一個大的 base-58 數字轉換為一個大的 base-256 數字(字節數組的“基數”,即我們正在尋找什麼)。

下面是一個可以從命令行執行的 Python 3 腳本,例如將字元串xpub添加到 74 個字節的數據(BIP32 擴展密鑰的長度,不包括 4 個尾隨檢查字節),在 base 之前添加的字節-58 編碼是:

$ python3 prepend_bytes.py xpub 74
0x04, 0x88, 0xb2, 0x1e

#!/usr/bin/env python3

from math import log, ceil
import sys


# lookup tables to convert integers in the range [0, 58) to base-58 digits and back
int_to_b58_digit = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
b58_digit_to_int = { b58:i for i,b58 in enumerate(int_to_b58_digit) }

# convert a (long) integer to its base-58 representation string
def int_to_base58_str(int_rep):
   base58_str = ''
   while int_rep:
       int_rep, remainder = divmod(int_rep, 58)
       base58_str = int_to_b58_digit[remainder] + base58_str
   return base58_str


def prepended_bytes(prepended_b58_digits, b256_digit_count):

   # ones are a special case in base58check format;
   # count and remove them, they are added back in later
   ones = 0
   for b58 in prepended_b58_digits:
       if b58 != '1':
           break
       ones += 1
       prepended_b58_digits = prepended_b58_digits[1:]
   if not prepended_b58_digits:  # if they're all 1's
       return ones * b'\0'

   # calc the # of base58 digits required for b256_digit_count bytes of "real" data
   # (not including the prepended base58 digits)
   b58_digit_count = ceil(b256_digit_count * log(256) / log(58))

   do_overflow_check = True
   while True:
       # calc the minimum integral value which starts with the desired digits in base-58
       min_int = 0
       for b58 in prepended_b58_digits:
           min_int *= 58
           min_int += b58_digit_to_int[b58]
       #
       # left-shift (mult. by a power of 58) to be just left of the "real" base-58 data
       min_int *= 58 ** b58_digit_count

       # uncomment to sanity-check that min_int is correct
       #print(" min_int:", ones * '1' + int_to_base58_str(min_int))

       # right-shift by multiples of 8 bits (base-256) to retrieve only the
       # most-significant bytes which are to the left of the "real" base-256 data
       min_int &gt;&gt;= b256_digit_count * 8
       # right-shifing effectively rounds min_int down, but we
       # need it rounded up, so add one to round it up instead
       min_int += 1

       # because min_int has been rounded up above, it's possible that adding it to "real"
       # data could cause an overflow in base-58 making the prepended_b58_digits increment
       # by one; if this could happen, left-shift prepended_b58_digits and repeat
       if do_overflow_check:
           max_real_data_int = (1 &lt;&lt; b256_digit_count*8) - 1
           max_base58_str = int_to_base58_str((min_int &lt;&lt; b256_digit_count*8) + max_real_data_int)
           if not max_base58_str.startswith(prepended_b58_digits):
               prepended_b58_digits += '1'
               do_overflow_check = False  # it doesn't matter if the '1' appended above overflows to '2'

               # uncomment to confirm that the max possible value
               # wouldn't have the desired prepended base-58 digits
               #print("overflow:", ones * '1' + max_base58_str)

               continue

       # prepend any ones according to base58check rules, and convert min_int to a byte string
       return ones * b'\0' + min_int.to_bytes(length= (min_int.bit_length() + 7) // 8, byteorder='big')


if __name__ == '__main__':
   if len(sys.argv) != 3:
       sys.exit('usage: {} &lt;STRING-TO-PREPEND&gt; &lt;DATA-BYTE-LEN (excluding 4-byte checksum)&gt;'.format(sys.argv[0]))

   result = prepended_bytes(sys.argv[1], int(sys.argv[2]) + 4)  # add 4 for the checksum
   print(', '.join('{:#04x}'.format(i) for i in result))

引用自:https://bitcoin.stackexchange.com/questions/28380