Ejemplo n.º 1
0
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")
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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, [])
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
 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())
Ejemplo n.º 8
0
    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))
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    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())
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
 def __init__(self, k, m):
     self.k = k
     self.m = m
     self.chain = Chain()
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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:
Ejemplo n.º 16
0
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

Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
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']
    }
Ejemplo n.º 19
0
 def __init__(self, genesis):
     self.chain = Chain(genesis)
Ejemplo n.º 20
0
    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)
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
 def block_arrival(self, chain):
     if chain[-1].height > self.chain[-1].height:
         self.chain = Chain.from_chain(chain)