Пример #1
0
    def create_block(cls):
        last_block = Block.last()
        previous_hash = last_block.block_id
        proof_of_work = ProofOfWork(previous_hash, 10)
        proof_result = proof_of_work.prove()

        if not proof_result.isValid():
            raise Exception('fail proof')

        transactions = UnconfirmedTransactionPool.transactions.copy()
        UnconfirmedTransactionPool.transactions.clear()
        block_number = len(Block.list()) + 1

        block = Block.build(
            block_number = block_number,
            version = "1",
            previous_block_hash = previous_hash,
            timestamp = datetime.now().timestamp(),
            merkle_root = "",  # TODO
            difficulty_target = 10,
            nonce = proof_result.nonce,
            transactions = transactions
        )

        for tx in transactions:
            tx.block_id = block.block_id

        Block.create_block(block)

        db.session.commit()

        transaction = cls._create_transaction_to_miner()

        return block, proof_result, transaction
Пример #2
0
 def test_block_mining(self):
     # Create example block
     h = "some hash"
     data = "some random data"
     block = Block(h, 0, [data], "1234")
     block.mine()
     self.assertEqual(
         block.block["hash"],
         "00015080dc53b9ab05840ec3cbebe26bb4c13059b9b8c828404a730fa32e134c")
Пример #3
0
    def _resolve_conflicts(cls, send_node_url):
        json = requests.get(send_node_url + '/blocks').json()
        send_node_blocks = decode_blocks(json)
        my_node_blocks = Block.list()

        forked_block_number = cls._search_forked_block_number(send_node_blocks, my_node_blocks)
        deleting_blocks = list(filter(lambda block: block.block_number > forked_block_number, my_node_blocks))
        adding_blocks = list(filter(lambda block: block.block_number > forked_block_number, send_node_blocks))
        Block.delete_blocks(deleting_blocks)
        Block.create_blocks(adding_blocks)
Пример #4
0
def block_delete():
    meta = {}

    ids = request.values.get('ids', '')
    type = request.values.get('type', 1)
    if not ids:
        return jsonify(success=False, message='缺少请求参数!')

    try:
        arr = ids.split(',')
        for d in arr:
            block = Block.objects(_id=ObjectId(d)).first()
            if block:
                is_pass = check_role(block.role)
                if is_pass:
                    block.mark_delete() if block else None
    except (Exception) as e:
        return jsonify(success=False, message=str(e))

    return jsonify(success=True,
                   message='操作成功!',
                   data={
                       'ids': ids,
                       'type': type
                   },
                   redirect_to=url_for('admin.block_list'))
Пример #5
0
    def receive_block(cls, block, proof_result, send_node_url):
        last_block = Block.last()

        if not proof_result.isValid():
            raise Exception('received block is invalid')

        if last_block.block_id != block.previous_block_hash:
            if last_block.block_number < block.block_number:
                print('resolving conflicting...')
                cls._resolve_conflicts(send_node_url)

        if last_block.block_id == block.previous_block_hash:
            Block.create_block(block)

        UnconfirmedTransactionPool.transactions.clear()
        db.session.commit()
Пример #6
0
    def test_block_creation(self):
        # Create genesis transaction
        transaction = Transaction("Genesis Addr", "Genesis Block")
        key = RSA.generate(1024)
        miner_id = "1234"
        # Create genesis block with genesis transaction, signing it
        genesis = Block("Genesis Block", 0, [transaction.get_signed_json(key)],
                        miner_id)

        self.assertDictEqual(
            genesis.get_json(), {
                "miner": miner_id,
                "hash": "",
                "prevHash": "Genesis Block",
                "height": 0,
                "nonce": 0,
                "data": [transaction.get_signed_json(key)]
            })
Пример #7
0
def decode_block(dictionary):
    return Block(block_id=dictionary['block_id'],
                 block_number=dictionary['block_number'],
                 previous_block_hash=dictionary['previous_block_hash'],
                 timestamp=dictionary['timestamp'],
                 merkle_root=dictionary['merkle_root'],
                 difficulty_target=dictionary['difficulty_target'],
                 nonce=dictionary['nonce'],
                 transactions=list(
                     map(lambda tx_dict: decode_transaction(tx_dict),
                         dictionary['transactions'])))
