parent
ab17b4d529
commit
3a33675e11
@ -29,6 +29,7 @@ install:
|
||||
# hashes
|
||||
- pip install tribus-hash
|
||||
- pip install blake256
|
||||
- pip install scrypt
|
||||
- pip install x11_hash
|
||||
- pip install xevan_hash
|
||||
- pip install quark_hash
|
||||
|
||||
@ -1174,6 +1174,31 @@ class Reddcoin(Coin):
|
||||
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):
|
||||
NAME = "Vertcoin"
|
||||
SHORTNAME = "VTC"
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
from collections import namedtuple
|
||||
|
||||
from electrumx.lib.hash import sha256, double_sha256, hash_to_hex_str
|
||||
from electrumx.lib.script import OpCodes
|
||||
from electrumx.lib.util import (
|
||||
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,
|
||||
@ -422,6 +423,74 @@ class DeserializerGroestlcoin(DeserializerSegWit):
|
||||
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
|
||||
class TxInputDcr(namedtuple("TxInput", "prev_hash prev_idx tree sequence")):
|
||||
'''Class representing a Decred transaction input.'''
|
||||
|
||||
28
tests/blocks/tokenpay_mainnet_20000.json
Normal file
28
tests/blocks/tokenpay_mainnet_20000.json
Normal file
@ -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"
|
||||
}
|
||||
@ -64,7 +64,9 @@ addresses = [
|
||||
(coins.PivxTestnet, "yJ8iHtUxj9U4vsXLCZTbPNbuxG6NJNCvb8",
|
||||
"e808105b7bfcc8b102cafa7242089b22c77a3b94", "31d61c3076fa0b2b7c74ef"),
|
||||
(coins.PivxTestnet, "yCcNWqqMhDmsPzKchCPK1ux4HpxK7j3xpB",
|
||||
"ab72728952c06dfc0f6cf21449dd645422731ec4", "eb3a3155215538d51de7cc")
|
||||
"ab72728952c06dfc0f6cf21449dd645422731ec4", "eb3a3155215538d51de7cc"),
|
||||
(coins.TokenPay, "TDE2X28FGtckatxuP3d8s3V726G4TLNHpT",
|
||||
"23b5dd9b7b402388c7a40bc88c261f3178acf30d", "7c7bdf0e0713f3752f4b88"),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@ -134,7 +134,10 @@ def test_COIN_NET():
|
||||
e = Env()
|
||||
assert e.coin == lib_coins.PivxTestnet
|
||||
os.environ.pop('NET')
|
||||
|
||||
os.environ['NET'] = 'mainnet'
|
||||
os.environ['COIN'] = ' TokenPay '
|
||||
e = Env()
|
||||
assert e.coin == lib_coins.TokenPay
|
||||
|
||||
def test_CACHE_MB():
|
||||
assert_integer('CACHE_MB', 'cache_MB', 1200)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user