Better handle base58 version bytes and allow for a >1 byte version
This commit is contained in:
parent
b3005fbb3e
commit
6b1b9d01f2
132
lib/coins.py
132
lib/coins.py
@ -1,4 +1,5 @@
|
||||
# Copyright (c) 2016-2017, Neil Booth
|
||||
# Copyright (c) 2017, the ElectrumX authors
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
@ -29,18 +30,15 @@ Anything coin-specific should go in this file and be subclassed where
|
||||
necessary for appropriate handling.
|
||||
'''
|
||||
|
||||
from decimal import Decimal
|
||||
from functools import partial
|
||||
from hashlib import sha256
|
||||
import inspect
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
from decimal import Decimal
|
||||
from hashlib import sha256
|
||||
|
||||
from lib.hash import Base58, hash160, ripemd160, double_sha256, hash_to_str
|
||||
import lib.util as util
|
||||
from lib.hash import Base58, hash160, double_sha256, hash_to_str
|
||||
from lib.script import ScriptPubKey
|
||||
from lib.tx import Deserializer, DeserializerSegWit
|
||||
import lib.util as util
|
||||
|
||||
|
||||
class CoinError(Exception):
|
||||
@ -156,7 +154,7 @@ class Coin(object):
|
||||
def P2PKH_address_from_hash160(cls, hash160):
|
||||
'''Return a P2PKH address given a public key.'''
|
||||
assert len(hash160) == 20
|
||||
return Base58.encode_check(bytes([cls.P2PKH_VERBYTE]) + hash160)
|
||||
return Base58.encode_check(cls.P2PKH_VERBYTE + hash160)
|
||||
|
||||
@classmethod
|
||||
def P2PKH_address_from_pubkey(cls, pubkey):
|
||||
@ -167,7 +165,7 @@ class Coin(object):
|
||||
def P2SH_address_from_hash160(cls, hash160):
|
||||
'''Return a coin address given a hash160.'''
|
||||
assert len(hash160) == 20
|
||||
return Base58.encode_check(bytes([cls.P2SH_VERBYTE]) + hash160)
|
||||
return Base58.encode_check(cls.P2SH_VERBYTE + hash160)
|
||||
|
||||
@classmethod
|
||||
def multisig_address(cls, m, pubkeys):
|
||||
@ -202,10 +200,11 @@ class Coin(object):
|
||||
'''
|
||||
raw = Base58.decode_check(address)
|
||||
|
||||
# Require version byte plus hash160.
|
||||
# Require version byte(s) plus hash160.
|
||||
verbyte = -1
|
||||
if len(raw) == 21:
|
||||
verbyte, hash_bytes = raw[0], raw[1:]
|
||||
verlen = len(raw) - 20
|
||||
if verlen > 0:
|
||||
verbyte, hash_bytes = raw[0:verlen], raw[verlen:]
|
||||
|
||||
if verbyte == cls.P2PKH_VERBYTE:
|
||||
return ScriptPubKey.P2PKH_script(hash_bytes)
|
||||
@ -215,9 +214,9 @@ class Coin(object):
|
||||
raise CoinError('invalid address: {}'.format(address))
|
||||
|
||||
@classmethod
|
||||
def prvkey_WIF(privkey_bytes, compressed):
|
||||
def prvkey_WIF(cls, privkey_bytes, compressed):
|
||||
'''Return the private key encoded in Wallet Import Format.'''
|
||||
payload = bytearray([cls.WIF_BYTE]) + privkey_bytes
|
||||
payload = bytearray(cls.WIF_BYTE) + privkey_bytes
|
||||
if compressed:
|
||||
payload.append(0x01)
|
||||
return Base58.encode_check(payload)
|
||||
@ -292,9 +291,9 @@ class Bitcoin(Coin):
|
||||
NET = "mainnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("0488b21e")
|
||||
XPRV_VERBYTES = bytes.fromhex("0488ade4")
|
||||
P2PKH_VERBYTE = 0x00
|
||||
P2SH_VERBYTE = 0x05
|
||||
WIF_BYTE = 0x80
|
||||
P2PKH_VERBYTE = bytes.fromhex("00")
|
||||
P2SH_VERBYTE = bytes.fromhex("05"),
|
||||
WIF_BYTE = bytes.fromhex("80")
|
||||
GENESIS_HASH = ('000000000019d6689c085ae165831e93'
|
||||
'4ff763ae46a2a6c172b3f1b60a8ce26f')
|
||||
TX_COUNT = 156335304
|
||||
@ -328,9 +327,9 @@ class BitcoinTestnet(Bitcoin):
|
||||
IRC_PREFIX = None
|
||||
XPUB_VERBYTES = bytes.fromhex("043587cf")
|
||||
XPRV_VERBYTES = bytes.fromhex("04358394")
|
||||
P2PKH_VERBYTE = 0x6f
|
||||
P2SH_VERBYTE = 0xc4
|
||||
WIF_BYTE = 0xef
|
||||
P2PKH_VERBYTE = bytes.fromhex("6f")
|
||||
P2SH_VERBYTE = bytes.fromhex("c4"),
|
||||
WIF_BYTE = bytes.fromhex("ef")
|
||||
GENESIS_HASH = ('000000000933ea01ad0ee984209779ba'
|
||||
'aec3ced90fa3f408719526f8d77f4943')
|
||||
REORG_LIMIT = 2000
|
||||
@ -370,9 +369,9 @@ class Litecoin(Coin):
|
||||
NET = "mainnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("019da462")
|
||||
XPRV_VERBYTES = bytes.fromhex("019d9cfe")
|
||||
P2PKH_VERBYTE = 0x30
|
||||
P2SH_VERBYTE = 0x05
|
||||
WIF_BYTE = 0xb0
|
||||
P2PKH_VERBYTE = bytes.fromhex("30")
|
||||
P2SH_VERBYTE = bytes.fromhex("05"),
|
||||
WIF_BYTE = bytes.fromhex("b0")
|
||||
GENESIS_HASH = ('12a765e31ffd4059bada1e25190f6e98'
|
||||
'c99d9714d334efa41a195a7e7e04bfe2')
|
||||
TX_COUNT = 8908766
|
||||
@ -381,6 +380,7 @@ class Litecoin(Coin):
|
||||
IRC_PREFIX = "EL_"
|
||||
IRC_CHANNEL = "#electrum-ltc"
|
||||
RPC_PORT = 9332
|
||||
REORG_LIMIT = 800
|
||||
|
||||
|
||||
class LitecoinTestnet(Litecoin):
|
||||
@ -388,9 +388,9 @@ class LitecoinTestnet(Litecoin):
|
||||
NET = "testnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("0436f6e1")
|
||||
XPRV_VERBYTES = bytes.fromhex("0436ef7d")
|
||||
P2PKH_VERBYTE = 0x6f
|
||||
P2SH_VERBYTE = 0xc4
|
||||
WIF_BYTE = 0xef
|
||||
P2PKH_VERBYTE = bytes.fromhex("6f")
|
||||
P2SH_VERBYTE = bytes.fromhex("c4"),
|
||||
WIF_BYTE = bytes.fromhex("ef")
|
||||
GENESIS_HASH = ('f5ae71e26c74beacc88382716aced69c'
|
||||
'ddf3dffff24f384e1808905e0188f68f')
|
||||
|
||||
@ -402,11 +402,16 @@ class Namecoin(Coin):
|
||||
NET = "mainnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("d7dd6370")
|
||||
XPRV_VERBYTES = bytes.fromhex("d7dc6e31")
|
||||
P2PKH_VERBYTE = 0x34
|
||||
P2SH_VERBYTE = 0x0d
|
||||
WIF_BYTE = 0xe4
|
||||
P2PKH_VERBYTE = bytes.fromhex("34")
|
||||
P2SH_VERBYTE = bytes.fromhex("0d"),
|
||||
WIF_BYTE = bytes.fromhex("e4")
|
||||
GENESIS_HASH = ('000000000062b72c5e2ceb45fbc8587e'
|
||||
'807c155b0da735e6483dfba2f0a9c770')
|
||||
TX_COUNT = 4415768
|
||||
TX_COUNT_HEIGHT = 329065
|
||||
TX_PER_BLOCK = 10
|
||||
IRC_PREFIX = "E_"
|
||||
IRC_CHANNEL = "#electrum-nmc"
|
||||
|
||||
|
||||
class NamecoinTestnet(Namecoin):
|
||||
@ -415,10 +420,11 @@ class NamecoinTestnet(Namecoin):
|
||||
NET = "testnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("043587cf")
|
||||
XPRV_VERBYTES = bytes.fromhex("04358394")
|
||||
P2PKH_VERBYTE = 0x6f
|
||||
P2SH_VERBYTE = 0xc4
|
||||
WIF_BYTE = 0xef
|
||||
# TODO add GENESIS_HASH
|
||||
P2PKH_VERBYTE = bytes.fromhex("6f")
|
||||
P2SH_VERBYTE = bytes.fromhex("c4"),
|
||||
WIF_BYTE = bytes.fromhex("ef")
|
||||
GENESIS_HASH = ('00000007199508e34a9ff81e6ec0c477'
|
||||
'a4cccff2a4767a8eee39c11db367b008')
|
||||
|
||||
|
||||
# For DOGE there is disagreement across sites like bip32.org and
|
||||
@ -429,11 +435,17 @@ class Dogecoin(Coin):
|
||||
NET = "mainnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("02facafd")
|
||||
XPRV_VERBYTES = bytes.fromhex("02fac398")
|
||||
P2PKH_VERBYTE = 0x1e
|
||||
P2SH_VERBYTE = 0x16
|
||||
WIF_BYTE = 0x9e
|
||||
P2PKH_VERBYTE = bytes.fromhex("1e")
|
||||
P2SH_VERBYTE = bytes.fromhex("16"),
|
||||
WIF_BYTE = bytes.fromhex("9e")
|
||||
GENESIS_HASH = ('1a91e3dace36e2be3bf030a65679fe82'
|
||||
'1aa1d6ef92e7c9902eb318182c355691')
|
||||
TX_COUNT = 27583427
|
||||
TX_COUNT_HEIGHT = 1604979
|
||||
TX_PER_BLOCK = 20
|
||||
IRC_PREFIX = "E_"
|
||||
IRC_CHANNEL = "#electrum-doge"
|
||||
REORG_LIMIT = 2000
|
||||
|
||||
|
||||
class DogecoinTestnet(Dogecoin):
|
||||
@ -442,9 +454,9 @@ class DogecoinTestnet(Dogecoin):
|
||||
NET = "testnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("0432a9a8")
|
||||
XPRV_VERBYTES = bytes.fromhex("0432a243")
|
||||
P2PKH_VERBYTE = 0x71
|
||||
P2SH_VERBYTE = 0xc4
|
||||
WIF_BYTE = 0xf1
|
||||
P2PKH_VERBYTE = bytes.fromhex("71")
|
||||
P2SH_VERBYTE = bytes.fromhex("c4"),
|
||||
WIF_BYTE = bytes.fromhex("f1")
|
||||
GENESIS_HASH = ('bb0a78264637406b6360aad926284d54'
|
||||
'4d7049f45189db5664f3c4d07350559e')
|
||||
|
||||
@ -458,9 +470,9 @@ class Dash(Coin):
|
||||
XPRV_VERBYTES = bytes.fromhex("02fe52f8")
|
||||
GENESIS_HASH = ('00000ffd590b1485b3caadc19b22e637'
|
||||
'9c733355108f107a430458cdf3407ab6')
|
||||
P2PKH_VERBYTE = 0x4c
|
||||
P2SH_VERBYTE = 0x10
|
||||
WIF_BYTE = 0xcc
|
||||
P2PKH_VERBYTE = bytes.fromhex("4c")
|
||||
P2SH_VERBYTE = bytes.fromhex("10"),
|
||||
WIF_BYTE = bytes.fromhex("cc")
|
||||
TX_COUNT_HEIGHT = 569399
|
||||
TX_COUNT = 2157510
|
||||
TX_PER_BLOCK = 4
|
||||
@ -490,9 +502,9 @@ class DashTestnet(Dash):
|
||||
XPRV_VERBYTES = bytes.fromhex("3a8061a0")
|
||||
GENESIS_HASH = ('00000bafbc94add76cb75e2ec9289483'
|
||||
'7288a481e5c005f6563d91623bf8bc2c')
|
||||
P2PKH_VERBYTE = 0x8c
|
||||
P2SH_VERBYTE = 0x13
|
||||
WIF_BYTE = 0xef
|
||||
P2PKH_VERBYTE = bytes.fromhex("8c")
|
||||
P2SH_VERBYTE = bytes.fromhex("13"),
|
||||
WIF_BYTE = bytes.fromhex("ef")
|
||||
TX_COUNT_HEIGHT = 101619
|
||||
TX_COUNT = 132681
|
||||
TX_PER_BLOCK = 1
|
||||
@ -510,9 +522,9 @@ class Argentum(Coin):
|
||||
NET = "mainnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("0488b21e")
|
||||
XPRV_VERBYTES = bytes.fromhex("0488ade4")
|
||||
P2PKH_VERBYTE = 0x17
|
||||
P2SH_VERBYTE = 0x05
|
||||
WIF_BYTE = 0x97
|
||||
P2PKH_VERBYTE = bytes.fromhex("17")
|
||||
P2SH_VERBYTE = bytes.fromhex("05"),
|
||||
WIF_BYTE = bytes.fromhex("97")
|
||||
GENESIS_HASH = ('88c667bc63167685e4e4da058fffdfe8'
|
||||
'e007e5abffd6855de52ad59df7bb0bb2')
|
||||
TX_COUNT = 2263089
|
||||
@ -528,9 +540,9 @@ class ArgentumTestnet(Argentum):
|
||||
NET = "testnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("043587cf")
|
||||
XPRV_VERBYTES = bytes.fromhex("04358394")
|
||||
P2PKH_VERBYTE = 0x6f
|
||||
P2SH_VERBYTE = 0xc4
|
||||
WIF_BYTE = 0xef
|
||||
P2PKH_VERBYTE = bytes.fromhex("6f")
|
||||
P2SH_VERBYTE = bytes.fromhex("c4"),
|
||||
WIF_BYTE = bytes.fromhex("ef")
|
||||
REORG_LIMIT = 2000
|
||||
|
||||
|
||||
@ -540,9 +552,9 @@ class DigiByte(Coin):
|
||||
NET = "mainnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("0488b21e")
|
||||
XPRV_VERBYTES = bytes.fromhex("0488ade4")
|
||||
P2PKH_VERBYTE = 0x1E
|
||||
P2SH_VERBYTE = 0x05
|
||||
WIF_BYTE = 0x80
|
||||
P2PKH_VERBYTE = bytes.fromhex("1E")
|
||||
P2SH_VERBYTE = bytes.fromhex("05"),
|
||||
WIF_BYTE = bytes.fromhex("80")
|
||||
GENESIS_HASH = ('7497ea1b465eb39f1c8f507bc877078f'
|
||||
'e016d6fcb6dfad3a64c98dcc6e1e8496')
|
||||
TX_COUNT = 1046018
|
||||
@ -557,9 +569,9 @@ class DigiByteTestnet(DigiByte):
|
||||
NET = "testnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("043587cf")
|
||||
XPRV_VERBYTES = bytes.fromhex("04358394")
|
||||
P2PKH_VERBYTE = 0x6f
|
||||
P2SH_VERBYTE = 0xc4
|
||||
WIF_BYTE = 0xef
|
||||
P2PKH_VERBYTE = bytes.fromhex("6f")
|
||||
P2SH_VERBYTE = bytes.fromhex("c4"),
|
||||
WIF_BYTE = bytes.fromhex("ef")
|
||||
GENESIS_HASH = ('b5dca8039e300198e5fe7cd23bdd1728'
|
||||
'e2a444af34c447dbd0916fa3430a68c2')
|
||||
IRC_PREFIX = "DET_"
|
||||
@ -574,9 +586,9 @@ class FairCoin(Coin):
|
||||
NET = "mainnet"
|
||||
XPUB_VERBYTES = bytes.fromhex("0488b21e")
|
||||
XPRV_VERBYTES = bytes.fromhex("0488ade4")
|
||||
P2PKH_VERBYTE = 0x5f
|
||||
P2SH_VERBYTE = 0x24
|
||||
WIF_BYTE = 0xdf
|
||||
P2PKH_VERBYTE = bytes.fromhex("5f")
|
||||
P2SH_VERBYTE = bytes.fromhex("24"),
|
||||
WIF_BYTE = bytes.fromhex("df")
|
||||
GENESIS_HASH=('1f701f2b8de1339dc0ec908f3fb6e9b0'
|
||||
'b870b6f20ba893e120427e42bbc048d7')
|
||||
TX_COUNT = 1000
|
||||
|
||||
Loading…
Reference in New Issue
Block a user