def main(): user = User() chain = Chain(user.identity, user.secret_key, user.public_key) # print(len(user.public_key)) chain.push_block("Pushing Test Test Test....".encode(), mime_type="application/json")
class Party: def __init__(self, genesis): self.chain = Chain(genesis) def block_arrival(self, chain): if chain[-1].height > self.chain[-1].height: self.chain = Chain.from_chain(chain) def play(self): self.chain.mine() return self.chain
def test_chain(self): blockchain = Chain() self.assertTrue(blockchain) # First block in the chain is always a genesis block. self.assertEqual(len(blockchain), 1) self.assertEqual(type(blockchain[0]), Block) self.assertEqual(blockchain[0].previous_hash, None) self.assertEqual(blockchain[0].transactions, [])
def __init__(self, genesis, k, m, mu_B): self.attack_phase = AttackPhase.DOUBLE_SPEND self.m = m self.k = k self.mu_B = mu_B self.bypass_level = mu_B self.bypass_level_blocks_seen = 0 self.min_bypass_level = 2 self.honest_chain = Chain(genesis) self.last_good_honest_block = None self.double_spend_block = None self.stitch_block = None self.blocks_mined = [] self.need_bypass = False self.adversarial_nipopow = NIPoPoW(k, m) self.adversarial_nipopow.chain.append(genesis) super().__init__(genesis)
def make_expected_distribution_superchain(self, length, interlink=False, gen=None): if gen is None: gen = Block.genesis() C = Chain(gen) for n in range(1, length + 1): C.mine() # expected distribution, OEIS A007814 if n % 2 == 1: lvl = 0 else: lvl = 1 + C[n // 2].level C[-1].level = lvl if interlink: C[-1].velvet_interlink = C[-1].real_interlink return C
def test_add_block(self): blockchain = Chain() # A block is appended in the end of the list(chain). transactions1 = [ 1, 2, 3, ] blockchain.register_block(transactions=transactions1) self.assertEqual(len(blockchain), 2) self.assertEqual(blockchain[-1].transactions, transactions1) transactions2 = [ 1, 2, 3, 4, ] blockchain.register_block(transactions=transactions2) self.assertEqual(len(blockchain), 3) self.assertEqual(blockchain[-1].transactions, transactions2) # The hashes are maintained along the chain. self.assertEqual(blockchain[0].this_hash, blockchain[1].previous_hash) self.assertEqual(blockchain[1].this_hash, blockchain[2].previous_hash)
def test_chain(self): G = Block.genesis() C = Chain() C.append(G) b = C.mine() self.assertEqual(len(C), 2) self.assertEqual(C[0], G) self.assertEqual(C[-1], b) self.assertEqual(C[0:2], C) self.assertEqual(len(C.slice(G, b)), 1) self.assertEqual(C[0].height, 0) self.assertEqual(C[1].height, 1) self.assertTrue(C.is_chained())
def test_verify_inconsistency(self): k = 1 m = 3 C = self.make_expected_distribution_superchain(2**7, True) C1 = Chain(C[-1]) for i in range(10): C1.mine() C1[-1].level = 30 C2 = self.make_expected_distribution_superchain(2**7, True, C[-1]) self.assertTrue(C1.is_chained()) self.assertTrue(C2.is_chained()) proof1 = NIPoPoW.prove(k, m, C1) proof2 = NIPoPoW.prove(k, m, C2) self.assertTrue(proof1.chain.is_chained()) self.assertTrue(proof2.chain.is_chained()) # a shorter chain with more superblocks wins # (this will never happen in practice for large values of m) self.assertWins(NIPoPoW.prove(k, m, C1), NIPoPoW.prove(k, m, C2))
def test_addressing(self): C = Chain(Block.genesis()) for n in range(100): C.mine() self.assertEqual(C[-1].height, 100) self.assertEqual(C[3:13], C[3:7].union(C[7:13])) self.assertEqual(C[3:13], C[7:13].union(C[3:7])) self.assertNotEqual(C[3:13], C[7:12].union(C[3:7])) self.assertNotEqual(C[3:13], C[7:13].union(C[3:6])) self.assertEqual(C.union(C), C) self.assertEqual(C.intersect(C), C)
def prove(cls, k, m, C): proof = NIPoPoW(k, m) if len(C) <= k: proof.chain = C return proof chi = C[-k:] stable_C = C[:-k] pi = Chain() b = C[0] for mu in range(len(stable_C[-1].real_interlink) + 1, -1, -1): stable_C = stable_C.slice(b) alpha = stable_C.upchain(mu) pi |= alpha if len(alpha) > m: b = alpha[-m] proof.chain = pi | chi return proof
def test_chain_validation(self): """A blockchain ledger should be immutable. To make sure we validate it by traversing through the chain to make sure previous hash of a block is indeed the hash of previous block.""" blockchain = Chain() transactions1 = [ 1, 2, 3, ] blockchain.register_block(transactions=transactions1) transactions2 = [ 1, 2, 3, 4, ] blockchain.register_block(transactions=transactions2) self.assertTrue(blockchain.isvalid()) # In case of any mutation the hash condition of the whole chain is invalid. blockchain[1].transactions[1] = 11 self.assertFalse(blockchain.isvalid())
def block_arrival(self, chain): block = chain[-1] if self.attack_phase > AttackPhase.STITCH and self.attack_phase < AttackPhase.SUFFIX: if block.level >= self.bypass_level: # A superblock has appeared which is of higher level than we want. # We need to bypass it. # (There could be multiple of these in a row) self.need_bypass = True self.bypass_level_blocks_seen += 1 if self.bypass_level_blocks_seen >= m: self.bypass_level -= 1 self.bypass_level_blocks_seen = 0 if self.bypass_level < self.min_bypass_level: self.attack_phase = AttackPhase.SUFFIX self.chain = Chain(self.last_good_honest_block) self.suffix_size = 0 else: if not self.need_bypass: self.last_good_honest_block = block self.adversarial_nipopow.chain.append(block) self.honest_chain = chain
def __init__(self, k, m): self.k = k self.m = m self.chain = Chain()
class NIPoPoW: @classmethod def prove(cls, k, m, C): proof = NIPoPoW(k, m) if len(C) <= k: proof.chain = C return proof chi = C[-k:] stable_C = C[:-k] pi = Chain() b = C[0] for mu in range(len(stable_C[-1].real_interlink) + 1, -1, -1): stable_C = stable_C.slice(b) alpha = stable_C.upchain(mu) pi |= alpha if len(alpha) > m: b = alpha[-m] proof.chain = pi | chi return proof @classmethod def score(cls, proof1, proof2): assert proof1.k == proof2.k and proof1.m == proof2.m, 'Proofs are incomparable' assert proof1.chain[0] == proof2.chain[0], 'Proofs must share a genesis block' k = proof1.k if len(proof1.chain) < k or len(proof2.chain) < k: # Comparison at the 0 level return proof1.chain[0], (len(proof1.chain), 0), (len(proof2.chain), 0) pi_1, chi_1 = proof1.chain[:-k], proof1.chain[-k:] pi_2, chi_2 = proof2.chain[:-k], proof2.chain[-k:] b = (pi_1 & pi_2)[-1] return b, proof1.best_arg(b), proof2.best_arg(b) def __init__(self, k, m): self.k = k self.m = m self.chain = Chain() def best_arg(self, b): k, m = self.k, self.m pi = self.chain[:-k] fork = pi.slice(b)[1:] best_score = 0 best_level = -1 for mu in range(len(pi[-1].real_interlink) + 1): argument = fork.count_upchain(mu) if argument >= m or mu == 0: mu_score = 2**mu * argument if mu_score > best_score: best_score = mu_score best_level = mu return best_score, best_level def __ge__(self, other): if not self.chain.is_chained(): return False if not other.chain.is_chained(): return True b, (score1, mu1), (score2, mu2) = NIPoPoW.score(self, other) return score1 >= score2
seeds = [(extra_seed[0], int(extra_seed[1]))] p2p = Network(seeds=seeds, address=('0.0.0.0', port), debug=True) # Chain root_block = SimpleBlock( links=[], work_target=10**6, total_work=10**6, timestamp=1412226468, nonce=529437, coinbase=PUB_KEY_X_FOR_KNOWN_SE, state_hash= 110737787655952643436062828845269098869204940693353997171788395014951100605706 ) chain = Chain(root_block, db, p2p) # Handlers set_message_handlers(chain, p2p) # inbuilt miner coinbase_miner = pubkey_for_secret_exponent(coinbase_se)[0] # get x coord miner = Miner(chain, p2p, coinbase_miner) logging.basicConfig(filename=log_filename, level=logging.DEBUG) # Create root if "-create_root" in sys.argv:
content_type = {'Content-Type': 'Application/json'} is_exe = getattr(sys, 'frozen', False) if is_exe: templates = path.join(sys._MEIPASS, 'templates') statics = path.join(sys._MEIPASS, 'static') else: templates = 'templates' statics = 'static' app = Flask(__name__, template_folder=templates, static_folder=statics) if len(sys.argv) < 2: print("Please provide port as cmd arg") sys.exit(1) port = int(sys.argv[1]) chain = Chain(port) #### API #### @app.route('/') def main(): return jsonify(chain), 200, content_type @app.route('/mine') def mine(): chain.mine() return jsonify(chain), 200, content_type
from blockchain import Chain, Node from client import Client import requests, pymongo, json # Instantiate the Node app = Flask(__name__) archive = Archive() node = Node() # protocol = Client() #Name Age, BloodType, Alergies chain = Chain( id= '3076301006072a8648ce3d020106052b8104002203620004c9f62827303857bfabdd6510dc43cb96d3c26d4533ea7a372d2e452f6e609d8074c7de1ae24298235ed7f26e753390c50bc854c18a7cab33598693bc3d9714087658c7859fcf5ee2d2c3796988399ebf653f2dd7aa913f0fb675eda6cff74a13', data={ "name": "Ben", "dob": "40", "bloodType": "A+", "allergies": "none", "doctorkey": "" }) chain2 = Chain( id= '3076301006072a8648ce3d020106052b8104002203620004f7454c81ef41950e6d56cb14a983b61720ec4d8943feee89d7e3a1e2384ab819ed5ffa180226e3c41a84a69810179a80c3738415e4ff8ff6be51c63f75f0ddb71c53c4fb4718409c067814a7d054e1faed5e30a8b6a87d5d5e9c088ea662fac8', data={ "name": "Ana", "dob": "21", "bloodType": "B+", "allergies": "none", "doctorkey": "" }) archive.add_record(chain)
import hashlib import json import utils from time import time from textwrap import dedent from uuid import uuid4 from flask import Flask, jsonify, request from blockchain import Chain app = Flask(__name__) node_id = str(uuid4()).replace('-', '') blockchain = Chain() @app.route('/chain/mine', methods=['GET']) def mine(): last_block = blockchain.last_block last_proof = blockchain.last_block['proof'] proof = blockchain.proof(last_proof) blockchain.new_transaction(sender="1", receiver=node_id, amount=1) pre_hash = utils.hash(last_block) block = blockchain.new_block(proof, pre_hash) response = { 'message': 'Forged new Block', 'index': block['id'], 'transactions': block['transactions'], 'pre_hash': block['pre_hash'] }
def __init__(self, genesis): self.chain = Chain(genesis)
def test_at_correct_level(self): k = 1 m = 3 # both chains will compare at level 30 # ensure there's at least m = 3 blocks of level 30 G = Block.genesis() C1 = Chain(G) C2 = Chain(G) # C1 has 3 blocks at 30 and then 10+k blocks at 0 for i in range(3): C1.mine() C1[-1].level = 30 for i in range(10 + k): C1.mine() C1[-1].level = 0 # C2 has 6 blocks at 30, then k blocks at 0 for i in range(6): C2.mine() C2[-1].level = 30 for i in range(k): C2.mine() C2[-1].level = 0 # Ensure only blocks of the right level count proof1 = NIPoPoW.prove(k, m, C1) proof2 = NIPoPoW.prove(k, m, C2) b, (score1, mu1), (score2, mu2) = NIPoPoW.score(proof1, proof2) self.assertEqual(mu1, 30) self.assertEqual(mu2, 30) self.assertEqual(b, G) self.assertEqual(score1, 2**30 * 3) self.assertEqual(score2, 2**30 * 6) assert (len(C1) > len(C2)) self.assertWins(proof2, proof1)
class Adversary(Party): def __init__(self, genesis, k, m, mu_B): self.attack_phase = AttackPhase.DOUBLE_SPEND self.m = m self.k = k self.mu_B = mu_B self.bypass_level = mu_B self.bypass_level_blocks_seen = 0 self.min_bypass_level = 2 self.honest_chain = Chain(genesis) self.last_good_honest_block = None self.double_spend_block = None self.stitch_block = None self.blocks_mined = [] self.need_bypass = False self.adversarial_nipopow = NIPoPoW(k, m) self.adversarial_nipopow.chain.append(genesis) super().__init__(genesis) def play(self): if self.attack_phase == AttackPhase.DOUBLE_SPEND: self.double_spend_block = self.chain.mine(True) self.blocks_mined.append(self.double_spend_block) self.adversarial_nipopow.chain.append(self.double_spend_block) self.attack_phase = AttackPhase.STITCH return None # withhold double spending block if self.attack_phase == AttackPhase.STITCH: self.stitch_block = self.honest_chain.mine(True) self.stitch_block.set_thorny_interlink([self.double_spend_block]) self.last_good_honest_block = self.stitch_block self.blocks_mined.append(self.stitch_block) self.adversarial_nipopow.chain.append(self.stitch_block) self.attack_phase = AttackPhase.GROW return self.honest_chain if self.attack_phase == AttackPhase.GROW: # discard = True if self.need_bypass: b = Block.mine(self.honest_chain[-1]) b.adversarial = True b.set_thorny_interlink([self.last_good_honest_block]) self.blocks_mined.append(b) if b.level < self.bypass_level: # Our block is of low enough level to stay under the radar # so we can use it for bypassing # Bypass any blocks between last_good_honest_block and b, # as they are blocks of a higher level than what we want. self.last_good_honest_block = b self.honest_chain.append(b) self.adversarial_nipopow.chain.append(b) # Bypass was successful. self.need_bypass = False # discard = False return self.honest_chain else: # Unfortunately, we mined a block of high level and this # cannot be used for bypassing (as b would then be included # by the honest prover into their proof), so we have to discard # this block and try again # discard = True pass # if not discard: # return b if self.attack_phase == AttackPhase.SUFFIX: b = self.chain.mine(True) self.blocks_mined.append(b) self.adversarial_nipopow.chain.append(b) self.suffix_size += 1 if self.suffix_size >= k and self.growth_completed(): self.attack_phase = AttackPhase.DONE return None # withhold suffix def block_arrival(self, chain): block = chain[-1] if self.attack_phase > AttackPhase.STITCH and self.attack_phase < AttackPhase.SUFFIX: if block.level >= self.bypass_level: # A superblock has appeared which is of higher level than we want. # We need to bypass it. # (There could be multiple of these in a row) self.need_bypass = True self.bypass_level_blocks_seen += 1 if self.bypass_level_blocks_seen >= m: self.bypass_level -= 1 self.bypass_level_blocks_seen = 0 if self.bypass_level < self.min_bypass_level: self.attack_phase = AttackPhase.SUFFIX self.chain = Chain(self.last_good_honest_block) self.suffix_size = 0 else: if not self.need_bypass: self.last_good_honest_block = block self.adversarial_nipopow.chain.append(block) self.honest_chain = chain def growth_completed(self): m = self.m mu_B = self.mu_B C = self.honest_chain.slice(self.stitch_block) if C.count_upchain(mu_B) < 2 * m: return False b = C[0] for mu in range(mu_B - 1, 0, -1): b = C.upchain(mu + 1)[m] C = C.slice(b) if C.count_upchain(mu) < 2 * m: return False return True def ready(self): return self.attack_phase == AttackPhase.DONE
def block_arrival(self, chain): if chain[-1].height > self.chain[-1].height: self.chain = Chain.from_chain(chain)