-
Notifications
You must be signed in to change notification settings - Fork 0
/
wallet.py
83 lines (64 loc) · 2.83 KB
/
wallet.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
import base58
import codecs
import hashlib
from ecdsa import NIST256p
from ecdsa import SigningKey
import utils
class Wallet(object):
def __init__(self):
self._private_key = SigningKey.generate(curve=NIST256p)
self._public_key = self._private_key.get_verifying_key()
self._blockchain_address = self.generate_blockchain_address()
@property
def private_key(self):
return self._private_key.to_string().hex()
@property
def public_key(self):
return self._public_key.to_string().hex()
@property
def blockchain_address(self):
return self._blockchain_address
def generate_blockchain_address(self):
public_key_bytes = self._public_key.to_string()
sha256_bpk = hashlib.sha256(public_key_bytes)
sha256_bpk_digest = sha256_bpk.digest()
ripemed160_bpk = hashlib.new('ripemd160')
ripemed160_bpk.update(sha256_bpk_digest)
ripemed160_bpk_digest = ripemed160_bpk.digest()
ripemed160_bpk_hex = codecs.encode(ripemed160_bpk_digest, 'hex')
network_byte = b'00'
network_bitcoin_public_key = network_byte + ripemed160_bpk_hex
network_bitcoin_public_key_bytes = codecs.decode(
network_bitcoin_public_key, 'hex')
sha256_bpk = hashlib.sha256(network_bitcoin_public_key_bytes)
sha256_bpk_digest = sha256_bpk.digest()
sha256_2_nbpk = hashlib.sha256(sha256_bpk_digest)
sha256_2_nbpk_digest = sha256_2_nbpk.digest()
sha256_hex = codecs.encode(sha256_2_nbpk_digest, 'hex')
checksum = sha256_hex[:8]
address_hex = (network_bitcoin_public_key + checksum).decode('utf-8')
blockchain_address = base58.b58encode(address_hex).decode('utf-8')
return blockchain_address
class Transaction(object):
def __init__(self, sender_private_key, sender_public_key,
sender_blockchain_address, recipient_blockchain_address,
value):
self.sender_private_key = sender_private_key
self.sender_public_key = sender_public_key
self.sender_blockchain_address = sender_blockchain_address
self.recipient_blockchain_address = recipient_blockchain_address
self.value = value
def generate_signature(self):
sha256 = hashlib.sha256()
transaction = utils.sorted_dict_by_key({
'sender_blockchain_address': self.sender_blockchain_address,
'recipient_blockchain_address': self.recipient_blockchain_address,
'value': float(self.value)
})
sha256.update(str(transaction).encode('utf-8'))
message = sha256.digest()
private_key = SigningKey.from_string(
bytes().fromhex(self.sender_private_key), curve=NIST256p)
private_key_sign = private_key.sign(message)
signature = private_key_sign.hex()
return signature