Пример #8
0
def block_list():
    meta = {
        'title': '配置管理',
        'css_nav_sub_block': 'active',
        'css_nav_system': 'active'
    }
    query = {}
    page = int(request.args.get('page', 1))
    per_page = 20
    status = int(request.args.get('status', 0))
    deleted = int(request.args.get('deleted', 0))
    page_url = url_for('admin.block_list', page="#p#", status=status)
    if status == -1:
        meta['css_disable'] = 'active'
        query['status'] = 0
    elif status == 1:
        query['status'] = 1
        meta['css_verify'] = 'active'
    elif status == 5:
        query['status'] = 5
        meta['css_success'] = 'active'
    else:
        meta['css_all'] = 'active'

    query['deleted'] = deleted
    current_app.logger.debug(type(g.user))

    data = Block.objects(**query).order_by('-created_at').paginate(
        page=page, per_page=per_page)
    total_count = Block.objects(**query).count()

    meta['data'] = data.items

    pager = Pager(page, per_page, total_count, page_url)
    meta['pager'] = pager.render_view()

    return render_template('admin/block/list.html', meta=meta)
Пример #9
0
def sync_local():
    node_blocks = []
    # Assuming that the folder and at least initial block exists
    data_dir = get_data_directory()
    if os.path.exists(data_dir):
        for filename in os.listdir(data_dir):
            # Check on the files that are stored in the required format.
            # No need to look in all the files
            if filename.endswith('.json'):
                filepath = '%s/%s' % (data_dir, filename)
            with open(filepath, 'r') as block_file:
                block_info = json.load(block_file)
                block_object = Block(**block_info)
                node_blocks.append(block_object)
    return node_blocks
Пример #10
0
def decode_block(dictionary):
    if dictionary['transactions'] is not None:
        transactions = decode_transactions(dictionary['transactions'])
    else:
        transactions = None

    return Block(
        block_id = dictionary['block_id'],
        block_number = dictionary['block_number'],
        version = dictionary['version'],
        previous_block_hash = dictionary['previous_block_hash'],
        timestamp = dictionary['timestamp'],
        merkle_root = dictionary['merkle_root'],
        difficulty_target = dictionary['difficulty_target'],
        nonce = dictionary['nonce'],
        transactions = transactions
    )
Пример #11
0
def get_block_content(mark, type=1):
    content = ''
    if not mark:
        return content
    try:
        query = {'mark': mark, 'status': 1}
        item = Block.objects(**query).first()
        if not item:
            return content

        if type == 1:
            content = item.code
        else:
            content = item.content

        return content
    except (Exception) as e:
        return content
Пример #12
0
def mine(last_block):
    index = int(last_block.index) + 1
    timestamp = datetime.utcnow()
    # random string for now
    data = "I block #%s" % (int(last_block.index) + 1)
    prev_hash = last_block.hash
    nonce = 0
    block_hash = calculate_hash(index, prev_hash, data, timestamp, nonce)
    while str(block_hash[0:num_zeores]) != '0' * num_zeores:
        nonce += 1
        block_hash = calculate_hash(index, prev_hash, data, timestamp, nonce)
    block_data = {}
    block_data['index'] = int(last_block.index) + 1
    block_data['timestamp'] = timestamp
    block_data['data'] = "I block #%s" % last_block.index
    block_data['prev_hash'] = last_block.hash
    block_data['hash'] = block_hash
    block_data['nonce'] = nonce
    return Block(**block_data)
Пример #13
0
def block_submit():
    meta = {
        'title': '配置管理',
        'css_nav_sub_block': 'active',
        'css_nav_system': 'active'
    }
    meta['referer_url'] = request.environ.get(
        'HTTP_REFERER') if request.environ.get('HTTP_REFERER') else ''
    id = request.args.get('id', None)
    meta['data'] = None
    if id:
        block = Block.objects(_id=ObjectId(id)).first()
        meta['data'] = block

    form = SaveForm()

    #current_app.logger.debug(id)

    return render_template('admin/block/submit.html', meta=meta, form=form)
Пример #14
0
 def create_and_add_block(self, miner_id):
     """
     Using miner_id and current transaction_pool, create block and add to chain.
     """
     block = None
     if not self.empty():
         # Get last block
         prevBlock = self.storage[-1]
         # Use it to create new block with the current transactions in pool
         block = Block(prevBlock["hash"], prevBlock["height"] + 1,
                       self.transaction_pool, miner_id)
         block.mine()
         logger.info("Block created: {}".format(block.get_json()))
         self.validate_and_add_block(block.get_json())
     return block
