Browse Source

Better handle base58 version bytes and allow for a >1 byte version

master
John L. Jegutanis 8 years ago
committed by Neil Booth
parent
commit
6b1b9d01f2
  1. 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…
Cancel
Save