-
Notifications
You must be signed in to change notification settings - Fork 41
/
btcProof.py
132 lines (108 loc) · 3.83 KB
/
btcProof.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
#!/usr/bin/python
#Some code to do the same thing as btcproof (since I think there may be an error in their file hashing?)
#some of this code is taken from KeyUtils.py on a random github, so if you made that, then thanks
import sys
import ecdsa
import ecdsa.der
import ecdsa.util
import hashlib
import os
import re
import struct
import webbrowser #for qr code of address
b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
VERSION = 0x00
def base58encode(n):
result = ''
while n > 0:
result = b58[n%58] + result
n /= 58
return result
def base256decode(s):
result = 0
for c in s:
result = result * 256 + ord(c)
return result
def countLeadingChars(s, ch):
count = 0
for c in s:
if c == ch:
count += 1
else:
break
return count
# https://en.bitcoin.it/wiki/Base58Check_encoding
def base58CheckEncode(version, payload):
s = chr(version) + payload #concat version
checksum = hashlib.sha256(hashlib.sha256(s).digest()).digest()[0:4]
print("checksum", checksum)
result = s + checksum #concat checksum to end
leadingZeros = countLeadingChars(result, '\0')
#return base58encode(base256decode(result))
return '1' * leadingZeros + base58encode(base256decode(result))
def privateKeyToWif(key_hex):
return base58CheckEncode(VERSION, key_hex.decode('hex'))
def privateKeyToPublicKey(s):
sk = ecdsa.SigningKey.from_string(s.decode('hex'), curve=ecdsa.SECP256k1)
vk = sk.verifying_key
return ('\04' + sk.verifying_key.to_string()).encode('hex')
def pubKeyToAddr(s):
ripemd160 = hashlib.new('ripemd160')
ripemd160.update(hashlib.sha256(s.decode('hex')).digest())
return base58CheckEncode(0, ripemd160.digest())
def keyToAddr(s):
return pubKeyToAddr(privateKeyToPublicKey(s))
## below tto create digest of file, result should not vary with blocksize
BLOCKSIZE = 2 **10
def sha256OfFile(filepath):
sha = hashlib.sha256()
with open(filepath, 'rb') as f:
while True:
block = f.read(BLOCKSIZE)
if len(block) < BLOCKSIZE:
print(len(block))
block = block[:-1]
if not block: break
sha.update(block)
return sha.hexdigest()
##proofs, c.f.
#https://www.btproof.com/technical.html
# hash = SHA256(DATA) // or the supplied hash
#vhash = CONCAT(VERSION_BYTE, RIPEMD160(hash)) // VERSION_BYTE is 0x00 for main net
#address = BASE58(CONCAT(vhash, SHA256(SHA256(vhash))[0..3]))
def btcProofOfFile(fi):
has = sha256OfFile(fi)
ripemd160 = hashlib.new('ripemd160')
ripemd160.update(has)
address = base58CheckEncode(0, ripemd160.digest())
return address
def btcProofOfString(strin):
sha = hashlib.sha256()
sha.update(strin)
has = sha.digest()
ripemd160 = hashlib.new('ripemd160')
ripemd160.update(has)
address = base58CheckEncode(0, ripemd160.digest())
return address
# Generate a random private key
#private_key = os.urandom(32).encode('hex')
#address = base58CheckEncode(version, payload)
#this works (check sha test vectors at http://www.di-mgt.com.au/sha_testvectors.html) indicating I am hashing the file correctly
#print(sha256OfFile("a.txt"))
#print("should be: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0")
#this works
#print("address for abc")
#print(btcProofOfString("abc"))
#this does not agree with btcproof.com, indicating they are hashing file wrong
#print("address for a.txt")
#print(btcProofOfFile("a.txt"))
#print("bitcoin:"+btcProofOfFile(sys.argv[1])+"?amount=0.0001")
a = btcProofOfFile(sys.argv[1])
print(a)
#bitcoin:1PZmMahjbfsTy6DsaRyfStzoWTPppWwDnZ?amount=0.1
#url = "https://chart.googleapis.com/chart?chs=250x250&cht=qr&chl="+a
url2 = "https://blockchain.info/address/"+a
#print(url)
print(url2)
#webbrowser.open(url)
webbrowser.open(url2)