示例#1
0
 def RecNodeInfo(self):
     data, addr = s.recvfrom(1024)
     g_Flag = 1
     print ('Received from %s:%s.' % addr, data)
     
     rece_blockheight = data[0:8]
     int_blockheight = int(rece_blockheight,10)
     rece_blockhash = data[8:40]
     if(int_blockheight > self.blockheight):
         BlockChain.setBlockChain(self,int_blockheight,rece_blockhash)
         g_Flag = 0
class ProcessContentTestCase(unittest.TestCase):
    filename = 'test_contentprocessing.dat'
    zero_digest = bytes(32)

    def setUp(self):
        self.block_chain = BlockChain()
        self.content_queue = queue.Queue()
        logging.debug('setUp')

    def tearDown(self):
        logging.debug('tearDown')
        del self.content_queue
        del self.block_chain

    def test_01(self):
        logging.debug('Start test_01')
        kwargs = {}
        kwargs['content_queue'] = self.content_queue
        kwargs['block_chain' ] = self.block_chain

        pct = ProcessContent(name='ProcessContentThread', kwargs=kwargs)

        pct.start()
        # For checking purposes, each content should be unique
        input_content = (b'abc', b'def', b'Love is in the air!')
        for i in input_content:
            self.content_queue.put(i)

        self.content_queue.put(None)
        self.content_queue.join()
        pct.join()

        # Now check the created block chain
        received_content = {}
        digest = self.block_chain.getLastBlockDigest()
        while digest != self.zero_digest:
            block = self.block_chain.getBlockWithDigest(digest)
            raw_content = block.getContent()
            received_content[raw_content] = True
            logging.info(raw_content)
            digest = block.getPreviousBlockHash()

        # Verify that there is one block with content for
        # each content input.
        for c in input_content:
            self.assertTrue(c in received_content, 'No block generated for ' + c.decode('utf-8'))

        logging.debug('End test_01')
示例#3
0
class BlockChainTestCase(unittest.TestCase):
    filename = 'test_blockchain.dat'
    content = ['The quick brown fox jumps over the lazy dog.', 'Another day, another 50 cents.', "All's well that ends well", 'Four score and seven years ago...']
    zero_digest = bytes(32)

    def setUp(self):
        self.block_chain = BlockChain()
        self.factory = BlockFactory()

    def tearDown(self):
        del self.block_chain
        del self.factory

    def test_saveToFile(self):
        num_contents = len(self.content)
        for i in range(num_contents):
            self.createBlock(self.content[i])

        block_count = self.block_chain.saveToFile(self.filename)
        self.assertEqual(block_count, num_contents, 'Incorrect block count')

    def test_loadFromFile(self):
        blocks_loaded = self.block_chain.loadFromFile(self.filename)
        for i in range(blocks_loaded):
            content = self.block_chain.getBlockContent(i)
            content_string = content.decode('utf-8')
            self.assertEqual(self.content[i], content_string, 'Wrong content loaded')

    def test_walkChain(self):
        # Load the block chain
        blocks_loaded = self.block_chain.loadFromFile(self.filename)
        self.assertTrue(blocks_loaded > 0, "No blocks loaded!")
        # start with the top

        digest = self.block_chain.getLastBlockDigest()
        while digest != self.zero_digest:
            block = self.block_chain.getBlockWithDigest(digest)
            content = block.getContent()
            logging.debug('content: %s; digest: %s', content.decode('utf-8'), digest.hex())
            digest = block.getPreviousBlockHash()

    def createBlock(self, text):
        content = text.encode()
        block_object = self.factory.createNew(content)
        pbhd = self.block_chain.getLastBlockDigest()
        block_object.farm(pbhd)
        height = self.block_chain.addBlock(block_object)
示例#4
0
    def SelWinner(self):
        if g_Flag == 0:
            for blockheight in range(MAX_BLOCKHEIGHT):
                loop = asyncio.new_event_loop()
                blockhash, winner = loop.run_until_complete(self.powNextblock())
                loop.close()
                if blockheight % ELECT_GAP == 7:
                    self.pow_nodes, self.verify_nodes = self.elect()
                    print(''.join('-' for _ in range(50)))
                    print('POW_NODES: ' + ' '.join(node.txid for node in self.pow_nodes))
                    print('VERYFI_NODES: ' + ' '.join(node.txid for node in self.verify_nodes))
                    print(''.join('-' for _ in range(50)))
                if blockheight % VERIFY_GAP == 3:
                    pass
                self.nextBlock(blockhash)
            
                data = BlockChain.getBlockChain(self)

                for i in iter(g_ListIP):
                    s.sendto(data.encode(), (g_ListIP[i], port))
        pass
示例#5
0
from flask import Flask, request
import requests
import json
import time

from blockchain import BlockChain
from block import Block

# Initialize flask aplication
app = Flask(__name__)
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True

#Initialize a blockchain object
blockchain = BlockChain()
blockchain.build_genesis()

# User ID
# TODO add account handling
userID = "miner1337"

# Contains the host addresses of other participating members of the network
peers = set()


@app.route('/new_transaction', methods=['POST'])
def new_transaction():
    tx_data = request.get_json()
    required_fields = ["sender", "recipient", "amount"]

    for field in required_fields:
        if not tx_data.get(field):
示例#6
0
from flask import Flask, jsonify, request, send_from_directory
from flask_cors import CORS

from wallet import Wallet
from blockchain import BlockChain

app = Flask(__name__)
wallet = Wallet()
blockchain = BlockChain(wallet.public_key)
CORS(app)


@app.route('/wallet', methods=['POST'])
def create_keys():
    wallet.create_keys()
    if wallet.save_keys():
        global blockchain
        blockchain = BlockChain(wallet.public_key)
        response = {
            'public_key': wallet.public_key,
            'private_key': wallet.private_key,
            'funds': blockchain.get_balance(),
        }
        return jsonify(response), 201
    else:
        response = {'message': 'Saving the keys failed.'}
        return jsonify(response), 500


