Browse Source

Add TokenPay (#495)

This commit adds TokenPay as a supported coin.
patch-2
Gabriel 7 years ago
committed by Neil
parent
commit
3a33675e11
  1. 1
      .travis.yml
  2. 25
      electrumx/lib/coins.py
  3. 69
      electrumx/lib/tx.py
  4. 28
      tests/blocks/tokenpay_mainnet_20000.json
  5. 4
      tests/lib/test_addresses.py
  6. 5
      tests/server/test_env.py

1
.travis.yml

@ -29,6 +29,7 @@ install:
# hashes # hashes
- pip install tribus-hash - pip install tribus-hash
- pip install blake256 - pip install blake256
- pip install scrypt
- pip install x11_hash - pip install x11_hash
- pip install xevan_hash - pip install xevan_hash
- pip install quark_hash - pip install quark_hash

25
electrumx/lib/coins.py

@ -1174,6 +1174,31 @@ class Reddcoin(Coin):
RPC_PORT = 45443 RPC_PORT = 45443
class TokenPay(ScryptMixin, Coin):
NAME = "TokenPay"
SHORTNAME = "TPAY"
NET = "mainnet"
P2PKH_VERBYTE = bytes.fromhex("41")
P2SH_VERBYTES = [bytes.fromhex("7e")]
WIF_BYTE = bytes.fromhex("b3")
GENESIS_HASH = ('000008b71ab32e585a23f0de642dc113'
'740144e94c0ece047751e9781f953ae9')
DESERIALIZER = lib_tx.DeserializerTokenPay
DAEMON = daemon.LegacyRPCDaemon
TX_COUNT = 147934
TX_COUNT_HEIGHT = 73967
TX_PER_BLOCK = 100
RPC_PORT = 8800
REORG_LIMIT = 500
XPUB_VERBYTES = bytes.fromhex("0488B21E")
XPRV_VERBYTES = bytes.fromhex("0488ADE4")
PEERS = [
"electrum-us.tpay.ai s",
"electrum-eu.tpay.ai s",
]
class Vertcoin(Coin): class Vertcoin(Coin):
NAME = "Vertcoin" NAME = "Vertcoin"
SHORTNAME = "VTC" SHORTNAME = "VTC"

69
electrumx/lib/tx.py

@ -30,6 +30,7 @@
from collections import namedtuple from collections import namedtuple
from electrumx.lib.hash import sha256, double_sha256, hash_to_hex_str from electrumx.lib.hash import sha256, double_sha256, hash_to_hex_str
from electrumx.lib.script import OpCodes
from electrumx.lib.util import ( from electrumx.lib.util import (
unpack_le_int32_from, unpack_le_int64_from, unpack_le_uint16_from, unpack_le_int32_from, unpack_le_int64_from, unpack_le_uint16_from,
unpack_le_uint32_from, unpack_le_uint64_from, pack_le_int32, pack_varint, unpack_le_uint32_from, unpack_le_uint64_from, pack_le_int32, pack_varint,
@ -422,6 +423,74 @@ class DeserializerGroestlcoin(DeserializerSegWit):
TX_HASH_FN = staticmethod(sha256) TX_HASH_FN = staticmethod(sha256)
class TxInputTokenPay(TxInput):
'''Class representing a TokenPay transaction input.'''
OP_ANON_MARKER = 0xb9
# 2byte marker (cpubkey + sigc + sigr)
MIN_ANON_IN_SIZE = 2 + (33 + 32 + 32)
def _is_anon_input(self):
return (len(self.script) >= self.MIN_ANON_IN_SIZE and
self.script[0] == OpCodes.OP_RETURN and
self.script[1] == self.OP_ANON_MARKER)
def is_generation(self):
# Transactions comming in from stealth addresses are seen by
# the blockchain as newly minted coins. The reverse, where coins
# are sent TO a stealth address, are seen by the blockchain as
# a coin burn.
if self._is_anon_input():
return True
return super(TxInputTokenPay, self).is_generation()
class TxInputTokenPayStealth(
namedtuple("TxInput", "keyimage ringsize script sequence")):
'''Class representing a TokenPay stealth transaction input.'''
def __str__(self):
script = self.script.hex()
keyimage = bytes(self.keyimage).hex()
return ("Input({}, {:d}, script={}, sequence={:d})"
.format(keyimage, self.ringsize[1], script, self.sequence))
def is_generation(self):
return True
def serialize(self):
return b''.join((
self.keyimage,
self.ringsize,
pack_varbytes(self.script),
pack_le_uint32(self.sequence),
))
class DeserializerTokenPay(DeserializerTxTime):
def _read_input(self):
txin = TxInputTokenPay(
self._read_nbytes(32), # prev_hash
self._read_le_uint32(), # prev_idx
self._read_varbytes(), # script
self._read_le_uint32(), # sequence
)
if txin._is_anon_input():
# Not sure if this is actually needed, and seems
# extra work for no immediate benefit, but it at
# least correctly represents a stealth input
raw = txin.serialize()
deserializer = Deserializer(raw)
txin = TxInputTokenPayStealth(
deserializer._read_nbytes(33), # keyimage
deserializer._read_nbytes(3), # ringsize
deserializer._read_varbytes(), # script
deserializer._read_le_uint32() # sequence
)
return txin
# Decred # Decred
class TxInputDcr(namedtuple("TxInput", "prev_hash prev_idx tree sequence")): class TxInputDcr(namedtuple("TxInput", "prev_hash prev_idx tree sequence")):
'''Class representing a Decred transaction input.''' '''Class representing a Decred transaction input.'''

28
tests/blocks/tokenpay_mainnet_20000.json

@ -0,0 +1,28 @@
{
"hash" : "a04c982af88368f934aada4c04a2907c204548b2f23b123104e5d5681318c58e",
"confirmations" : 223761,
"size" : 400,
"height" : 20000,
"version" : 6,
"merkleroot" : "9a15ca74bc6caf91be0517be05236a2c013993bbd9c0b28fd61dacbe66ff0edb",
"mint" : 0.06584667,
"time" : 1517342128,
"nonce" : 0,
"bits" : "1e00857c",
"difficulty" : 0.00749140,
"blocktrust" : "1eaf6bd",
"chaintrust" : "376cd8e0ac",
"previousblockhash" : "03e5e53d9edacc59720e22800f9f0230b7100abd1c2f388c64a2e0bd98df2710",
"nextblockhash" : "caff0ac56f5b367dc4f4da3d2b4a8848d4116079c353234ab2e0fe6f3f69ff82",
"flags" : "proof-of-stake",
"proofhash" : "000019d0fa709575179a07d46604f5d4efbf7bb02b5a1308b6a9f4410ba3328e",
"entropybit" : 0,
"modifier" : "1c5a2302bda4c0f3",
"modifierv2" : "5740fb0cc8bf2853ad258f16c363bbb92387cf85ac874ec553917c903ea70444",
"tx" : [
"d2e1100088af3e19976cac83f167ceffe725375442907d739341a40896d1089c",
"c24b1208937b6f634c0410cbc9ecf00a36837451ae27a85550b6af2a35b36f1f"
],
"signature" : "304402206d29ae84b3d1e6ac4cafefee9aaf8b96a5b2c1d60fa43f8805916db72e47e90502203aed70e4cf36ecd5f07d01087e8c7bc9b232825204116c6e2f77875ce0480f68",
"block": "060000001027df98bde0a2648c382f1cbd0a10b730029f0f80220e7259ccda9e3de5e503db0eff66beac1dd68fb2c0d9bb9339012c6a2305be1705be91af6cbc74ca159ab0cd705a7c85001e000000000201000000b0cd705a010000000000000000000000000000000000000000000000000000000000000000ffffffff0302204effffffff010000000000000000000000000001000000b0cd705a01ca1eea11a6379fbf3c61f18df79065e48aacd60c76c6694490cdf4ecae7c5edf01000000494830450221009bac3e0c4f6432abf7becca230eb69c5781d23a3d82a6c79457edd29fd0eb493022058de72c9ec4d51518f2d6538549aba819d9137e593beaad04aa9085a3043bf4901ffffffff020000000000000000002b0d0da529000000232103e9f972cb71e89a91c02e1512f36c7c92e4ed5f84fdbad3ac77e444e0a2f97cc4ac0000000046304402206d29ae84b3d1e6ac4cafefee9aaf8b96a5b2c1d60fa43f8805916db72e47e90502203aed70e4cf36ecd5f07d01087e8c7bc9b232825204116c6e2f77875ce0480f68"
}

4
tests/lib/test_addresses.py

@ -64,7 +64,9 @@ addresses = [
(coins.PivxTestnet, "yJ8iHtUxj9U4vsXLCZTbPNbuxG6NJNCvb8", (coins.PivxTestnet, "yJ8iHtUxj9U4vsXLCZTbPNbuxG6NJNCvb8",
"e808105b7bfcc8b102cafa7242089b22c77a3b94", "31d61c3076fa0b2b7c74ef"), "e808105b7bfcc8b102cafa7242089b22c77a3b94", "31d61c3076fa0b2b7c74ef"),
(coins.PivxTestnet, "yCcNWqqMhDmsPzKchCPK1ux4HpxK7j3xpB", (coins.PivxTestnet, "yCcNWqqMhDmsPzKchCPK1ux4HpxK7j3xpB",
"ab72728952c06dfc0f6cf21449dd645422731ec4", "eb3a3155215538d51de7cc") "ab72728952c06dfc0f6cf21449dd645422731ec4", "eb3a3155215538d51de7cc"),
(coins.TokenPay, "TDE2X28FGtckatxuP3d8s3V726G4TLNHpT",
"23b5dd9b7b402388c7a40bc88c261f3178acf30d", "7c7bdf0e0713f3752f4b88"),
] ]

5
tests/server/test_env.py

@ -134,7 +134,10 @@ def test_COIN_NET():
e = Env() e = Env()
assert e.coin == lib_coins.PivxTestnet assert e.coin == lib_coins.PivxTestnet
os.environ.pop('NET') os.environ.pop('NET')
os.environ['NET'] = 'mainnet'
os.environ['COIN'] = ' TokenPay '
e = Env()
assert e.coin == lib_coins.TokenPay
def test_CACHE_MB(): def test_CACHE_MB():
assert_integer('CACHE_MB', 'cache_MB', 1200) assert_integer('CACHE_MB', 'cache_MB', 1200)

Loading…
Cancel
Save