-
Notifications
You must be signed in to change notification settings - Fork 70
/
getz_input.py
121 lines (104 loc) · 4.96 KB
/
getz_input.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
# -*- coding: utf-8 -*-
"""
@author: iceland
"""
import sys
import secp256k1 as ice
import argparse
from urllib.request import urlopen
#==============================================================================
parser = argparse.ArgumentParser(description='This tool helps to get ECDSA Signature r,s,z values from Bitcoin rawtx or txid',
epilog='Enjoy the program! :) Tips BTC: bc1q39meky2mn5qjq704zz0nnkl0v7kj4uz6r529at')
parser.add_argument("-txid", help = "txid of the transaction. Automatically fetch rawtx from given txid", action="store")
parser.add_argument("-rawtx", help = "Raw Transaction on the blockchain.", action="store")
if len(sys.argv)==1:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
#==============================================================================
txid = args.txid if args.txid else ''
rawtx = args.rawtx if args.rawtx else ''
if rawtx == '' and txid == '':
print('One of the required option missing -rawtx or -txid'); sys.exit(1)
#==============================================================================
def get_rs(sig):
rlen = int(sig[2:4], 16)
r = sig[4:4+rlen*2]
# slen = int(sig[6+rlen*2:8+rlen*2], 16)
s = sig[8+rlen*2:]
return r, s
def split_sig_pieces(script):
sigLen = int(script[2:4], 16)
sig = script[2+2:2+sigLen*2]
r, s = get_rs(sig[4:])
pubLen = int(script[4+sigLen*2:4+sigLen*2+2], 16)
pub = script[4+sigLen*2+2:]
assert(len(pub) == pubLen*2)
return r, s, pub
# Returns list of this list [first, sig, pub, rest] for each input
def parseTx(txn):
if len(txn) <130:
print('[WARNING] rawtx most likely incorrect. Please check..')
sys.exit(1)
inp_list = []
ver = txn[:8]
if txn[8:12] == '0001':
print('UnSupported Tx Input. Presence of Witness Data')
sys.exit(1)
inp_nu = int(txn[8:10], 16)
first = txn[0:10]
cur = 10
for m in range(inp_nu):
prv_out = txn[cur:cur+64]
var0 = txn[cur+64:cur+64+8]
cur = cur+64+8
scriptLen = int(txn[cur:cur+2], 16)
script = txn[cur:2+cur+2*scriptLen] #8b included
r, s, pub = split_sig_pieces(script)
seq = txn[2+cur+2*scriptLen:10+cur+2*scriptLen]
inp_list.append([prv_out, var0, r, s, pub, seq])
cur = 10+cur+2*scriptLen
rest = txn[cur:]
return [first, inp_list, rest]
#==============================================================================
def get_rawtx_from_blockchain(txid):
try:
htmlfile = urlopen("https://blockchain.info/rawtx/%s?format=hex" % txid, timeout = 20)
except:
print('Unable to connect internet to fetch RawTx. Exiting..')
sys.exit(1)
else: res = htmlfile.read().decode('utf-8')
return res
# =============================================================================
def getSignableTxn(parsed):
res = []
first, inp_list, rest = parsed
tot = len(inp_list)
for one in range(tot):
e = first
for i in range(tot):
e += inp_list[i][0] # prev_txid
e += inp_list[i][1] # var0
if one == i:
e += '1976a914' + HASH160(inp_list[one][4]) + '88ac'
else:
e += '00'
e += inp_list[i][5] # seq
e += rest + "01000000"
z = ice.get_sha256(ice.get_sha256(bytes.fromhex(e))).hex()
res.append([inp_list[one][2], inp_list[one][3], z, inp_list[one][4], e])
return res
#==============================================================================
def HASH160(pubk_hex):
iscompressed = True if len(pubk_hex) < 70 else False
P = ice.pub2upub(pubk_hex)
return ice.pubkey_to_h160(0, iscompressed, P).hex()
#==============================================================================
#txn = '01000000028370ef64eb83519fd14f9d74826059b4ce00eae33b5473629486076c5b3bf215000000008c4930460221009bf436ce1f12979ff47b4671f16b06a71e74269005c19178384e9d267e50bbe9022100c7eabd8cf796a78d8a7032f99105cdcb1ae75cd8b518ed4efe14247fb00c9622014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffffb0385cd9a933545628469aa1b7c151b85cc4a087760a300e855af079eacd25c5000000008b48304502210094b12a2dd0f59b3b4b84e6db0eb4ba4460696a4f3abf5cc6e241bbdb08163b45022007eaf632f320b5d9d58f1e8d186ccebabea93bad4a6a282a3c472393fe756bfb014104e3896e6cabfa05a332368443877d826efc7ace23019bd5c2bc7497f3711f009e873b1fcc03222f118a6ff696efa9ec9bb3678447aae159491c75468dcc245a6cffffffff01404b4c00000000001976a91402d8103ac969fe0b92ba04ca8007e729684031b088ac00000000'
if rawtx == '':
rawtx = get_rawtx_from_blockchain(txid)
print('\nStarting Program...')
m = parseTx(rawtx)
e = getSignableTxn(m)
for i in range(len(e)):
print('='*70,f'\n[Input Index #: {i}]\n R: {e[i][0]}\n S: {e[i][1]}\n Z: {e[i][2]}\nPubKey: {e[i][3]}')