@app.route('/wallet', methods=['GET'])
def load_keys():
示例#7
0
class Monopoly:
    def __init__(self, num_players):
        self.board = Board()
        self.draw = Draw()
        self.blockchain = BlockChain()
        self.banker = Bank()
        self.num_players = num_players
        self.players = []
        for player_index in range(num_players):
            name = input('Enter Player {}\'s Name: '.format(player_index + 1))
            self.players.append(Player(name, player_index + 1))

        # Initialize the accounts of all players with 1500 Monopoly Coin
        self.blockchain.initialize_accounts(self.players)

        # Initialize all properties. By default the owner of all properties is the bank
        self.blockchain.initialize_properties(self.board.get_all_properties())

    @staticmethod
    def roll_dice():
        return random.randint(1, 6), random.randint(1, 6)

    def play_game(self, automatic=True):
        if automatic:
            while not self.game_over():
                for player in self.players:
                    self.serve_turn(player, 0)
        else:
            game_ended = False
            while not game_ended:
                for player in self.players:
                    cont = input('\nContinue? Y/N: ')
                    if cont == 'Y' or cont == 'y':
                        self.serve_turn(player, 0)
                    else:
                        winner = None
                        highest_assets = 0
                        for player in self.players:
                            if not player.state == PlayerState.DONE:
                                assets = player.add_assets(
                                    self.blockchain, self.board)
                                if highest_assets < assets:
                                    winner = player
                                    highest_assets = assets
                        game_ended = True
                        print('Winner is {}. Game Ended. Bye!'.format(winner))

    # ---------- Serving Methods ------------
    def serve_turn(self, player, num_doubles):
        if num_doubles == 0:
            print('\n{} is up! Starting balance: ${}'.format(
                str(player), player.get_balance(self.blockchain)))

        roll = self.roll_dice()
        print('{} rolled: {}'.format(str(player), roll))
        if num_doubles == 2 and roll[0] == roll[1]:
            self.go_to_jail(player)
        elif player.in_jail:
            self.serve_jail(player, roll)
        else:
            trade = input('Would you like to make a trade? Y/N: ')
            if trade == 'Y' or trade == 'y':
                self.serve_trade(player)
            edit = input('Would you like to edit properties? Y/N: ')
            if edit == 'Y' or edit == 'y':
                self.serve_prop_edit(player)
            self.serve_normally(player, roll)
            if roll[0] == roll[1]:
                self.serve_turn(player, num_doubles + 1)

        if num_doubles == 0:
            print('{}\'s turn is over! Ending balance: ${}'.format(
                str(player), player.get_balance(self.blockchain)))

    def serve_normally(self, player, roll):
        position = (player.position + roll[0] + roll[1]) % 40
        space = self.board.get_property_at_index(position)
        print('{} landed on: {}'.format(str(player), space.name))
        self.move_player_to(player, position)

        if space.type == 'Draw':
            self.serve_draw(player, space)
        elif space.type == 'Special':
            self.serve_special_space(player, space)
        else:
            self.serve_property(player, space)

    def serve_jail(self, player, roll):
        player.jail_rolls += 1
        if roll[0] == roll[1] or player.jail_rolls == 3:
            print('{} got out of Jail!'.format(str(player)))
            player.jail_rolls = 0
            player.in_jail = False
            self.serve_normally(player, roll)
        else:
            print('{} is still in Jail!'.format(str(player)))

    def serve_draw(self, player, space):
        draw = self.draw.draw_card(space.draw_type)
        print('{} drew: {}'.format(str(player), draw.description))

        if draw.type == 'Pay':
            player.pay(self.banker, draw.amount, self.blockchain)
        elif draw.type == 'Pay All':
            for player_ in self.players:
                if player_ != player:
                    player.pay(player_, draw.amount, self.blockchain)
        elif draw.type == 'Receive':
            self.banker.pay(player, draw.amount, self.blockchain)
        elif draw.type == 'Receive All':
            for player_ in self.players:
                if player_ != player:
                    player_.pay(player, draw.amount, self.blockchain)
        elif draw.type == 'Move':
            if draw.name != 'Go to Jail':
                move_space = self.board.get_property_at_index(draw.index)
                print('{} moved to: {}'.format(str(player), str(move_space)))
                self.move_player_to(player, move_space.index)
                if move_space.type != 'Draw' and move_space.type != 'Special':
                    self.serve_property(player, move_space)
            else:
                self.go_to_jail(player)
        elif draw.type == 'Special':
            if draw.name == 'Street Repairs' or draw.name == 'Property Repairs':
                houses = 0
                hotels = 0
                for index in self.blockchain.get_all_properties(player):
                    houses += self.blockchain.get_houses(index)
                    hotels += self.blockchain.get_hotel(index)
                print(
                    '{} has {} houses and {} hotels and must pay ${}.'.format(
                        player, houses, hotels, houses * draw.house_amount +
                        hotels * draw.hotel_amount))
                player.pay(
                    self.banker,
                    houses * draw.house_amount + hotels * draw.hotel_amount,
                    self.blockchain)
            elif draw.name == 'Advance to Utility':
                if abs(player.position - 12) >= abs(player.position - 28):
                    index = 28
                else:
                    index = 12
                self.move_player_to(player, index)
                print('{} moved to: {}'.format(
                    player,
                    self.board.get_property_at_index(index).name))
                self.serve_property(player,
                                    self.board.get_property_at_index(index),
                                    draw.name)
            elif draw.name == 'Advance to Railroad 1' or draw.name == 'Advance to Railroad 2':
                if player.position == 7:
                    index = 5
                elif player.position == 22:
                    index = 25
                else:
                    index = 35
                self.move_player_to(player, index)
                print('{} moved to: {}'.format(
                    player,
                    self.board.get_property_at_index(index).name))
                self.serve_property(player,
                                    self.board.get_property_at_index(index),
                                    draw.multiplier)

    def serve_special_space(self, player, space):
        if space.name == 'Income Tax':
            decision = input(
                'Pay 10% of assets or $200: Y for 10%, N for $200: ')
            if decision == 'Y' or decision == 'y':
                player.pay(
                    self.banker,
                    player.add_assets(self.blockchain, self.board) // 10,
                    self.blockchain)
            else:
                player.pay(self.banker, 200, self.blockchain)
        elif space.name == 'Luxury Tax':
            print('Pay $75 for Luxury Tax')
            player.pay(self.banker, 75, self.blockchain)

    def serve_property(self, player, space, multiplier=1):
        owner_address = self.blockchain.get_property_owner(space.index)
        if owner_address == self.blockchain.get_account(self.banker):
            self.serve_banker(owner_address, player, space)
        elif owner_address == self.blockchain.get_account(player):
            print('Welcome back home {}!'.format(player))
        else:
            self.serve_other_owner(multiplier, owner_address, player, space)

    def serve_banker(self, owner_address, player, space):
        decision = input(
            '{} is unowned! It costs ${}. Want to see a description? Y/N: '.
            format(space, space.price))
        if decision == 'Y' or decision == 'y':
            self.describe_property(space)
        decision = input(
            'Current Balance: ${}. Would you like to buy it? Y/N: '.format(
                player.get_balance(self.blockchain)))
        if decision == 'Y' or decision == 'y':
            if self.blockchain.change_ownership(owner_address, player,
                                                space.index, space.price):
                print('Congrats! You bought {}!'.format(space))
            else:
                print('Couldn\'t buy {}... :('.format(space))

    def serve_other_owner(self, multiplier, owner_address, player, space):
        owner = None
        for player_ in self.players:
            if self.blockchain.get_account(player_) == owner_address:
                owner = player_
                break
        if not self.blockchain.get_mortgage(space.index):
            if space.type == 'Utility':
                other_utility = 28 if space.index == 12 else 12
                if owner_address == self.blockchain.get_property_owner(
                        other_utility) or multiplier == 10:
                    rent = sum(self.roll_dice()) * 10
                else:
                    rent = sum(self.roll_dice()) * 4
            elif space.type == 'Station':
                rent = space.standard_rent
                other_stations = [
                    s for s in [5, 15, 25, 35] if s != space.index
                ]
                for station_index in other_stations:
                    if owner_address == self.blockchain.get_property_owner(
                            station_index):
                        rent += space.standard_rent
            else:
                rent = space.standard_rent
                layout = (self.blockchain.get_houses(space.index),
                          self.blockchain.get_hotel(space.index))
                if layout[0]:
                    if layout[0] == 1:
                        rent = space.one_house_rent
                    elif layout[0] == 2:
                        rent = space.two_house_rent
                    elif layout[0] == 3:
                        rent = space.three_house_rent
                    else:
                        rent = space.four_house_rent
                elif layout[1]:
                    rent = space.hotel_rent
                else:
                    other_properties = [
                        s for s in self.board.monopolies[space.group]
                        if s != space.index
                    ]
                    monopoly = True
                    for index in other_properties:
                        if self.blockchain.get_property_owner(
                                index) != owner_address:
                            monopoly = False
                            break
                    if monopoly:
                        rent *= 2
            print('Uh oh. You owe {} ${}.'.format(owner, rent * multiplier))
            player.pay(owner,
                       rent * multiplier,
                       self.blockchain,
                       critical=True,
                       board=self.board)
        else:
            print('You lucky duck, {} is mortgaged. Enjoy your free stay!'.
                  format(space))

    def serve_trade(self, player):
        all_properties = player.describe_all_properties(
            self.blockchain, self.board)  # Prints all properties as well
        keep_trading = True
        while keep_trading:
            trade_index = int(input('Index to trade: '))
            if trade_index in all_properties:
                buyer = int(input('Enter player number to trade with: '))
                if buyer - 1 < len(self.players) and buyer > 0:
                    buyer = self.players[buyer - 1]
                    sell_property = self.board.get_property_at_index(
                        trade_index)
                    price = int(input('Enter amount to offer: '))
                    buyer_decision = input(
                        'Would {} like to buy {} for ${}? Y/N: '.format(
                            buyer, sell_property, price))
                    if buyer_decision == 'Y' or buyer_decision == 'y':
                        player.sell_property(buyer, sell_property, price,
                                             self.blockchain)
                    else:
                        print('{} rejected the offer.'.format(buyer))
                else:
                    print('{} is not a valid player index, try again.'.format(
                        buyer))
            else:
                print('{} is not an index you can trade, try again tiger.'.
                      format(trade_index))
            decision = input('Continue trading? Y/N: ')
            if not decision == 'Y' and not decision == 'y':
                keep_trading = False

    def serve_prop_edit(self, player):
        all_properties = player.describe_all_properties(
            self.blockchain, self.board)  # Prints all properties as well
        keep_editing = True
        while keep_editing:
            edit_index = int(input('Index to edit: '))
            if edit_index in all_properties:
                player.edit_property(self.blockchain, self.board, edit_index)
            decision = input('Continue editing? Y/N: ')
            if not decision == 'Y' and not decision == 'y':
                keep_editing = False

    # Describes a property's rent and mortgage
    @staticmethod
    def describe_property(space):
        if space.type == 'Utility':
            print(
                '     If one utility is owned rent is 4 times amount shown on dice.\n'
                +
                '     If both utilities are owned rent is 10 times amount shown on dice.'
            )
        elif space.type == 'Station':
            print('     Rent ${}\n'.format(space.standard_rent) +
                  '     If 2 stations are owned ${}\n'.format(
                      space.standard_rent * 2) +
                  '     If 3 stations are owned ${}\n'.format(
                      space.standard_rent * 3) +
                  '     If 4 stations are owned ${}'.format(
                      space.standard_rent * 4))
        else:
            print('     Color Group: {}\n'.format(space.group) +
                  '     Rent ${}\n'.format(space.standard_rent) +
                  '     With 1 House ${}\n'.format(space.one_house_rent) +
                  '     With 2 Houses ${}\n'.format(space.two_house_rent) +
                  '     With 3 Houses ${}\n'.format(space.three_house_rent) +
                  '     With 4 Houses ${}\n'.format(space.four_house_rent) +
                  '     With Hotel ${}'.format(space.hotel_rent))
        print('     Mortgage Value: ${}'.format(space.mortgage))

    # Moves a player to the given index. If at 30, the player goes to jail
    def move_player_to(self, player, index):
        if index < player.position:
            print('{} passed Go!'.format(str(player)))
            self.banker.pay(player, 200, self.blockchain)
        if index == 30:
            self.go_to_jail(player)
        else:
            player.position = index

    @staticmethod
    def go_to_jail(player):
        print('{} went to Jail!'.format(player))
        player.in_jail = True
        player.position = 10

    def game_over(self):
        finished_players = 0
        for player in self.players:
            if player.state == PlayerState.DONE:
                finished_players += 1
        if finished_players - 1 == len(self.players):
            return True
        else:
            return False
