/
jaamocoin.py
139 lines (112 loc) · 4 KB
/
jaamocoin.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
133
134
135
136
137
138
139
import hashlib
import json
from time import time
#
# Very simple example of a cryptocurrency based on blockchain technology.
#
# Based on this tutorial:
# https://medium.com/coinmonks/python-tutorial-build-a-blockchain-713c706f6531
#
class JaamoCoin(object):
#
# Initialize the blockchain.
#
def __init__(self):
# This is the actual blockchain!
# Let's add a genesis block with some initial content.
# Also init the chain with 10 coins.
self.chain = [
{
"index": 1,
"timestamp": time(),
"sender": "god",
"recipient": "thebank",
"amount": 10,
"proof": 0,
"previous_hash": "A single JaamoCoin is worth of 500 000 Cinelli Supercorsa bicycles.",
}
]
#
# Adds new transaction and creates a block to the blockchain.
#
def new_transaction(self, sender, recipient, amount):
if self.get_balance(sender) < amount:
print("Can't transfer %s JCN from an account '%s'. Balance is %s." % (amount, sender, self.get_balance(sender)))
return False
# Create new block.
block = {
# Running index.
"index": len(self.chain) + 1,
# Add timestamp.
"timestamp": time(),
# Transaction details.
"sender": sender,
"recipient": recipient,
"amount": amount,
# This is the chain part of blockchain. Calculate has from previous block.
# If the previous block is ever altered this hash changes and the
# whole chain will change.
"previous_hash": self.hash(self.chain[-1]),
}
# Mine a proof to this block.
block["proof"] = self.mine_proof(block)
# Finally add our fresh new block to our blockchain!
self.chain.append(block)
#
# Calculate a verification hash for a block.
#
def hash(self, block):
string_object = json.dumps(block, sort_keys=True)
block_string = string_object.encode()
raw_hash = hashlib.sha256(block_string)
hex_hash = raw_hash.hexdigest()
return hex_hash
#
# This is the actual mining part. Try different kind of proofs
# to find a block hash that starts with four zeros.
#
# This takes time to calculate (proof of work) but is also very cheap
# to verify.
#
# Four zeros is not very complex to calculate
# but this is just an example.
#
def mine_proof(self, block):
# Just run through candidates for proof.
for x in range(10000):
block["proof"] = x
# Calculate block hash.
hex_hash = self.hash(block)
# Create binary representation of the hash
# and remove Python's "0b" prefix.
bin_hash = bin(int(hex_hash, 16))[2:]
# Leading zeros are omitted so we need to first pad the
# binary string with leading zeros. Then we take only
# the first four bits from the list.
hash_slice = bin_hash.zfill(256)[:4]
# Check if we found what we are looking for.
if hash_slice == "0000":
return x
# WTF?!! No proof found. Just return something.
# In reality this would fuck up things in real life.
return -1
#
# Get balance for given account. There's actually no concept
# of "account" in blockchain so the account balance needs to
# be calculated by looping through the whole blockchain.
#
def get_balance(self, account):
balance = 0
for block in self.chain:
if block["sender"] == account:
balance = balance - block["amount"]
if block["recipient"] == account:
balance = balance + block["amount"]
return balance
#
# Debug output.
#
def print(self):
print(json.dumps(self.chain, indent=2))
# Init an object
jcn = JaamoCoin()