mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-24 07:18:09 +00:00
85 lines
2.1 KiB
Python
Executable File
85 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import sys
|
|
|
|
try:
|
|
import construct as c
|
|
except ImportError:
|
|
sys.stderr.write("This tool requires Construct. Install it with 'pip install Construct'.\n")
|
|
sys.exit(1)
|
|
|
|
from construct import this, len_
|
|
|
|
if os.isatty(sys.stdin.fileno()):
|
|
tx_hex = input("Enter transaction in hex format: ")
|
|
else:
|
|
tx_hex = sys.stdin.read().strip()
|
|
|
|
tx_bin = bytes.fromhex(tx_hex)
|
|
|
|
|
|
CompactUintStruct = c.Struct(
|
|
"base" / c.Int8ul,
|
|
"ext" / c.Switch(this.base, {0xfd: c.Int16ul, 0xfe: c.Int32ul, 0xff: c.Int64ul}),
|
|
)
|
|
|
|
|
|
class CompactUintAdapter(c.Adapter):
|
|
def _encode(self, obj, context, path):
|
|
if obj < 0xfd:
|
|
return {"base": obj}
|
|
if obj < 2 ** 16:
|
|
return {"base": 0xfd, "ext": obj}
|
|
if obj < 2 ** 32:
|
|
return {"base": 0xfe, "ext": obj}
|
|
if obj < 2 ** 64:
|
|
return {"base": 0xff, "ext": obj}
|
|
raise ValueError("Value too big for compact uint")
|
|
|
|
def _decode(self, obj, context, path):
|
|
return obj["ext"] or obj["base"]
|
|
|
|
|
|
class ConstFlag(c.Adapter):
|
|
def __init__(self, const):
|
|
self.const = const
|
|
super().__init__(c.Optional(c.Const(const)))
|
|
|
|
def _encode(self, obj, context, path):
|
|
return self.const if obj else None
|
|
|
|
def _decode(self, obj, context, path):
|
|
return obj is not None
|
|
|
|
|
|
CompactUint = CompactUintAdapter(CompactUintStruct)
|
|
|
|
TxInput = c.Struct(
|
|
"tx" / c.Bytes(32),
|
|
"index" / c.Int32ul,
|
|
# TODO coinbase tx
|
|
"script" / c.Prefixed(CompactUint, c.GreedyBytes),
|
|
"sequence" / c.Int32ul,
|
|
)
|
|
|
|
TxOutput = c.Struct(
|
|
"value" / c.Int64ul,
|
|
"pk_script" / c.Prefixed(CompactUint, c.GreedyBytes),
|
|
)
|
|
|
|
StackItem = c.Prefixed(CompactUint, c.GreedyBytes)
|
|
TxInputWitness = c.PrefixedArray(CompactUint, StackItem)
|
|
|
|
Transaction = c.Struct(
|
|
"version" / c.Int32ul,
|
|
"segwit" / ConstFlag(b"\x00\x01"),
|
|
"inputs" / c.PrefixedArray(CompactUint, TxInput),
|
|
"outputs" / c.PrefixedArray(CompactUint, TxOutput),
|
|
"witness" / c.If(this.segwit, TxInputWitness[len_(this.inputs)]),
|
|
"lock_time" / c.Int32ul,
|
|
c.Terminated,
|
|
)
|
|
|
|
print(Transaction.parse(tx_bin))
|