Пример #15
0
def sync_overall(save=False):
    best_chain = Chain(sync_local())
    for peer in PEERS:
        # try to connect to peer
        peer_blockchain_url = peer + 'blockchain.json'
        try:
            r = requests.get(peer_blockchain_url)
            peer_blockchain_dict = r.json()
            peer_blocks = [Block(**bdict) for bdict in peer_blockchain_dict]
            peer_chain = Chain(peer_blocks)

            if peer_chain.is_valid() and peer_chain > best_chain:
                best_chain = peer_chain

        except requests.exceptions.ConnectionError:
            print "Peer at %s not running. Continuing to next peer." % peer

    print "Longest blockchain is %s blocks" % len(best_chain)
    # for now, save the new blockchain over whatever was there
    if save:
        best_chain.save()
    return best_chain
Пример #16
0
 def seed(cls):
     timestamp = 0
     block = Block.build(block_number=1,
                         version='1',
                         previous_block_hash='1',
                         timestamp=1,
                         merkle_root='',
                         difficulty_target=10,
                         nonce=1)
     transaction = Transaction.build(block_id='1',
                                     locktime=0,
                                     timestamp=timestamp)
     transaction_output = TransactionOutput.build(
         transaction_id='1',
         amount=10000000000000000000,
         sender_address='coinbase',
         recipient_address=
         '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznjoHvzCJtQcIYd3yj7v\ngwaPlyiG6U/Qlw1G89n0bNt5anvRe+e2eKzvpy98aj6ShGu7hARE9SxAFA9bIHCB\nqdAyPnrUaw7qGkeZNPHBByHe9prJSn0ZwBtfySOSbzdetO5aAwvLj5qMudW2PDz1\n5mP2taGOvXqNnbcH78ZHQLvF6G+SbwuLHU5LEDSZlcy+CnvPqD67cg+QmJLneVmQ\nfOBtbFHz3yDQghNrHWa+UCspUMHVGsDG6OEK7MSpPieY6TzBEYQWsikosQ+V0zBN\nrSCADe3GBcJ7XzafM/gb+gzJ1eP78F1sA6Ja4ZtqInqN406PwerAXaUJa2twW652\n9wIDAQAB\n-----END PUBLIC KEY-----',
         timestamp=timestamp)
     db.session.add(block)
     db.session.add(transaction)
     db.session.add(transaction_output)
     db.session.commit()
Пример #17
0
    def _create_block(cls):
        last_block = Blockchain.fetch_last_block()

        previous_hash = last_block.block_id
        block_number = Blockchain.fetch_block_count() + 1

        proof_of_work = ProofOfWork(previous_hash,
                                    last_block.difficulty_target)
        proof_result = proof_of_work.prove()

        proof_result.assert_valid()

        transactions = UnconfirmedTxPool.transactions.copy()
        UnconfirmedTxPool.transactions.clear()

        target_transactions = Blockchain.search_new_transactions(transactions)

        block = Block.build(
            block_number=block_number,
            previous_block_hash=previous_hash,
            timestamp=datetime.now().timestamp(),
            merkle_root="",  # TODO
            difficulty_target=last_block.difficulty_target,
            nonce=proof_result.nonce,
            transactions=target_transactions)

        last_block = Blockchain.fetch_last_block()
        if last_block.block_id != block.previous_block_hash:
            print('lost mining', block.block_id)
            raise LoseMiningException()

        Blockchain.create_block(block)
        print('block created', block.block_id)
        print('current block number', block.block_number)

        return block, proof_result
Пример #18
0
from app.models.chain import Chain
from static.test import test_data

block_zero_dir = test_data[0]
block_one_dir = test_data[1]
block_two_dir = test_data[2]
block_three_dir = test_data[3]
block_three_later_in_time_dir = test_data[4]

###########################
#
# Block time
#
###########################

block_zero = Block(**block_zero_dir)
another_block_zero = Block(**block_zero_dir)
assert block_zero.is_valid()
assert block_zero == another_block_zero
assert not block_zero != another_block_zero

block_one = Block(**block_one_dir)
another_block_one = Block(**block_one_dir)
assert block_one.is_valid()
assert block_one == another_block_one
assert not block_one != another_block_one

