Skip to content

Commit 116c12d

Browse files
committed
Create and test the Wallet class
1 parent 5911a70 commit 116c12d

File tree

5 files changed

+83
-1
lines changed

5 files changed

+83
-1
lines changed

backend/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
SECONDS = 1000 * MILLISECONDS
55

66
MINE_RATE = 4 * SECONDS
7+
8+
STARTING_BALANCE = 1000

backend/tests/wallet/test_wallet.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from backend.wallet.wallet import Wallet
2+
3+
def test_verify_valid_signature():
4+
data = { 'foo': 'test_data' }
5+
wallet = Wallet()
6+
signature = wallet.sign(data)
7+
8+
assert Wallet.verify(wallet.public_key, data, signature)
9+
10+
def test_verify_invalid_signature():
11+
data = { 'foo': 'test_data' }
12+
wallet = Wallet()
13+
signature = wallet.sign(data)
14+
15+
assert not Wallet.verify(Wallet().public_key, data, signature)

backend/wallet/__init__.py

Whitespace-only changes.

backend/wallet/wallet.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import json
2+
import uuid
3+
4+
from backend.config import STARTING_BALANCE
5+
from cryptography.hazmat.backends import default_backend
6+
from cryptography.hazmat.primitives.asymmetric import ec
7+
from cryptography.hazmat.primitives import hashes
8+
from cryptography.exceptions import InvalidSignature
9+
10+
class Wallet:
11+
"""
12+
An individual wallet for a miner.
13+
Keeps track of the miner's balance.
14+
Allows a miner to authorize transactions.
15+
"""
16+
def __init__(self):
17+
self.address = str(uuid.uuid4())[0:8]
18+
self.balance = STARTING_BALANCE
19+
self.private_key = ec.generate_private_key(
20+
ec.SECP256K1(),
21+
default_backend()
22+
)
23+
self.public_key = self.private_key.public_key()
24+
25+
def sign(self, data):
26+
"""
27+
Generate a signature based on the data using the local private key.
28+
"""
29+
return self.private_key.sign(
30+
json.dumps(data).encode('utf-8'),
31+
ec.ECDSA(hashes.SHA256())
32+
)
33+
34+
@staticmethod
35+
def verify(public_key, data, signature):
36+
"""
37+
Verify a signature based on the original public key and data.
38+
"""
39+
try:
40+
public_key.verify(
41+
signature,
42+
json.dumps(data).encode('utf-8'),
43+
ec.ECDSA(hashes.SHA256())
44+
)
45+
return True
46+
except InvalidSignature:
47+
return False
48+
49+
def main():
50+
wallet = Wallet()
51+
print(f'wallet.__dict__: {wallet.__dict__}')
52+
53+
data = { 'foo': 'bar' }
54+
signature = wallet.sign(data)
55+
print(f'signature: {signature}')
56+
57+
should_be_valid = Wallet.verify(wallet.public_key, data, signature)
58+
print(f'should_be_valid: {should_be_valid}')
59+
60+
should_be_invalid = Wallet.verify(Wallet().public_key, data, signature)
61+
print(f'should_be_invalid: {should_be_invalid}')
62+
63+
if __name__ == '__main__':
64+
main()

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pytest==5.1.2
22
Flask==1.1.1
33
pubnub==4.1.6
4-
requests==2.22.0
4+
requests==2.22.0
5+
cryptography==2.7

0 commit comments

Comments
 (0)