示例#8
0
def cli_create_bc(Addr):
    blk_chain = BlockChain()
    blk_chain.createGenesisblock(Addr)
示例#9
0
from block import Block
from blockchain import BlockChain

if __name__ == '__main__':
    block_chain = BlockChain()
    block_chain.mine_block("第一个交易是转账10块")
    block_chain.mine_block("第二个交易是转账20")
    block_chain.print_chain()
from blockchain import BlockChain

if __name__ == '__main__':
    my_block_chain = BlockChain(debug=True)
    my_block_chain.new_block('Second Block')
    my_block_chain.new_block('Third Block')
    for block in range(0, 10):
        my_block_chain.new_block('Block %d' % block)
    print(my_block_chain.blocks())
示例#11
0
class Node:
    def __init__(self):
        self.blockchain = BlockChain(consts.difficulty)
        self.blockchain.create_genesis_block()

        self.private_key = rsa.generate_private_key(public_exponent=consts.rsa_public_exponent,
                                                    key_size=consts.rsa_key_size, backend=default_backend())
        # Storing public key as serialized string
        self.public_key = self.private_key.public_key().public_bytes(encoding=serialization.Encoding.PEM,
                                                                     format=serialization.PublicFormat.SubjectPublicKeyInfo).decode(
            'ascii')
        self._peers = {}
        self.host = ''

    @property
    def peers(self):
        encoded_peers = {}
        for p in self._peers:
            encoded_peers[p] = {}
            for key in self._peers[p]:
                if key == "public_key":
                    pk = self._peers[p]["public_key"]
                    pk_serialized = pk.public_bytes(encoding=serialization.Encoding.PEM,
                                                    format=serialization.PublicFormat.SubjectPublicKeyInfo)
                    ascii_pk = pk_serialized.decode('ascii')
                    encoded_peers[p]["public_key"] = ascii_pk
                else:
                    encoded_peers[p][key] = self._peers[p][key]
        return encoded_peers

    def sign(self, message: str):
        return base64.b64encode(self.private_key.sign(message.encode(),
                                     padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                                 salt_length=padding.PSS.MAX_LENGTH),
                                     hashes.SHA256())).decode('ascii')

    def verify(self, message: bytes, signature: bytes, key: rsa.RSAPublicKey):
        try:
            key.verify(signature, message,
                       padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
                       hashes.SHA256())
            return True
        except InvalidSignature:
            return False

    def peer_timeout_update(self):
        to_del = []
        for peer in self._peers:
            self._peers[peer]["timeout"] -= 1
            if self._peers[peer]["timeout"] == 0:
                to_del.append(peer)

        for peer in to_del:
            self._peers.pop(peer, None)

    def peer_keep_alive_update(self, msg):
        if "node_address" in msg and msg["node_address"] in self._peers:
            peer_addr = msg["node_address"]
            self._peers[peer_addr]["timeout"] = consts.peer_timeout
            print(f"received keep alive from: {peer_addr}")

    def peer_management(self, peer_list):
        for p in peer_list:
            if p["node_address"] not in self._peers:
                self._peers[p["node_address"]] = {}
                self._peers[p["node_address"]]["timeout"] = consts.peer_timeout

                pk_bytes = p["public_key"].encode()
                pk = serialization.load_pem_public_key(pk_bytes, backend=default_backend())
                self._peers[p["node_address"]]["public_key"] = pk
            else:
                self._peers[p["node_address"]]["timeout"] = consts.peer_timeout

    def create_message(self, data: dict):
        msg = {"msg": data, "signature": self.sign(json.dumps(data, sort_keys=True))}
        return msg

    def verify_message(self, msg):
        signature = base64.b64decode(msg.pop("signature").encode())
        peer = msg["msg"]["node_address"]
        dump = json.dumps(msg["msg"], sort_keys=True)
        if self.verify(dump.encode(), signature, self._peers[peer]["public_key"]):
            return True
        return False

    def create_chain_from_dump(self,chain_dump):
        new_blockchain = BlockChain(consts.difficulty)
        for idx, block_data in enumerate(chain_dump):
            block = Block(block_data["id"],
                        block_data["transactions"],
                        block_data["timestamp"],
                        block_data["previous_hash"],
                        block_data["nonce"])
            block.hash = block_data['hash']

            if idx > 0:
                added = new_blockchain.add_block(block)
                if not added:
                    raise Exception("The chain dump is tampered!!")
            else:  # the block is a genesis block, no verification needed
                new_blockchain.chain.append(block)

        return new_blockchain
示例#12
0
from time import time
from transaction import Transaction
from blockchain import BlockChain

import time

FVC: BlockChain = BlockChain()

FVC.create_transaction(Transaction('address1', 'address2', 10))
FVC.create_transaction(Transaction('address1', 'address2', 50))

print('\nStarting miner....')

FVC.mine_pending_transaction('favours-address')

print(f"\nFavour's balance is {FVC.get_balance_of_address('favours-address')}")

print('\nStarting miner....')

FVC.mine_pending_transaction('favours-address')

print(f"\nFavour's balance is {FVC.get_balance_of_address('favours-address')}")

print('\nSending 50 FVCs to address2')
FVC.create_transaction(Transaction('favours-address', 'address2', 100))

FVC.mine_pending_transaction('favours-address')

print(f"\nFavour's balance is {FVC.get_balance_of_address('favours-address')}")
print(f"\nAddress2 balance is {FVC.get_balance_of_address('address2')}")
示例#13
0
from flask import Flask, jsonify, request

from blockchain import BlockChain
from market_pool import Market

PORT = 5000


# Instantiate our Node
app = Flask(__name__)

# Generate a globally unique address for this node
node_identifier = str(uuid4()).replace('-', '')

# Instantiate the Block chain
block_chain = BlockChain()

# Instantiate the Market
market = Market(block_chain)