block_two = Block(**block_two_dir)
another_block_two = Block(**block_two_dir)
assert block_two.is_valid()
assert block_two == another_block_two
Пример #19
0
 def assert_new_block(cls, block_id):
     block = Block.find(block_id)
     return block is None
Пример #20
0
 def list_blocks(cls):
     return Block.list()
Пример #21
0
 def find_by_block_number(cls, block_number):
     return Block.find_by_block_number(block_number)
Пример #22
0
    def test_block_validation(self):
        chain = Blockchain()
        private_key = RSA.generate(1024)
        miner_id = "1234"
        chain.create_genesis_block(private_key, miner_id)
        prevBlock = chain.storage[0]
        t = Transaction("1234", "4567")
        # Create Block with dummy transaction
        block = Block(prevBlock["hash"], prevBlock["height"] + 1,
                      [t.get_signed_json(private_key)], miner_id)
        block.mine()

        # Check block validation is ok
        self.assertTrue(chain.validate_block(block.get_json(), prevBlock))

        # Mess with blockchain structure
        block.block["prevHash"] = "00012345"
        self.assertFalse(chain.validate_block(block.get_json(), prevBlock))

        # Mess with height
        block.block["prevHash"] = prevBlock["hash"]
        block.block["height"] = 5
        self.assertFalse(chain.validate_block(block.get_json(), prevBlock))

        # Mess with PoW
        block.block["height"] = 2
        block.block["hash"] = "0111111111"
        self.assertFalse(chain.validate_block(block.get_json(), prevBlock))

        # Mess with hash but keep PoW
        block.block["hash"] = "0001111111"
        self.assertFalse(chain.validate_block(block.get_json(), prevBlock))

        # Mess with transaction integrity
        t.signature = "L7TBH0ahox4GOAdF8om2ijbNVPcO3Ys6+KdvfFhvfX/SysetaJw+0rlU6VMuzwB0rQ/X2+ioAdtXcstutSeRAfZTYP+utaNFL1nP48as/C6mca4sp+ya39AWWLIUuZeGMit9kSUavx6uX5cSAuqXB4tcK/bUSVghtMC9vG4JyC8="
        block = Block(prevBlock["prevHash"], prevBlock["height"] + 1,
                      [t.get_signed_json(private_key)], miner_id)
        block.mine()
        self.assertFalse(chain.validate_block(block.get_json(), prevBlock))
