1import bitcoin
2import struct
3import serialize
4
5
6class BlockHeader:
7
8    def __init__(self):
9        self.height = None
10
11    @classmethod
12    def deserialize(cls, raw):
13        assert len(raw) == 80
14        self = cls()
15        self.version = struct.unpack('<I', raw[:4])[0]
16        self.previous_block_hash = raw[4:36][::-1]
17        assert len(self.previous_block_hash) == 32
18        self.merkle = raw[36:68][::-1]
19        assert len(self.merkle) == 32
20        self.timestamp, self.bits, self.nonce = struct.unpack('<III', raw[68:])
21        return self
22
23    @property
24    def hash(self):
25        data = struct.pack('<I', self.version)
26        data += self.previous_block_hash[::-1]
27        data += self.merkle[::-1]
28        data += struct.pack('<III', self.timestamp, self.bits, self.nonce)
29        return bitcoin.Hash(data)[::-1]
30
31    def __repr__(self):
32        return '<BlockHeader %s>' % (self.hash.encode("hex"),)
33
34
35#missing object at serialize.py
36class Block:
37    pass
38
39
40class OutPoint(object):
41    def __init__(self):
42        self.hash = None
43        self.index = None
44
45    def is_null(self):
46        return (len(self.hash) == 0) and (self.index == 0xffffffff)
47
48    def __repr__(self):
49        return "OutPoint(hash=%s, index=%i)" % \
50               (self.hash.encode("hex"), self.index)
51
52    def serialize(self):
53        return serialize.ser_output_point(self)
54
55    @staticmethod
56    def deserialize(bytes):
57        return serialize.deser_output_point(bytes)
58
59
60class TxOut(object):
61    def __init__(self):
62        self.value = None
63        self.script = ""
64
65    def __repr__(self):
66        return "TxOut(value=%i.%08i script=%s)" % \
67               (self.value // 100000000,
68                self.value % 100000000,
69                self.script.encode("hex"))
70
71    def serialize(self):
72        return serialize.ser_txout(self)
73
74    @staticmethod
75    def deserialize(bytes):
76        return serialize.deser_txout(bytes)
77
78
79class TxIn(object):
80    def __init__(self):
81        self.previous_output = OutPoint()
82        self.script = ""
83        self.sequence = 0xffffffff
84
85    def is_final(self):
86        return self.sequence == 0xffffffff
87
88    def __repr__(self):
89        return "TxIn(previous_output=%s script=%s sequence=%i)" %\
90               (repr(self.previous_output),
91                self.script.encode("hex"),
92                self.sequence)
93
94    def serialize(self):
95        return serialize.ser_txin(self)
96
97    @staticmethod
98    def deserialize(bytes):
99        return serialize.deser_txin(bytes)
100
101
102class Transaction:
103    def __init__(self):
104        self.version = 1
105        self.locktime = 0
106        self.inputs = []
107        self.outputs = []
108
109    def is_final(self):
110        for tin in self.vin:
111            if not tin.is_final():
112                return False
113        return True
114
115    def is_coinbase(self):
116        return len(self.vin) == 1 and self.vin[0].prevout.is_null()
117
118    def __repr__(self):
119        return "Transaction(version=%i inputs=%s outputs=%s locktime=%i)" %\
120               (self.version,
121                repr(self.inputs),
122                repr(self.outputs),
123                self.locktime)
124
125    def serialize(self):
126        return serialize.ser_tx(self)
127
128    @staticmethod
129    def deserialize(bytes):
130        return serialize.deser_tx(bytes)
131