create tx tests
This commit is contained in:
parent
4890b9136c
commit
ed01d12876
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
File diff suppressed because one or more lines are too long
@ -267,9 +267,9 @@ class Transaction():
|
|||||||
self.tx_fee = None
|
self.tx_fee = None
|
||||||
self.version = version
|
self.version = version
|
||||||
self.tx_in_count = len(tx_in)
|
self.tx_in_count = len(tx_in)
|
||||||
self.tx_in = tx_in
|
self.tx_in = list(tx_in)
|
||||||
self.tx_out_count = len (tx_out)
|
self.tx_out_count = len(tx_out)
|
||||||
self.tx_out = tx_out
|
self.tx_out = list(tx_out)
|
||||||
self.lock_time = lock_time
|
self.lock_time = lock_time
|
||||||
if self.tx_in:
|
if self.tx_in:
|
||||||
self.coinbase = self.tx_in[0].coinbase
|
self.coinbase = self.tx_in[0].coinbase
|
||||||
@ -292,9 +292,11 @@ class Transaction():
|
|||||||
self.data = i.pk_script.data
|
self.data = i.pk_script.data
|
||||||
for out in self.tx_out:
|
for out in self.tx_out:
|
||||||
self.total_outs_value += out.value
|
self.total_outs_value += out.value
|
||||||
|
if not self.tx_in:
|
||||||
|
self.witness = list()
|
||||||
if witness is None:
|
if witness is None:
|
||||||
self.witness = [Witness.deserialize(b"\x00") for i in range(len(tx_in))]
|
self.witness = [Witness.deserialize(b"\x00") for i in range(len(tx_in))]
|
||||||
if hash is None:
|
if hash is None :
|
||||||
self.recalculate_txid()
|
self.recalculate_txid()
|
||||||
|
|
||||||
def recalculate_txid(self):
|
def recalculate_txid(self):
|
||||||
@ -310,6 +312,9 @@ class Transaction():
|
|||||||
self.size = len(t)
|
self.size = len(t)
|
||||||
self.vsize = math.ceil((self.size * 3 + self.size) / 4)
|
self.vsize = math.ceil((self.size * 3 + self.size) / 4)
|
||||||
|
|
||||||
|
def txid(self):
|
||||||
|
return rh2s(self.hash)
|
||||||
|
|
||||||
def add_input(self, tx_hash, output_number,
|
def add_input(self, tx_hash, output_number,
|
||||||
sequence = 0xffffffff,
|
sequence = 0xffffffff,
|
||||||
sig_script = b"",
|
sig_script = b"",
|
||||||
@ -320,15 +325,67 @@ class Transaction():
|
|||||||
self.tx_in_count += 1
|
self.tx_in_count += 1
|
||||||
self.recalculate_txid()
|
self.recalculate_txid()
|
||||||
|
|
||||||
def add_output(self, amount, script):
|
def add_output_script(self, amount, script):
|
||||||
if type(script)==str:
|
if type(script)==str:
|
||||||
script = unhexlify(script)
|
script = unhexlify(script)
|
||||||
self.tx_out.append(Output(amount,script))
|
self.tx_out.append(Output(amount,script))
|
||||||
self.tx_out_count += 1
|
self.tx_out_count += 1
|
||||||
self.recalculate_txid()
|
self.recalculate_txid()
|
||||||
|
|
||||||
|
def add_output_address(self, amount, address, testnet = False):
|
||||||
|
assert is_address_valid(address, testnet)
|
||||||
|
output_type = address_type(address, True)
|
||||||
|
if output_type == 0:
|
||||||
|
self.add_P2PKH_output(amount, address)
|
||||||
|
elif output_type == 1:
|
||||||
|
self.add_P2SH_output(amount, address)
|
||||||
|
elif output_type == 5:
|
||||||
|
self.add_P2WPKH_output(amount, address)
|
||||||
|
elif output_type == 6:
|
||||||
|
self.add_P2WSH_output(amount, address)
|
||||||
|
|
||||||
|
|
||||||
|
def add_output_hash(self, amount, output_hash, output_type, witness_version = 0):
|
||||||
|
if type(output_type)==str:
|
||||||
|
output_type = SCRIPT_TYPES[output_type]
|
||||||
|
if output_hash == str:
|
||||||
|
output_hash = unhexlify(output_hash)
|
||||||
|
assert output_type in (0, 1, 5, 6)
|
||||||
|
if output_type == 0:
|
||||||
|
self.add_P2PKH_output(amount, output_hash)
|
||||||
|
elif output_type == 1:
|
||||||
|
self.add_P2SH_output(amount, output_hash)
|
||||||
|
elif output_type == 5:
|
||||||
|
self.add_P2WPKH_output(amount, output_hash, witness_version)
|
||||||
|
elif output_type == 6:
|
||||||
|
self.add_P2WSH_output(amount, output_hash, witness_version)
|
||||||
|
|
||||||
|
|
||||||
|
def add_P2WPKH_output(self, amount, p2wpkh_address, witness_version = 0):
|
||||||
|
if type(p2wpkh_address)==str:
|
||||||
|
assert address_type(p2wpkh_address) == 'P2WPKH'
|
||||||
|
witness_version = get_witness_version(p2wpkh_address)
|
||||||
|
p2wpkh_address = address2hash(p2wpkh_address)
|
||||||
|
assert len(p2wpkh_address) == 20
|
||||||
|
self.tx_out.append(Output(amount,
|
||||||
|
bytes([witness_version]) + b'\x14' + p2wpkh_address))
|
||||||
|
self.tx_out_count += 1
|
||||||
|
self.recalculate_txid()
|
||||||
|
|
||||||
|
def add_P2WSH_output(self, amount, p2wsh_address, witness_version = 0):
|
||||||
|
if type(p2wsh_address)==str:
|
||||||
|
assert address_type(p2wsh_address) == 'P2WSH'
|
||||||
|
witness_version = get_witness_version(p2wsh_address)
|
||||||
|
p2wsh_address = address2hash(p2wsh_address)
|
||||||
|
assert len(p2wsh_address) == 32
|
||||||
|
self.tx_out.append(Output(amount,
|
||||||
|
bytes([witness_version]) + b'\x20' + p2wsh_address))
|
||||||
|
self.tx_out_count += 1
|
||||||
|
self.recalculate_txid()
|
||||||
|
|
||||||
def add_P2SH_output(self, amount, p2sh_address):
|
def add_P2SH_output(self, amount, p2sh_address):
|
||||||
if type(p2sh_address)==str:
|
if type(p2sh_address)==str:
|
||||||
|
assert address_type(p2sh_address) == 'P2SH'
|
||||||
p2sh_address = decode_base58(p2sh_address)[1:-4]
|
p2sh_address = decode_base58(p2sh_address)[1:-4]
|
||||||
if len(p2sh_address) != 20:
|
if len(p2sh_address) != 20:
|
||||||
raise Exception("Invalid output hash160")
|
raise Exception("Invalid output hash160")
|
||||||
@ -337,8 +394,10 @@ class Transaction():
|
|||||||
self.tx_out_count += 1
|
self.tx_out_count += 1
|
||||||
self.recalculate_txid()
|
self.recalculate_txid()
|
||||||
|
|
||||||
|
|
||||||
def add_P2PKH_output(self, amount, p2pkh_address):
|
def add_P2PKH_output(self, amount, p2pkh_address):
|
||||||
if type(p2pkh_address)==str:
|
if type(p2pkh_address)==str:
|
||||||
|
assert address_type(p2pkh_address) == 'P2PKH'
|
||||||
p2pkh_address = decode_base58(p2pkh_address)[1:-4]
|
p2pkh_address = decode_base58(p2pkh_address)[1:-4]
|
||||||
if len(p2pkh_address) != 20:
|
if len(p2pkh_address) != 20:
|
||||||
raise p2pkh_address("Invalid output hash160")
|
raise p2pkh_address("Invalid output hash160")
|
||||||
@ -367,7 +426,8 @@ class Transaction():
|
|||||||
nouts = to_var_int(self.tx_out_count)
|
nouts = to_var_int(self.tx_out_count)
|
||||||
outputs = []
|
outputs = []
|
||||||
for number, i in enumerate(self.tx_out):
|
for number, i in enumerate(self.tx_out):
|
||||||
outputs.append(i.value.to_bytes(8,'little')+to_var_int(len(i.pk_script.raw))+i.pk_script.raw)
|
a = i.pk_script.raw
|
||||||
|
outputs.append(i.value.to_bytes(8,'little')+to_var_int(len(a))+a)
|
||||||
marke_flag = b"\x00\x01" if segwit else b""
|
marke_flag = b"\x00\x01" if segwit else b""
|
||||||
witness = b""
|
witness = b""
|
||||||
if segwit:
|
if segwit:
|
||||||
@ -491,7 +551,7 @@ class Transaction():
|
|||||||
return double_sha256(preimage) if not hex else hexlify(double_sha256(preimage)).decode()
|
return double_sha256(preimage) if not hex else hexlify(double_sha256(preimage)).decode()
|
||||||
|
|
||||||
|
|
||||||
def json(self):
|
def json(self, testnet = False):
|
||||||
r = dict()
|
r = dict()
|
||||||
r["txid"] = rh2s(self.hash)
|
r["txid"] = rh2s(self.hash)
|
||||||
r["wtxid"] = r["txid"] if self.whash is None else rh2s(self.whash)
|
r["wtxid"] = r["txid"] if self.whash is None else rh2s(self.whash)
|
||||||
@ -519,6 +579,18 @@ class Transaction():
|
|||||||
"scriptPubKey": {"hex": hexlify(o.pk_script.raw).decode()},
|
"scriptPubKey": {"hex": hexlify(o.pk_script.raw).decode()},
|
||||||
"asm": o.pk_script.asm,
|
"asm": o.pk_script.asm,
|
||||||
"type": o.pk_script.type}
|
"type": o.pk_script.type}
|
||||||
|
if self.witness is not None:
|
||||||
|
out["witnessVersion"] = o.pk_script.witness_version
|
||||||
|
out["address"] = []
|
||||||
|
sh = False
|
||||||
|
if o.pk_script.ntype in (1,6):
|
||||||
|
sh =True
|
||||||
|
for a in o.pk_script.address:
|
||||||
|
out["address"].append(hash2address(a,
|
||||||
|
testnet=testnet,
|
||||||
|
script_hash= sh,
|
||||||
|
witness_version=o.pk_script.witness_version))
|
||||||
|
|
||||||
r["vout"].append(out)
|
r["vout"].append(out)
|
||||||
|
|
||||||
return json.dumps(r)
|
return json.dumps(r)
|
||||||
|
|||||||
@ -165,6 +165,11 @@ def address2hash(address, hex = False):
|
|||||||
else:
|
else:
|
||||||
return h
|
return h
|
||||||
|
|
||||||
|
def get_witness_version(address):
|
||||||
|
address = address.split("1")[1]
|
||||||
|
h = rebase_32_to_5(address)
|
||||||
|
return h[0]
|
||||||
|
|
||||||
def address_type(address, num = False):
|
def address_type(address, num = False):
|
||||||
if address[0] in (TESTNET_SCRIPT_ADDRESS_PREFIX,
|
if address[0] in (TESTNET_SCRIPT_ADDRESS_PREFIX,
|
||||||
MAINNET_SCRIPT_ADDRESS_PREFIX):
|
MAINNET_SCRIPT_ADDRESS_PREFIX):
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
from .script_deserialize import *
|
from .script_deserialize import *
|
||||||
from .hash_functions import *
|
from .hash_functions import *
|
||||||
|
from .create_transaction import *
|
||||||
from .address_functions import *
|
from .address_functions import *
|
||||||
from .transaction_deserialize import *
|
from .transaction_deserialize import *
|
||||||
from .sighash import *
|
from .sighash import *
|
||||||
from .ecdsa import *
|
from .ecdsa import *
|
||||||
# from .block import *
|
from .block import *
|
||||||
31
test/create_transaction.py
Normal file
31
test/create_transaction.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import unittest
|
||||||
|
from pybtc import *
|
||||||
|
from binascii import unhexlify
|
||||||
|
from pybtc import address2hash as address2hash160
|
||||||
|
|
||||||
|
class CreateTransactionTests(unittest.TestCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
print("\nTesting create transaction:\n")
|
||||||
|
|
||||||
|
def test_create_tx(self):
|
||||||
|
tx = Transaction()
|
||||||
|
tx.add_input("60965ce5eec9846373c497ff0b45e55d0af5e6ed96ef46455be377935eb563e4",
|
||||||
|
2)
|
||||||
|
tx.add_output_address(270000000, "3ByyFTy4ESZVr6y3mWqapqC84yn2TAtcr4")
|
||||||
|
tx.add_output_address(171310000, "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej")
|
||||||
|
self.assertEqual(rh2s(tx.hash), "1afc445bf8aef9904f2e1d7f4c5f9093587ccff8aa01263c7369c917aa86616a")
|
||||||
|
raw_tx = tx.serialize()
|
||||||
|
tx2 = Transaction.deserialize(raw_tx)
|
||||||
|
self.assertEqual(rh2s(tx2.hash), "1afc445bf8aef9904f2e1d7f4c5f9093587ccff8aa01263c7369c917aa86616a")
|
||||||
|
self.assertEqual(tx2.tx_out[-1].pk_script.type, "P2WSH")
|
||||||
|
|
||||||
|
tx = Transaction()
|
||||||
|
tx.add_input("593cd8119bcd49055df0a3a01c38989b311c1e88985a6315608bb5d59dda9d1f", 1)
|
||||||
|
tx.add_output_address(25000, "39okDra9814p4Dz3SFSuS2D8riqbbMtSiP")
|
||||||
|
tx.add_output_address(689, "bc1qrn7pyh2c79gf7a8ywpx85w9u7lj9dx7tfevlv0")
|
||||||
|
self.assertEqual(rh2s(tx.hash), "7221dfc0fa3ff37d5dcbaf77c2e1b56318a25a793a62d854909cbd7f754881bb")
|
||||||
|
self.assertEqual(tx.tx_out[-1].pk_script.type, "P2WPKH")
|
||||||
|
self.assertEqual(tx.tx_out[0].pk_script.type, "P2SH")
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ class ScriptDeserializeTests(unittest.TestCase):
|
|||||||
self.assertEqual(s.type, "P2WPKH")
|
self.assertEqual(s.type, "P2WPKH")
|
||||||
self.assertEqual(s.ntype, 5)
|
self.assertEqual(s.ntype, 5)
|
||||||
self.assertEqual(s.asm, "OP_0 4160bb1870159a08724557f75c7bb665a3a132e0")
|
self.assertEqual(s.asm, "OP_0 4160bb1870159a08724557f75c7bb665a3a132e0")
|
||||||
self.assertEqual(s.address[0], unhexlify("004160bb1870159a08724557f75c7bb665a3a132e0"))
|
self.assertEqual(s.address[0], unhexlify("4160bb1870159a08724557f75c7bb665a3a132e0"))
|
||||||
self.assertEqual(s.pattern, "OP_0 <20>")
|
self.assertEqual(s.pattern, "OP_0 <20>")
|
||||||
self.assertEqual(s.op_sig_count, 1)
|
self.assertEqual(s.op_sig_count, 1)
|
||||||
s = blockchain.Script("00144160bb1870159a08724557f75c7bb665a3a132e0", segwit=False)
|
s = blockchain.Script("00144160bb1870159a08724557f75c7bb665a3a132e0", segwit=False)
|
||||||
@ -135,7 +135,7 @@ class ScriptDeserializeTests(unittest.TestCase):
|
|||||||
self.assertEqual(s.type, "P2WSH")
|
self.assertEqual(s.type, "P2WSH")
|
||||||
self.assertEqual(s.ntype, 6)
|
self.assertEqual(s.ntype, 6)
|
||||||
self.assertEqual(s.asm, "OP_0 cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70")
|
self.assertEqual(s.asm, "OP_0 cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70")
|
||||||
self.assertEqual(s.address[0], unhexlify("00cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70"))
|
self.assertEqual(s.address[0], unhexlify("cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70"))
|
||||||
self.assertEqual(s.pattern, "OP_0 <32>")
|
self.assertEqual(s.pattern, "OP_0 <32>")
|
||||||
self.assertEqual(s.op_sig_count, 0)
|
self.assertEqual(s.op_sig_count, 0)
|
||||||
s = blockchain.Script("0020cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70", segwit=False)
|
s = blockchain.Script("0020cdbf909e935c855d3e8d1b61aeb9c5e3c03ae8021b286839b1a72f2e48fdba70", segwit=False)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user