Пример #23
0
class Blockchain:
    blocks = [
        Block.build(
            block_number=1,
            previous_block_hash="1",
            timestamp=0,
            merkle_root="",
            difficulty_target=20,
            nonce=0,
            transactions=[
                Transaction.build(
                    timestamp=1,
                    tx_inputs=[],
                    tx_outputs=[
                        TransactionOutput.build(
                            amount=1000000000,
                            sender_address=COINBASE_ADDRESS,
                            recipient_address=
                            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznjoHvzCJtQcIYd3yj7vgwaPlyiG6U/Qlw1G89n0bNt5anvRe+e2eKzvpy98aj6ShGu7hARE9SxAFA9bIHCBqdAyPnrUaw7qGkeZNPHBByHe9prJSn0ZwBtfySOSbzdetO5aAwvLj5qMudW2PDz15mP2taGOvXqNnbcH78ZHQLvF6G+SbwuLHU5LEDSZlcy+CnvPqD67cg+QmJLneVmQfOBtbFHz3yDQghNrHWa+UCspUMHVGsDG6OEK7MSpPieY6TzBEYQWsikosQ+V0zBNrSCADe3GBcJ7XzafM/gb+gzJ1eP78F1sA6Ja4ZtqInqN406PwerAXaUJa2twW6529wIDAQAB",
                            timestamp=1)
                    ]),
                Transaction.build(
                    timestamp=1,
                    tx_inputs=[],
                    tx_outputs=[
                        TransactionOutput.build(
                            amount=200000000,
                            sender_address=COINBASE_ADDRESS,
                            recipient_address=
                            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznjoHvzCJtQcIYd3yj7vgwaPlyiG6U/Qlw1G89n0bNt5anvRe+e2eKzvpy98aj6ShGu7hARE9SxAFA9bIHCBqdAyPnrUaw7qGkeZNPHBByHe9prJSn0ZwBtfySOSbzdetO5aAwvLj5qMudW2PDz15mP2taGOvXqNnbcH78ZHQLvF6G+SbwuLHU5LEDSZlcy+CnvPqD67cg+QmJLneVmQfOBtbFHz3yDQghNrHWa+UCspUMHVGsDG6OEK7MSpPieY6TzBEYQWsikosQ+V0zBNrSCADe3GBcJ7XzafM/gb+gzJ1eP78F1sA6Ja4ZtqInqN406PwerAXaUJa2twW6529wIDAQAB",
                            timestamp=1)
                    ]),
                Transaction.build(
                    timestamp=1,
                    tx_inputs=[],
                    tx_outputs=[
                        TransactionOutput.build(
                            amount=300003,
                            sender_address=COINBASE_ADDRESS,
                            recipient_address=
                            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznjoHvzCJtQcIYd3yj7vgwaPlyiG6U/Qlw1G89n0bNt5anvRe+e2eKzvpy98aj6ShGu7hARE9SxAFA9bIHCBqdAyPnrUaw7qGkeZNPHBByHe9prJSn0ZwBtfySOSbzdetO5aAwvLj5qMudW2PDz15mP2taGOvXqNnbcH78ZHQLvF6G+SbwuLHU5LEDSZlcy+CnvPqD67cg+QmJLneVmQfOBtbFHz3yDQghNrHWa+UCspUMHVGsDG6OEK7MSpPieY6TzBEYQWsikosQ+V0zBNrSCADe3GBcJ7XzafM/gb+gzJ1eP78F1sA6Ja4ZtqInqN406PwerAXaUJa2twW6529wIDAQAB",
                            timestamp=1)
                    ]),
            ])
    ]

    @classmethod
    def fetch_all_blocks(cls):
        return cls.blocks

    @classmethod
    def fetch_block_count(cls):
        return len(cls.blocks)

    @classmethod
    def fetch_last_block(cls):
        return cls.blocks[-1]

    @classmethod
    def fetch_unspent_tx_outputs_by_tx_output_ids(cls, tx_output_ids):
        blocks = cls.blocks
        if len(blocks) == 0:
            return []

        transactions = reduce(
            add, list(map(lambda block: block.transactions, blocks)))
        if len(transactions) == 0:
            return []

        tx_outputs = reduce(add,
                            list(map(lambda tx: tx.tx_outputs, transactions)))

        tx_inputs = reduce(add, list(map(lambda tx: tx.tx_inputs,
                                         transactions)))
        spent_tx_output_ids = list(
            map(lambda tx_i: tx_i.transaction_output_id, tx_inputs))

        unspent_tx_outputs = list(
            filter(
                lambda tx_o: tx_o.transaction_output_id not in
                spent_tx_output_ids, tx_outputs))
        return list(
            filter(lambda tx_o: tx_o.transaction_output_id in tx_output_ids,
                   unspent_tx_outputs))

    @classmethod
    def fetch_unspent_tx_outputs_by_address(cls, address):
        blocks = cls.blocks
        if len(blocks) == 0:
            return []

        transactions = reduce(
            add, list(map(lambda block: block.transactions, blocks)))
        if len(transactions) == 0:
            return []

        tx_outputs = reduce(add,
                            list(map(lambda tx: tx.tx_outputs, transactions)))
        tx_inputs = reduce(add, list(map(lambda tx: tx.tx_inputs,
                                         transactions)))
        spent_tx_output_ids = list(
            map(lambda tx_i: tx_i.transaction_output_id, tx_inputs))

        return list(
            filter(
                lambda tx_o: tx_o.recipient_address == address and tx_o.
                transaction_output_id not in spent_tx_output_ids, tx_outputs))

    @classmethod
    def create_block(cls, block):
        cls.blocks.append(block)

    @classmethod
    def search_new_transactions(cls, transactions):
        transactions_in_chain = reduce(
            add, list(map(lambda block: block.transactions, cls.blocks)))
        return list(
            filter(lambda tx: tx not in transactions_in_chain, transactions))

    @classmethod
    def delete_block(cls, deleting_block):
        cls.blocks.remove(deleting_block)

    @classmethod
    def find_block(cls, block_id):
        blocks = list(
            filter(lambda block: block.block_id == block_id, cls.blocks))
        if len(blocks) == 0:
            return None
        return blocks[0]