-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathtx.py
132 lines (93 loc) · 3.69 KB
/
tx.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import struct
import ecdsa
import base58
import hashlib
outpoint = "9844f4682eae5bb14297a94124d09f7fd635dbb2241490c99ca2e2ec3dc821db"
Alice_adress = "1NWzVg38ggPoVGAG2VWt6ktdWMaV6S1pJK"
Alice_hashed_pubkey = base58.b58decode_check(Alice_adress)[1:].encode("hex")
Bob_adress = "1ANRQ9bEJZcwXiw7YZ6uE5egrE7t9gCyip"
Bob_hashed_pubkey = base58.b58decode_check(Bob_adress)[1:].encode("hex")
Alice_private_key = ""
#############################################################################
class raw_tx:
version = struct.pack("<L", 1)
tx_in_count = 0 #temp
tx_in = {} #temp
tx_out_count = 0 #temp
tx_out1 = {} #temp
tx_out2 = {} #temp
lock_time = struct.pack("<L", 0)
hash_code = struct.pack("<L", 1)
tx_to_sign = 0 #temp
def flip_byte_order(self, string): #string, not bianry!
flipped = "".join(reversed([string[i:i+2] for i in range(0, len(string), 2)]))
return flipped
############################################################################
rtx = raw_tx()
rtx.tx_in_count = struct.pack("<B", 1)
rtx.tx_in["outpoint_hash"] = rtx.flip_byte_order(outpoint).decode("hex")
rtx.tx_in["outpoint_index"] = struct.pack("<L", 1)
rtx.tx_in["script_byes"] = 0 #temp
rtx.tx_in["script"] = ("76a914%s88ac" % Alice_hashed_pubkey).decode("hex")
rtx.tx_in["script_byes"] = struct.pack("<B", (len(rtx.tx_in["script"])))
rtx.tx_in["sequence"] = "ffffffff".decode("hex")
rtx.tx_out_count = struct.pack("<B", 2)
rtx.tx_out1["value"] = struct.pack("<Q", 50000) #send to Bob
rtx.tx_out1["pk_script_bytes"] = 0 #temp
rtx.tx_out1["pk_script"] = ("76a914%s88ac" % Bob_hashed_pubkey).decode("hex")
rtx.tx_out1["pk_script_bytes"] = struct.pack("<B", (len(rtx.tx_out1["pk_script"])))
rtx.tx_out2["value"] = struct.pack("<Q", 50000) #send back (change)
rtx.tx_out2["pk_script_bytes"] = 0 #temp
rtx.tx_out2["pk_script"] = ("76a914%s88ac" % Alice_hashed_pubkey).decode("hex")
rtx.tx_out2["pk_script_bytes"] = struct.pack("<B", (len(rtx.tx_out1["pk_script"])))
rtx.tx_to_sign = (
rtx.version
+ rtx.tx_in_count
+ rtx.tx_in["outpoint_hash"]
+ rtx.tx_in["outpoint_index"]
+ rtx.tx_in["script_byes"]
+ rtx.tx_in["script"]
+ rtx.tx_in["sequence"]
+ rtx.tx_out_count
+ rtx.tx_out1["value"]
+ rtx.tx_out1["pk_script_bytes"]
+ rtx.tx_out1["pk_script"]
+ rtx.tx_out2["value"]
+ rtx.tx_out2["pk_script_bytes"]
+ rtx.tx_out2["pk_script"]
+ rtx.lock_time
+ rtx.hash_code
)
#############################################################################
hashed_raw_tx = hashlib.sha256(hashlib.sha256(rtx.tx_to_sign).digest()).digest()
#############################################################################
sk = ecdsa.SigningKey.from_string(Alice_private_key.decode("hex"), curve = ecdsa.SECP256k1)
vk = sk.verifying_key
public_key = ('\04' + vk.to_string()).encode("hex")
#############################################################################
sign = sk.sign_digest(hashed_raw_tx, sigencode=ecdsa.util.sigencode_der)
#############################################################################
sigscript = (
sign
+ "\01"
+ struct.pack("<B", len(public_key.decode("hex")))
+ public_key.decode("hex"))
#############################################################################
real_tx = (
rtx.version
+ rtx.tx_in_count
+ rtx.tx_in["outpoint_hash"]
+ rtx.tx_in["outpoint_index"]
+ struct.pack("<B", (len(sigscript) + 1))
+ struct.pack("<B", len(sign) + 1)
+ sigscript
+ rtx.tx_in["sequence"]
+ rtx.tx_out_count
+ rtx.tx_out1["value"]
+ rtx.tx_out1["pk_script_bytes"]
+ rtx.tx_out1["pk_script"]
+ rtx.tx_out2["value"]
+ rtx.tx_out2["pk_script_bytes"]
+ rtx.tx_out2["pk_script"]
+ rtx.lock_time)
print real_tx.encode("hex")