Altcoin
我想為 Namecoin 和其他山寨幣生成 BIP32 版本號
我想為 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 >>= 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 << b256_digit_count*8) - 1 max_base58_str = int_to_base58_str((min_int << 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: {} <STRING-TO-PREPEND> <DATA-BYTE-LEN (excluding 4-byte checksum)>'.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))