@app.route('/mine', methods=['GET'])
def mine():
    """
    Our mining endpoint is where the magic happens, and it’s easy. It has to do three things:
    - Calculate the Proof of Work
    - Reward the miner (us) by adding a transaction granting us 1 coin
    - Forge the new Block by adding it to the chain

    Note that the recipient of the mined block is the address of our node.
    And most of what we’ve done here is just interact with the methods on our Block chain class.
示例#14
0
#!/usr/bin/env python3.6
# -*- encoding: utf-8 -*-
from blockchain import BlockChain

# Create the blockchain and add the genesis block
blockchain = BlockChain()

# How many blocks should we add to the chain
# after the genesis block
num_of_blocks_to_add = 20

# Add blocks to the chain
for i in range(0, num_of_blocks_to_add):
    new_block = blockchain.create_block("Hey! I'm block " + str(i + 1))
    last_block = blockchain.append_block(new_block)
    # Tell everyone about it!
    print("Block #{} has been added to the blockchain!".format(
        last_block.get_index()))
    print("Hash: {}".format(last_block.get_hash()))
    print("Data: {}\n".format(last_block.get_data()))
示例#15
0
 def setUp(self):
     self.block_chain = BlockChain()
     self.factory = BlockFactory()
示例#16
0
class Miner:
    def __init__(self, host, port, miners, genesis):
        self.address = (host, port)
        self.__blockchain = None
        self.miners = miners
        self.genesis = genesis
        self.__read_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.__write_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.__write_lock = threading.Lock()
        self.__block_queue = multiprocessing.Queue()
        self.__receive_process = threading.Thread(target=self.__receive_blocks)
        self.__update_process = threading.Thread(target=self.__update_chain)

    def broadcast(self, block):
        for miner in self.miners:
            self.__write_lock.acquire()
            self.__write_socket.sendto(block.encode(), miner)
            self.__write_lock.release()

    def __find_p_o_w(self):
        max_val = int.from_bytes(b'\xff' * 8, byteorder='big', signed=False)
        p_o_w = None
        for i in range(max_val + 1):
            i_bytes = i.to_bytes(8, 'big')
            if Block.is_valid_p_o_w(i_bytes):
                p_o_w = i_bytes
                break
        return p_o_w

    def __receive_blocks(self):
        while True:
            data, addr = self.__read_socket.recvfrom(1024)
            new_block = Block.decode(data)
            self.__block_queue.put(new_block)

    def __update_chain(self):
        while True:
            block = self.__block_queue.get()
            if not Block.is_valid_p_o_w(block.p_o_w):
                raise ValueError(
                    'Received a block, but it has invalid Proof of work!')
            if self.__blockchain is None:
                self.__blockchain = BlockChain(block)
                print('Block chain created')
            else:
                if self.__blockchain.append(block) is None:
                    print('Received block but didnt add')
                else:
                    print('Block added')

    def __create_block(self, block):
        self.__block_queue.put(block)
        self.broadcast(block)

    def run(self):
        self.__read_socket.bind(self.address)
        self.__receive_process.start()
        self.__update_process.start()
        if self.genesis:
            time.sleep(.1)
            genesis_block = Block(b'I\'m the one that come before all others',
                                  b'\x00', self.__find_p_o_w())
            self.__create_block(genesis_block)

        while True:
            time.sleep(1e-3)
            if self.__blockchain is not None:
                proof_of_work = self.__find_p_o_w()
                target = self.__blockchain.blocks[
                    -1] if self.__blockchain.blocks else self.__blockchain.root
                new_block = Block(b'Random block', target.hash(),
                                  proof_of_work)
                self.__create_block(new_block)
示例#17
0
class ServerCore:
    def __init__(self,
                 my_port=50082,
                 core_node_host=None,
                 core_node_port=None):
        self.server_state = STATE_INIT
        print('Initializing server...')
        self.my_ip = utils.get_host()
        print('Server IP address is set to ... ', self.my_ip)
        self.my_port = my_port
        self.cm = ConnectionManager(self.my_ip, self.my_port,
                                    self.__handle_message)
        self.core_node_host = core_node_host
        self.core_node_port = core_node_port
        self.miners_wallet = Wallet()
        self.blockchain = BlockChain(self.miners_wallet.blockchain_address)
        self.mining_semaphore = threading.Semaphore(1)
        self.__print_info()

    def __print_info(self):
        print({
            'private_key': self.miners_wallet.private_key,
            'public_key': self.miners_wallet.public_key,
            'blockchain_address': self.miners_wallet.blockchain_address
        })

    def start(self):
        """
            Coreノードとしての待受を開始
        """
        self.server_state = STATE_STANDBY
        self.cm.start()
        self.start_mining()

    def join_network(self):
        """
            事前に取得した情報に従い拠り所となる他のCoreノードに接続
        """
        if self.core_node_host is not None:
            self.server_state = STATE_CONNECTED_TO_NETWORK
            self.cm.join_network(self.core_node_host, self.core_node_port)
        else:
            print('This server is runnning as Genesis Core Node...')

    def shutdown(self):
        """
            待ち受け状態のServer Socketを閉じて終了
        """
        self.server_state = STATE_SHUTTING_DOWN
        print('Shutdown server...')
        self.cm.connection_close()

    def start_mining(self):
        print('start mining')
        is_acquire = self.mining_semaphore.acquire(blocking=False)
        if is_acquire:
            with contextlib.ExitStack() as stack:
                stack.callback(self.mining_semaphore.release)
                self.__mining()
                mining_interval = self.blockchain.mining_speed + random.uniform(
                    9.8, 10.3)
                loop = threading.Timer(round(mining_interval),
                                       self.start_mining)
                loop.start()

    def __mining(self):
        start = time.time()
        self.blockchain.add_transaction(
            sender_blockchain_address=MINING_SENDER,
            recipient_blockchain_address=self.blockchain.blockchain_address,
            value=MINING_REWARD)
        nonce = self.blockchain.proof_of_work()
        if nonce == -1:
            return False
        previous_hash = self.blockchain.hash(self.blockchain.chain[-1])
        is_created, block = self.blockchain.create_block(nonce, previous_hash)
        if not is_created:
            return False
        self.delete_transaction_for_all_peer()

        print({'action': 'mining', 'status': 'success'})
        utils.pprint(self.blockchain.chain)

        self.send_all_chain_for_consensus()

        elapse = round(time.time() - start, 4)
        self.blockchain.difficulty_adjustment(elapse)

        # print('mining speed : ', str(round(self.mining_speed, 3)))
        # print('difficult : ', str(self.difficulty))

        return True

    def delete_transaction_for_all_peer(self):
        """
            ノードのトランザクションプールをからにするメッセージの送信
        """
        new_message = self.cm.get_message_text(MSG_DELETE_TRANSACTION)
        self.cm.send_msg_to_all_peer(new_message)

    def send_all_chain_for_consensus(self):
        """
            チェーンを全てのノードに送信してコンセンサス
        """
        my_chain = self.blockchain.chain
        chain_data = json.dumps(my_chain)
        new_message = self.cm.get_message_text(RSP_FULL_CHAIN, chain_data)
        self.cm.send_msg_to_all_peer(new_message)

    def __handle_message(self, msg, is_core, peer=None):
        """
            ConnectionManagerに引き渡すコールバックの中身。
        """
        print('message_type : ', msg[2])
        if peer is not None:
            if msg[2] == MSG_REQUEST_FULL_CHAIN:
                # walletのチェーンを同期
                print('Send our latest blockchain for reply to : ', peer)
                my_chain = self.blockchain.chain
                chain_data = json.dumps(my_chain)
                new_message = self.cm.get_message_text(RSP_FULL_CHAIN,
                                                       chain_data)
                self.cm.send_msg(peer, new_message)
            elif msg[2] == MSG_REQUEST_KEY_INFO:
                # walletにminerの鍵情報を渡す
                key_info = pickle.dumps(self.miners_wallet, 0).decode()
                m_type = MSG_KEY_INFO
                message = self.cm.get_message_text(m_type, key_info)
                self.cm.send_msg(peer, message)
            elif msg[2] == MSG_DELETE_TRANSACTION:
                # transaction poolを空に
                print('DELETE_TRANSACTION is called')
                self.blockchain.transaction_pool = []
        else:
            if msg[2] == MSG_NEW_TRANSACTION:
                print('NEW_TRANSACTION command is called')
                payload = json.loads(msg[4])
                new_transaction = utils.sorted_dict_by_key({
                    'sender_blockchain_address':
                    payload['sender_blockchain_address'],
                    'recipient_blockchain_address':
                    payload['recipient_blockchain_address'],
                    'value':
                    float(payload['value'])
                })
                current_transactions = self.blockchain.transaction_pool.copy()
                print('new transaction : ', new_transaction)
                if new_transaction in current_transactions:
                    print('transaction is already in pool')
                    return
                else:
                    signature = pickle.loads(
                        payload['signature'].encode('utf8'))
                    print('signature', signature)
                    is_transacted = self.blockchain.add_transaction(
                        payload['sender_blockchain_address'],
                        payload['recipient_blockchain_address'],
                        payload['value'], payload['sender_public_key'],
                        signature)
                    if is_transacted:
                        print('new transaction is generated')
                        print('\n\ntransaction_pool',
                              self.blockchain.transaction_pool)
                    if not is_core:
                        # ウォレットからのトランザクションはブロードキャスト
                        print('transaction bloadcasted')
                        m_type = MSG_NEW_TRANSACTION
                        new_message = self.cm.get_message_text(m_type, msg[4])
                        self.cm.send_msg_to_all_peer(new_message)
            elif msg[2] == RSP_FULL_CHAIN:
                print('RSP_FULL_CHAIN command is called')
                if not is_core:
                    return

                new_block_chain = json.loads(msg[4])
                self.blockchain.resolve_conflicts(new_block_chain)
示例#18
0
class Scrooge():
    """
    Class representing the maintainer Scrooge who will be monitoring every progress in his network and responsible for creating `Coin`s and verify transactions.
    This class possesses a private and a public key for its own authentications and 
    """
    def __init__(self, users):
        self.__private_key, self.public_key = gen_keys()
        self.blockchain = BlockChain()
        self.users = users
        self.current_building_block = Block()
        self.last_block = None
        self.init()

    def process_transaction(self, transaction, sender_pubk):
        verified_check = self.verify_transaction(transaction, sender_pubk)
        double_spending_check = self.is_double_spending(transaction)
        if not verified_check:
            logger('|TRANSACTION REJECTED\t-\tInvalid Transaction|')
            return
        if double_spending_check:
            logger('|TRANSACTION REJECTED\t-\tDouble Spending Detected|\n|From User \t\t\t\t'+str(sender_pubk.__hash__())+'|')
            return
        transaction_previous_hash = self.retrieve_transaction_previous_hash(transaction)
        transaction.add_prev_transaction(transaction_previous_hash)
        self.add_transaction_to_block(transaction)

    def retrieve_transaction_previous_hash(self, transaction):
        previous_hashes = []
        for coin in transaction.coins:
            previous_hash = self.blockchain.retrieve_coin_previous_transaction(coin)
            if previous_hash != None:
                previous_hashes.append(previous_hash) 
        if len(previous_hashes) == 0:
            previous_hashes = None  
        elif len(previous_hashes) <= 1:
            previous_hashes = previous_hashes[0]      
        return previous_hashes

    def create_coins(self, amount, user_id):
        return [Coin(user_id) for _ in range(amount)]

    def init(self):
        self.log_users()
        # self.last_transaction = None
        for user in self.users:
            user_id = user.id
            coins = self.create_coins(10, 'scrooge')
            transaction = Transaction(self.public_key, coins, user_id, genre="create")
            if self.__sign(transaction):
                self.process_transaction(transaction, self.public_key)
    
    def log_users(self):
        logger('='*64+'\nUsers Report:\n'+'='*64)
        string_users = ''
        for user in self.users:
            string_users += user.to_string(self)
        logger(string_users+'\n'+'='*64)
    
    def add_coin_to_user(self, transaction):
        receiver_pubk = transaction.receiver
        transaction_coins = transaction.coins
        for user in self.users:
            if user.id == receiver_pubk:
                user.add_transaction(transaction_coins)
                break

    def add_transaction_to_block(self, transaction):
        if not self.current_building_block.add_transaction(transaction):
            self.last_block = self.current_building_block
            self.publish_block(self.current_building_block)
        
    def publish_block(self, block):
        self.blockchain.add_block(block)
        self.current_building_block = Block(transactions=[], hash_prev_block=self.last_block.id)
        for transaction in block.transactions:
            self.add_coin_to_user(transaction)
        self.log_users()



    def verify_transaction(self, transaction, sender_pk):
        return verify(sender_pk, transaction.signature, transaction.hash_val)

    def is_double_spending(self, transaction):
        return self.current_building_block.is_double_spending(transaction)
    
    def sign_last_block(self):
        self.__sign(self.current_building_block)

    def __sign(self, obj):
        if(isinstance(obj, Transaction)):
            try:
                transaction_content = get_hash(obj)
                signature = sign(self.__private_key, transaction_content)
                obj.add_signing(signature)
                obj.add_hash(transaction_content)
                return True
            except:
                return False
        else:
            try:
                block_content = get_hash(obj)
                signature = sign(self.__private_key, block_content)
                obj.add_signing(signature)
                return True
            except:
                return False
示例#19
0
 def setUp(self):
     self.block_chain = BlockChain()
示例#20
0
node = Flask(__name__)

my_address = str(uuid4()).replace('-', '')
print(my_address)


def create_genesis_block():
    return Block(0, date.datetime.now(), [], "0").serialize


def new_transaction(sender, recipient, amount):
    return {"from": sender, "to": recipient, "amount": amount}


blockchain = BlockChain(create_genesis_block())


@node.route('/mine', methods=['GET'])
def mine():
    print("mining api called at: " + str(date.datetime.now()))
    block = blockchain.next_block()
    if len(block["data"]) > 0:
        blockchain.add_to_chain(block)
    return "We'll mine a new Block"


@node.route('/transactions/new', methods=['POST'])
def add_transaction():
    values = request.get_json()
示例#21
0
class Filemng:
    def __init__(self,client,blockchain= None):
        encode_key_file = 'Server_public_key.pem'
        decode_key_file =  client+'_private_key.pem'
        base_path = Path(__file__).parent
        self.encode_path = str((base_path / "key" / encode_key_file).resolve())
        self.decode_path = str((base_path / "key" / decode_key_file).resolve())
        self.clients_list_file = str((base_path / "client" / 'clients.json').resolve())
        self.secert_path = str((base_path / "key" / 'Server_private_key.pem').resolve())
        self.client_list = []
        self.client = client
        self.error = []
        self.blockchain = blockchain
        self.lock = threading.Lock()

    def Set_Client_and_Chain(self,client,chain):
        self.client = client
        self.blockchain = chain
    def Set_Client(self,client):
        self.client = client

    def Get_Error(self):
        return self.error
    def Set_Lock(self):
        self.lock.acquire()
    def Release_Lock(self):
        self.lock.release()
    def load_encode_key(self):
        encode_key = []
        if(path.exists(self.encode_path) and path.isfile(self.encode_path) and not os.stat(self.encode_path).st_size==0):
            with open(self.encode_path, "rb") as key_file:
                encode_key = serialization.load_pem_public_key(
                           key_file.read(),
                           backend=default_backend()
                           )
            return encode_key
        self.error.append(96)
        return False

    def load_decode_key(self):
        decode_key = []
        if(path.exists(self.decode_path) and path.isfile(self.decode_path) and not os.stat(self.decode_path).st_size==0):
            with open(self.decode_path, "rb") as key_file:
                decode_key = serialization.load_pem_private_key(
                           key_file.read(),
                           password=None,
                           backend=default_backend()
                           )
            return decode_key
        self.error.append(97)
        return False
    def Load_Spefic_key(self,client):
        decode_key = []
        base_path = Path(__file__).parent
        encode_path = str((base_path / "key" / client ).resolve())

        if(path.exists(encode_path) and path.isfile(encode_path) and not os.stat(encode_path).st_size==0):
            with open(encode_path, "rb") as key_file:
                decode_key = serialization.load_pem_public_key(
                           key_file.read(),
                           backend=default_backend()
                           )
            return decode_key
        print("94")
        self.error.append(97)
        return False

    def Load_Both_Keys(self):
        encypt = []
        encypt.append(self.load_encode_key())
        encypt.append(self.load_decode_key())

        if(not encypt[0] ):
            print("Encrypt keys not loaded")
            sys.exit()
        else:
                print("Encryption keys loaded")
        if( not encypt[1]) :
                    print("Decrypt keys not loaded")
                    sys.exit()
        else:
                 print("Decryption keys loaded")
        return encypt

    def Load_Month(self):

        for x in range(0,29):
            file = (datetime.now() - timedelta(x)).strftime("{name}-%m-%d-%Y.log").format(name=self.client.decode('UTF-8')if type(self.client) != str else self.client)
            file = Path(str((Path(__file__).parent / "log" / file)))
            if(file.exists() and file.is_file()):
                    self.__load_log__(file)
        self.blockchain.Sort(False)

    def __Save_Chains__(self):
        days = self.blockchain.Split_into_days()
        for key in days:
            days[key].sort(key=self.__indexer__)
            file = self.client.decode('UTF-8')  if type(self.client) != str else self.client + "-"+ key+".log"
            file =os.path.join(os.path.dirname(__file__),"log",file)
            self.__save_log__(days[key],file)

    def __indexer__(self,block):
        return block.index


    def Save_Log(self):
        self.__Save_Chains__()

    def __save_log__(self,data,file):
            with open(file, mode='w') as f:
                  json.dump(data,f, cls=self.ComplexEncoder,indent=4)

    def __load_log__(self,file):
        sensor = []
        alert = []
        sensor_index = 0
        alert_index = 0

        if(file.exists() and file.is_file()):
                with open(str(file), 'r') as f:
                    json.load(f,object_hook = lambda x : self.blockchain.block_creator(x,sensor,alert,sensor_index,alert_index))
                    if len(self.blockchain.chain) != 0 :
                        return True
        print("Failed to Load data log")
        return False
    def Load_Server_Key(self):
        with open(self.secert_path, "rb") as key_file:
            print("Loaded Server Key")
            return serialization.load_pem_private_key(
                    key_file.read(),
                    password=None,
                    backend=default_backend()
                    )


    def Load_Client_List(self):
        temp = self.client
        if(path.exists(self.clients_list_file) and path.isfile(self.clients_list_file)):
            if(not os.stat(self.clients_list_file).st_size==0):
                with open(self.clients_list_file, 'r') as f:
                    json.load(f,object_hook = self.__client_creator__)
        for client in self.client_list:
            client.Set_Encode(self.Load_Spefic_key(client.public_key_file))
            self.client = client.id
            self.blockchain = BlockChain(client.id,client.passphrase)
            self.blockchain.Set_Hasher()
            self.Load_Month()
            client.chain = self.blockchain
        self.client = temp
        print("Loaded Client list")
        return self.client_list

    def __client_creator__(self,d):
        if(  d.get('clients',False) == False):
            self.client_list.append(self.Client(d['idenifier'], d['passphrase'],d['public_key_file'],d['last_com']))


    class Client:
        def __init__(self, idcode,passphrase, decode_file,last_com):
            self.id = idcode
            self.passphrase = passphrase.encode('utf-8')
            self.public_key_file = decode_file
            self.last_com = last_com
            self.encode_key = None
            self.chain = []

        def Set_Encode(self,key):
                self.encode_key = key


    #Python to Json Decoder. Used for creating string to create data log.
    class ComplexEncoder(json.JSONEncoder):
        def default(self, obj):
            if(not isinstance(obj,BlockChain.Block)):
                pass
            if(isinstance(obj,BlockChain.Block)):
                sensor = obj.sensor.__dict__
                alert = obj.alert.__dict__
                del_temp = []
                #deletes the empy cells of sensor so they aren't saved and take up space.
                if(len(sensor) > 0):
                    for items in sensor:
                        if sensor[items] == -1:
                            del_temp.append(items)

                    for dels in del_temp:
                        del sensor[dels]
                    del_temp.clear()
                else:
                    sensor = {'sen' :1}
                if(len(alert)>0):
                    for items in alert:
                        if alert[items] == -1:
                            del_temp.append(items)
                    for dels in del_temp:
                        del alert[dels]
                else:
                        alert = {'alt':1}
                stiff = {
                            "index": obj.index,
                            "local_time": obj.local_time,
                            "remote_time": obj.remote_time,
                            "source" : obj.source,
                            "sensor" : sensor,
                            "alert": alert,
                            "hash_last": obj.hash_last,
                            "hash_current": obj.hash_current,
                            "unsent": obj.unsent
                        }
                return stiff
            return json.JSONEncoder.default(self, obj)
示例#22
0
genesis_prev_hash = sha256((b'\x00' * 32))

genesis_data = 'Hello there!'.encode('utf-8')
data1 = '1!'.encode('utf-8')
data2 = '2!'.encode('utf-8')
data3 = '3!'.encode('utf-8')
data4 = '4!'.encode('utf-8')

genesis_block = Block(genesis_data, genesis_prev_hash.digest())
block1 = Block(data1, genesis_block.hash())
block2 = Block(data2, block1.hash())
block3 = Block(data3, block2.hash())
block4 = Block(data4, block1.hash())

blockchain = BlockChain(genesis_block)

one = blockchain.append(block1)
two = blockchain.append(block2)
three = blockchain.append(block3)
four = blockchain.append(block4)

test_dict = {
    "data": "MyE=",
    "previous":
    "3b9448477c4dc133872b1029ab8d3e5ca151ad872cf5de636c2e8595dbf67855"
}

test = Block.decode(dumps(test_dict))

print(test)
            verbose=True) else "Blockchain invalid"

    def _create_validator_chain(self):
        '''
            Create a chain with the same genesis block. Blocks from the test chain will be added to this chain by verifying the validity of the chain.

        '''

        self.validator_chain_ = BlockChain(
            chain=[self.blockchain_.genesis_block])


#################
### TEST CODE ###
#################
if __name__ == '__main__':

    # -----  Create the blockchain and add the genesis block
    blockchain = BlockChain()

    num_of_blocks_to_add = 20

    # ----- Gernerate a block chain by adding blocks to the chain
    for i in range(0, num_of_blocks_to_add):

        data = "Hey! I'm block " + str(blockchain.latest_block.index + 1)
        blockchain.generate_next_block(data)

    # ----- validate the blockchain
    BlockChainTester(blockchain).validate()
示例#24
0
class Node(object):
    __slots__ = [
        "nodes", "connections", "app", "chain", "session", "addr", "port"
    ]
    MASTER = ("localhost", DEFAULT_PORT)  # FIX localhost to real ip

    def __init__(self, addr, port=DEFAULT_PORT, *, master=False):
        self.addr = addr
        self.port = port

        self.nodes = [Node.MASTER]
        self.connections = []
        self.app = web.Application()
        self.chain = BlockChain()
        self.session = None

        if master == False:
            loop = asyncio.get_event_loop()
            loop.run_until_complete(self._init())

        # just for check with web-browser
        self.app.router.add_get("/query_node_list", self.response_node_list)
        self.app.router.add_get("/query_block_chain",
                                self.response_block_chain)
        # blockchain node do
        self.app.router.add_get("/ws", self.ws_handler)

    async def _init(self):
        await self.query_nodes()
        await self.connect_to_peers(self.nodes)
        await self.register_node()

    async def register_node(self):
        msg = json.dumps({
            'type': MessageType.REGISTER_ME,
            'nodeinfo': (self.addr, self.port)
        })
        await self.broadcast(msg)

    async def query_nodes(self):
        if self.session == None:
            self.session = aiohttp.ClientSession()
        ws = await self.session.ws_connect(
            "http://{}:{}/ws".format(*Node.MASTER))
        await ws.send_str(json.dumps({'type': MessageType.REQUEST_NODE_LIST}))
        msg = await ws.receive()
        self.nodes = json.loads(msg.data)
        await ws.close()

    # just for check
    async def response_block_chain(self, request):
        return web.Response(text=self.chain.json(),
                            content_type="application/json")

    async def response_node_list(self, request):
        return web.Response(text=json.dumps(self.nodes, indent=2),
                            content_type="application/json")

    # blockchain do
    async def connect_to_peers(self, peers):
        if self.session == None:
            self.session = aiohttp.ClientSession()
        for peer in peers:
            if peer[0] == self.addr and peer[1] == self.port:
                continue
            conn = await self.session.ws_connect(
                "http://{}:{}/ws".format(*peer))
            self.connections.append(conn)

    async def broadcast(self, msg):
        for peer in self.connections:
            await peer.send_str(msg)

    async def ws_handler(self, request):
        ws = web.WebSocketResponse()
        await ws.prepare(request)

        async for msg in ws:
            if msg.type == aiohttp.WSMsgType.TEXT:
                msg = json.loads(msg.data)
                if msg["type"] == MessageType.REGISTER_ME:
                    # 새로운 노드 연결
                    node = msg["nodeinfo"]
                    await self.connect_to_peers([node])
                    self.nodes.append(node)
                elif msg["type"] == MessageType.REQUEST_NODE_LIST:
                    # 노드 목록 알려줌
                    await ws.send_json(self.nodes)
                elif msg["type"] == MessageType.REQUEST_MAKE_BLOCK:
                    # 블록 생성함
                    await asyncio.sleep(random.randint(3,
                                                       10))  # 해시 푸는 속도라고 가정하자
                    tr_info = msg["data"]
                    _lastblock = self.chain.get_latest_block()

                    new_block = Block(_lastblock.index + 1, tr_info["data"],
                                      tr_info["timestamp"], _lastblock.hash,
                                      '')
                    new_block.calculate()
                    if new_block.index > self.chain.latest_block.index:
                        self.chain.add_block(new_block)
                        # 컨펌 받기
                        await self.broadcast(
                            json.dumps({
                                "type": MessageType.REQUEST_CONFIRM_BLOCK,
                                "chain": self.chain.json()
                            }))
                        await ws.send_str("[+] Well done !")

                elif msg["type"] == MessageType.REQUEST_CONFIRM_BLOCK:
                    # 블록 생성 컨펌해줌
                    blocks = [
                        Block.from_dict(j) for j in json.loads(msg["chain"])
                    ]
                    if len(blocks) > self.chain.length:
                        if BlockChain.is_valid_chain(blocks):
                            self.chain.blocks = blocks
                    else:
                        pass

            elif msg.type == aiohttp.WSMsgType.Error:
                print('ws connection closed with exception ', ws.exception())
        return ws
示例#25
0
class Node:
    def __init__(self):
        self.wallet = Wallet()
        # By default the node generate a new wallet while the user
        # can still generate a new WALLET
        self.wallet.create_keys()
        self.blockchain = BlockChain(self.wallet.public_key)
        #self.blockchain = None

    def get_transaction_value(self):
        #tx_sender = input("Enter the sender of the transaction:")
        tx_sender = self.wallet.public_key
        tx_recipient = input("Enter the recipient of the transaction:")
        tx_amount = float(input("Enter the amount of the transaction:"))
        return tx_sender, tx_recipient, tx_amount

    def print_blockchain_elements(self):
        for block in self.blockchain.get_chain():
            print(block)
        else:
            print("-" * 30)

    def get_user_choice(self):
        return int(input("Your choice:"))

    def display_balance_all(self):
        for person in self.blockchain.participants:
            print("Balance of {} : {:6.2f}".format(
                person, self.blockchain.get_balance(person)))

    def listen_for_input(self):
        waiting_for_input = True
        while waiting_for_input:
            print("Please select your choice: ")
            print("1) Add a a new transaction. ")
            print("2) Mine a new block")
            print("3) Print the blockchain. ")
            print("4) Show participants. ")
            print("5) Manipulate. ")
            print("6) Verify. ")
            print("7) Quit. ")
            print("8) Load Data.")
            print("9) Create Wallet")
            print("10) Load Wallet")
            print("11) Save Keys")
            user_choice = self.get_user_choice()
            if user_choice == 1:
                tx_sender, tx_recipient, tx_amount = self.get_transaction_value(
                )
                signature = self.wallet.sign_transaction(
                    tx_sender, tx_recipient, tx_amount)
                if self.blockchain.add_transaction(tx_sender, tx_recipient,
                                                   self.wallet.public_key,
                                                   signature, tx_amount):
                    print("Transaction successfully added.")
                else:
                    print("Transaction failed.")
                print([
                    tx.__dict__
                    for tx in self.blockchain.get_open_transactions()
                ])
            elif user_choice == 2:
                if self.blockchain.mine_block():
                    print(" New Block Mined!")
            elif user_choice == 3:
                self.print_blockchain_elements()
            elif user_choice == 4:
                print(self.blockchain.participants)
            elif user_choice == 5:
                print("NONE")
            elif user_choice == 6:
                print(Verification.verify_chain(self.blockchain.get_chain()))

            elif user_choice == 7:
                waiting_for_input = False

            elif user_choice == 8:
                self.blockchain.load_data()

            elif user_choice == 9:  # Create Wallet
                self.wallet.create_keys()
                self.blockchain = BlockChain(self.wallet.public_key)
                print(self.wallet.public_key)

            elif user_choice == 10:  # Load Wallet
                self.wallet.load_keys()
                self.blockchain = BlockChain(self.wallet.public_key)
                print(self.wallet.public_key)

            elif user_choice == 11:  # Save the keys
                if self.wallet.save_keys():
                    print("Keys SAVED.")
                else:
                    print("Keys NOT saved.")

            else:
                print("Not a valid input.")

            if not Verification.verify_chain(self.blockchain.get_chain()):
                print("Invalid blockchain")
                self.print_blockchain_elements()
                waiting_for_input = False

            self.display_balance_all()

        else:
            print("User left.")
示例#26
0
def cli_printblock(height):
    blk_chain = BlockChain()
    if not blk_chain.Verify_Block_Chain():
        print("Your database may be damaged. Cannot open this file.")
        return
    print(blk_chain.get_block(height - 1))
示例#27
0
def main():

    # Create or load the blockchain
    bc = BlockChain()

    # Create a new wallet to mine into (this could be set to the same string each run to maintain your wallet addr)
    # TODO: Make the chain into a cli so we can save wallet addresses locally for mining into
    my_wallet, priv_key = bc.createWallet()
    bc.savePrivKey(priv_key)

    w1, w1_priv_key = bc.createWallet()
    w2, w2_priv_key = bc.createWallet()

    # Mine some coin into w1 and w2
    # Note: blocks don't need transactions in them to give a reward
    #       this doesn't matter as it make the chain longer (more secure) and thus we should reward the miner
    for _ in range(20):
        bc.mineBlock(w1)
        bc.mineBlock(w2)

    try:
        for _ in range(20):
            # Create some transactions
            sig = bc.getTransactionSig(w1, w2, 5, w1_priv_key)
            bc.addTransaction(w1, w2, 5, sig)

            sig = bc.getTransactionSig(w2, w1, 5, w2_priv_key)
            bc.addTransaction(w2, w1, 5, sig)

            # Mine the current block with the transactions we made and collect the reward into our wallet
            bc.mineBlock(my_wallet)

    # Watch for a keyboard interrupt so we gracefully exit and save the blockchain to the db
    except KeyboardInterrupt:
        pass

    bc.save()
示例#28
0
    def listen_for_input(self):
        waiting_for_input = True
        while waiting_for_input:
            print("Please select your choice: ")
            print("1) Add a a new transaction. ")
            print("2) Mine a new block")
            print("3) Print the blockchain. ")
            print("4) Show participants. ")
            print("5) Manipulate. ")
            print("6) Verify. ")
            print("7) Quit. ")
            print("8) Load Data.")
            print("9) Create Wallet")
            print("10) Load Wallet")
            print("11) Save Keys")
            user_choice = self.get_user_choice()
            if user_choice == 1:
                tx_sender, tx_recipient, tx_amount = self.get_transaction_value(
                )
                signature = self.wallet.sign_transaction(
                    tx_sender, tx_recipient, tx_amount)
                if self.blockchain.add_transaction(tx_sender, tx_recipient,
                                                   self.wallet.public_key,
                                                   signature, tx_amount):
                    print("Transaction successfully added.")
                else:
                    print("Transaction failed.")
                print([
                    tx.__dict__
                    for tx in self.blockchain.get_open_transactions()
                ])
            elif user_choice == 2:
                if self.blockchain.mine_block():
                    print(" New Block Mined!")
            elif user_choice == 3:
                self.print_blockchain_elements()
            elif user_choice == 4:
                print(self.blockchain.participants)
            elif user_choice == 5:
                print("NONE")
            elif user_choice == 6:
                print(Verification.verify_chain(self.blockchain.get_chain()))

            elif user_choice == 7:
                waiting_for_input = False

            elif user_choice == 8:
                self.blockchain.load_data()

            elif user_choice == 9:  # Create Wallet
                self.wallet.create_keys()
                self.blockchain = BlockChain(self.wallet.public_key)
                print(self.wallet.public_key)

            elif user_choice == 10:  # Load Wallet
                self.wallet.load_keys()
                self.blockchain = BlockChain(self.wallet.public_key)
                print(self.wallet.public_key)

            elif user_choice == 11:  # Save the keys
                if self.wallet.save_keys():
                    print("Keys SAVED.")
                else:
                    print("Keys NOT saved.")

            else:
                print("Not a valid input.")

            if not Verification.verify_chain(self.blockchain.get_chain()):
                print("Invalid blockchain")
                self.print_blockchain_elements()
                waiting_for_input = False

            self.display_balance_all()

        else:
            print("User left.")
 def setUp(self):
     self.block_chain = BlockChain()
     self.content_queue = queue.Queue()
     logging.debug('setUp')
示例#30
0
 def __init__(self):
     self.wallet = Wallet()
     # By default the node generate a new wallet while the user
     # can still generate a new WALLET
     self.wallet.create_keys()
     self.blockchain = BlockChain(self.wallet.public_key)
示例#31
0
class BaseServer(object):
    def __init__(self):
        self.peers = Peers()
        self.blacklist = BlackList()
        self.blockchain = BlockChain()
        self.storage = BlockchainStorage()
        self.mempool = Mempool()
        self.miner = Miner()

        self.ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
        self.ctx.load_cert_chain("ca_certs/server.crt", "ca_certs/server.key")
        self.ctx.load_verify_locations("ca_certs/client.crt")
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind((HOST, PORT))
        self.sock.listen(1)
        logger.info(" Listening on {}:{}".format(HOST, PORT))

    def plisten(self):
        trys = 0
        try:
            while True:
                try:
                    ssock, caddr = self.sock.accept()
                    if caddr[0] in self.blacklist.get_blacklisted():
                        logger.warning(
                            " Blacklisted host {} attempt to connect at {}".
                            format(caddr[0], self.get_time()))
                        ssock.close()
                        continue
                    elif caddr[0] in [p for p in self.peers.get_all_peers()
                                      ] and self.peers.get_peer_downtime(
                                          caddr[0]) > MAX_DOWNTIME:
                        self.remove_and_blacklist(caddr[0])
                        ssock.close()
                        continue
                    elif trys > 2:
                        tm_str = self.get_time()
                        flag = self.blacklist.blacklist_host(caddr[0], tm_str)
                        if flag == False:
                            logger.warning(" Cannot blacklist local host")
                        else:
                            logger.warning(
                                " {} has been blacklisted at {} -- trys: {}".
                                format(caddr[0], tm_str, trys))
                        ssock.close()
                        trys = 0
                        continue
                    else:
                        csock = self.ctx.wrap_socket(ssock, server_side=True)
                        logger.info(
                            " accpting connection from {}".format(caddr))
                        self.proc = mp.Process(target=self.handler(csock))
                        self.proc.start()
                except socket.error as err:
                    logger.error("Socket Error: {}".format(err))
                    trys += 1
                    if self.peers.get_peer(
                            caddr[0]) != None and caddr[0] != "127.0.0.1":
                        self.peers.record_downtime(caddr[0])
                        logger.warning(" {} downtime: {}".format(
                            caddr[0], self.peers.get_peer_downtime(caddr[0])))
                    else:
                        logger.warning(" Host: {} Failed attempts: {}".format(
                            caddr[0], trys))
                except KeyboardInterrupt:
                    break
        except KeyboardInterrupt:
            if self.sock is not None:
                self.sock.close()
                logger.debug(" Main socket closed")
            if csock is not None:
                csock.close()
                logger.debug(" Client socket closed")
            if self.proc is not None:
                self.proc.terminate()
                logger.debug(" Closing process")

    def handler(self, csock):
        data = ""
        while True:
            res = csock.recv(1024).decode()
            data += res
            if len(res) < 1024:
                break
        if data.split(":")[0] == "PEER":
            flag = self.connect_peer(data.split(":")[1])
        elif data.split(":")[0] == "BADPEER":
            flag = self.remove_and_blacklist(data.split(":")[1])
        elif data.split(":")[0] == "TYPE" and data.split(
                ":")[1] == "unconfirmed":
            host = data.split(":")[3]
            trans = deserialize_trans_header(data.split(":")[5])
            flag = self.add_unconfirmed_trans(host, trans)
        else:
            flag = False
        csock.send("{}".format(flag).encode())

    def get_time(self):
        d = date.today()
        t = localtime(time())
        return "{} {}:{}:{}".format(d, t.tm_hour, t.tm_min, t.tm_sec)

    def remove_and_blacklist(self, *peers):
        tm_str = self.get_time()
        for peer in peers:
            if peer in [i[0] for i in self.peers.get_all_peers()]:
                self.peers.remove_peer(peer)
                logger.warning(" {} removed from peers".format(peer))
            flag = self.blacklist.blacklist_host(peer, tm_str)
            if flag == False:
                logger.warning(" Cannot blacklist localhost")
            else:
                logger.warning(" {} has been blacklisted".format(peer))
        return False

    def connect_peer(self, peer):
        all_peers = [i[0] for i in self.peers.get_all_peers()]
        if peer in self.blacklist.get_blacklisted():
            logger.warning(
                " Blacklisted host: {} connection attempt at {}".format(
                    peer, localtime(time())))
            return False
        elif peer in all_peers:
            if self.peers.get_peer_downtime(peer) > MAX_DOWNTIME:
                self.remove_and_blacklist(peer)
                return False
            else:
                logger.info(" {} already in peers".format(peer))
                return True
        elif peer not in all_peers:
            self.peers.add_peer(peer)
            logger.info(" {} added to peers".format(peer))
            return True

    def add_unconfirmed_trans(self, host, trans):
        if host not in [p[0] for p in self.peers.get_all_peers()]:
            logger.warning(" POST UTX error, {} not in peers".format(host))
            return False
        trans_from_dic = Transaction.from_dict(trans)
        valid = self.blockchain.verify_transaction(trans["sender_address"],
                                                   trans["recipient_address"],
                                                   trans["signature"],
                                                   trans["amount"])
        if valid and trans_from_dic.txt_hash == trans["txt_hash"]:
            self.mempool.add_unconfirmed_transaction(trans)
            logger.info(" Unconfirmed Tx {} verified, added to mempool".format(
                trans_from_dic.txt_hash))
            if len([
                    t for t in self.mempool.get_all_unconfirmed_transactions()
            ]) >= MAX_TRANSACTIONS:
                self.miner.start()
                logger.debug(" Mining process starting")
                if len([
                        t for t in
                        self.mempool.get_all_unconfirmed_transactions()
                ]) == 0:
                    logger.debug(" Mining process finished")
                else:
                    sleep(5)
            return True
        else:
            logger.warning(" Invalid Transaction: {}".format(
                trans_from_dic.txt_hash))
            return False
示例#32
0
from uuid import uuid4
from flask import (Flask, jsonify, request)

from blockchain import BlockChain

app = Flask(__name__)

# Generate a globally unique address for this node
node_identifier = str(uuid4()).replace('-', '')

# Instantiate the Blockchain
blockchain = BlockChain()


@app.route('/mine', methods=['GET'])
def mine():
    # We run the proof of work algorithm to get the next proof...
    last_block = blockchain.last_block
    last_proof = last_block['proof']
    proof = blockchain.proof_of_work(last_proof)

    # We must receive a reward for finding the proof.
    # The sender is "0" to signify that this node has mined a new coin.
    blockchain.new_transaction(
        sender="0",
        recipient=node_identifier,
        amount=1,
    )

    # Forge the new Block by adding it to the chain
    previous_hash = blockchain.hash(last_block)
示例#33
0
class ClientCore:
    def __init__(self, my_port=50082, c_host=None, c_port=None, callback=None):
        self.client_state = STATE_INIT
        print('Initializing ClientCore...')
        self.my_ip = utils.get_host()
        print('Server IP address is set to ... ', self.my_ip)
        self.my_port = my_port
        self.my_core_host = c_host
        self.my_core_port = c_port
        self.blockchain = BlockChain()
        self.wallet = Wallet()
        self.cm = ConnectionManager4Edge(self.my_ip, self.my_port, c_host,
                                         c_port, self.__handle_message)
        self.callback = callback

    def start(self, my_pubkey=None):
        """
            Edgeノードとしての待受を開始する(上位UI層向け
        """
        self.client_state = STATE_ACTIVE
        self.cm.start()
        self.cm.connect_to_core_node()
        # |TODO  鍵

    def shutdown(self):
        """
            待ち受け状態のServer Socketを閉じて終了する(上位UI層向け
        """
        self.client_state = STATE_SHUTTING_DOWN
        print('Shutdown edge node ...')
        self.cm.connection_close()

    def send_req_full_chain(self):
        """
            接続コアノードに対してフルチェーンを要求
        """
        msg_txt = self.cm.get_message_text(MSG_REQUEST_FULL_CHAIN)
        self.cm.send_msg((self.my_core_host, self.my_core_port), msg_txt)

    def send_req_key_info(self):
        """
            コアノードに鍵情報の送信願いを送信
        """
        msg_type = MSG_REQUEST_KEY_INFO
        self.send_message_to_my_core_node(msg_type)

    def send_new_transaction(self, msg):
        """
            接続コアノードに対してトランザクションを送信
            msg: json
        """
        msg_type = MSG_NEW_TRANSACTION
        self.send_message_to_my_core_node(msg_type, msg)

    def send_message_to_my_core_node(self, msg_type, msg=None):
        """
            接続中のCoreノードに対してメッセージを送付する(上位UI層向け

            Params:
                msg_type : MessageManagerで規定のメッセージ種別を指定する
                msg : メッセージ本文。文字列化されたJSONを想定
        """
        msg_txt = self.cm.get_message_text(msg_type, msg)
        print(msg_txt)
        self.cm.send_msg((self.my_core_host, self.my_core_port), msg_txt)

    def get_my_blockchain(self):
        return self.blockchain.chain

    def __handle_message(self, msg):
        """
            ConnectionManager4Edgeに引き渡すコールバックの中身。
        """
        if msg[2] == RSP_FULL_CHAIN:
            new_block_chain = json.loads(msg[4])
            result = self.blockchain.resolve_conflicts(new_block_chain)
            if result is not None:
                self.callback()
            else:
                print('received chain is invalid')
        elif msg[2] == MSG_KEY_INFO:
            miner_wallet = pickle.loads(msg[4].encode('utf8'))
            self.wallet = miner_wallet
示例#34
0
#!/usr/bin/env python3

from blockchain import BlockChain, public_key_to_address, ripemd160_to_address

from collections import defaultdict

import sys

BALANCES = defaultdict(int)
OUTPUTS = {}

filename = sys.argv[1]
with open(filename, "rb") as f:
    data = f.read()
    block_chain = BlockChain(data)
    for block in block_chain.blocks():
        for transaction in block["transactions"]:
            for inp in transaction["inputs"]:
                if inp["transaction_hash"] == b"0000000000000000000000000000000000000000000000000000000000000000":
                    pass  # generated
                else:
                    address, value = OUTPUTS[(inp["transaction_hash"], inp["transaction_index"])]
                    BALANCES[address] -= value
            for output_num, output in enumerate(transaction["outputs"]):
                transaction_hash = transaction["hash"]
                index = output_num
                value = output["value"]
                script = output["script"]
                if len(script) == 2 and script[1] == "OP_CHECKSIG":
                    address = public_key_to_address(script[0])
                elif len(script) == 5 and (
示例#35
0
@app.route('/register/<path:path>')
def sendRegisFiles(path):
    return send_from_directory('Pages/Register', path)

#user regis page
@app.route('/regisUser', methods = ['GET'])
def regisUser():
    return render_template(cfg.PAGES['regisUser'])

#intro page
@app.route('/', methods = ['GET'])
def hello():
    return render_template(cfg.PAGES['intro'])

# creating global blockchain 
blockC = BlockChain.BlockChain()
blockC.port = port

@app.route('/login', methods = ['GET'])
def login():
    if(blockC.islogin()):
        return redirect(url_for("dashboard"))
    return render_template(cfg.PAGES['login'])


## Retry login page
@app.route('/logintry', methods = ['GET'])
def loginretry():
    if(blockC.islogin()):
        return redirect(url_for("dashboard"))
    return render_template(cfg.PAGES['login'])
from flask import Flask, render_template, jsonify, request, redirect

from uuid import uuid4
from blockchain import BlockChain
from datetime import datetime

app = Flask(__name__)

node_identifier = str(uuid4()).replace('-', '')

blockchain = BlockChain()  # object create


# 새로운 블록 생성, 매달 생성해줘야함!
@app.route('/mine', methods=['GET'])
def mine():
    month = datetime.today().month
    last_block = blockchain.last_block
    last_proof = last_block['proof']
    proof = blockchain.proof_of_work(last_proof)

    blockchain.new_transaction(sender='0',
                               recipient=node_identifier,
                               des=str(datetime.today().month) + " block",
                               use_money_time=datetime.today().month,
                               amount=1,
                               use_option=1)

    previous_hash = blockchain.hash(last_block)
    block = blockchain.new_block(proof, month, previous_hash)
示例#37
0
from blockchain import BlockChain
import pprint
import os
import random

blockchain = BlockChain()

####################################### INTERACTIVE MENU #########################################


def addTransaction():
    sender = input("Type sender name: ")
    recipient = input("Type recipient name: ")
    value = float(input("Value of transaction: "))
    value = str(value) + " BTC"
    blockchain.newTransaction(sender, recipient, value)


def menu():
    print("#############################\n")
    print("BLOCKCHAIN TRANSACTIONS\n")
    print("#############################\n")

    print("CHOOSE AN OPTION:\n")
    print(
        "1 - ADD TRANSACTION\n2 - VIEW CURRENT TRANSACIONS\n3 - VALIDATE BLOCK WITH CURRENT TRANSACTIONS\n4 - VIEW CHAIN\nOTHER VALUE - QUIT"
    )

    option = (input("\n-> "))
    return option