Example #1
0
 def setUp(self):
     self.blockchain = Blockchain()
     self.chain = self.blockchain.chain
     self.mempool = self.blockchain.mempool
     self.network = self.blockchain.network
     self.wallet = Wallet()
     self.initial_address = self.wallet.addresses[0]
Example #2
0
def main():
      
    path = os.getcwd()
    print(path)
    try:
        print('trying to read')
        os.chdir(path + '/blk')
        with open('blkchain.pkl', 'rb') as fp:
            chain = pickle.load(fp)
            fp.close()
    
    except:
        check = int(input("Are you miner or wallet :"))
        if check:
            print('Miner/Wallet started')
        else:

            print('Creating genesis')
            number_of_candidates = int(input("Enter number of candidates :"))
            trs = []
            for i in range(number_of_candidates):
                Name = input("Enter name :")
                age = input("Enter Age :")
                #usr = User(name=Name, age=age, publickey=sha256(Name.encode() + str(age).encode()).hexdigest(), privatekey=sha256(Name.encode() + str(age).encode()).hexdigest(), candidate=True)
                ts = Transaction(sha256(Name.encode() + str(age).encode()).hexdigest(), sha256(Name.encode() + str(age).encode()).hexdigest(), 0, name=Name)
                trs.append(ts)

            chain = Blockchain()
            chain.initialize_genesis(trs)
            os.mkdir('blk')
            os.chdir(path + '/blk')
            with open('blkchain.pkl', 'wb') as fp:
                pickle.dump(chain, fp)
                fp.close()
Example #3
0
 def test_should_hash_and_de_hash(self):
     block = {
         'index': 1,
         'timestamp': time(),
         'transactions': [],
         'proof': 1,
         'previous_hash': 'abcd',
     }
     res = Blockchain.hash(block)
     assert res
     proof = 0
     while Blockchain.valid_proof(1, proof) is False:
         proof += 1
     assert isinstance(proof, int)
Example #4
0
    async def test_reorg_from_genesis(self):
        blocks = bt.get_consecutive_blocks(test_constants, 20, [], 9, b"0")
        store = FullNodeStore("fndb_test")
        await store._clear_database()
        b: Blockchain = Blockchain(store, test_constants)
        await b.initialize()
        for block in blocks:
            await b.receive_block(block)
        assert b.get_current_tips()[0].height == 20

        # Reorg from genesis
        blocks_reorg_chain = bt.get_consecutive_blocks(test_constants, 21,
                                                       [blocks[0]], 9, b"1")
        for reorg_block in blocks_reorg_chain:
            result = await b.receive_block(reorg_block)
            if reorg_block.height == 0:
                assert result == ReceiveBlockResult.ALREADY_HAVE_BLOCK
            elif reorg_block.height < 19:
                assert result == ReceiveBlockResult.ADDED_AS_ORPHAN
            else:
                assert result == ReceiveBlockResult.ADDED_TO_HEAD
        assert b.get_current_tips()[0].height == 21

        # Reorg back to original branch
        blocks_reorg_chain_2 = bt.get_consecutive_blocks(
            test_constants, 3, blocks, 9, b"3")
        await b.receive_block(blocks_reorg_chain_2[20]
                              ) == ReceiveBlockResult.ADDED_AS_ORPHAN
        assert (await b.receive_block(blocks_reorg_chain_2[21]
                                      )) == ReceiveBlockResult.ADDED_TO_HEAD
        assert (await b.receive_block(blocks_reorg_chain_2[22]
                                      )) == ReceiveBlockResult.ADDED_TO_HEAD
Example #5
0
    async def test_difficulty_change(self):
        num_blocks = 30
        # Make it 5x faster than target time
        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 2)

        b: Blockchain = Blockchain(test_constants)
        await b.initialize({})
        for i in range(1, num_blocks):
            assert (await
                    b.receive_block(blocks[i]
                                    )) == ReceiveBlockResult.ADDED_TO_HEAD

        diff_25 = b.get_next_difficulty(blocks[24].header_hash)
        diff_26 = b.get_next_difficulty(blocks[25].header_hash)
        diff_27 = b.get_next_difficulty(blocks[26].header_hash)

        assert diff_26 == diff_25
        assert diff_27 > diff_26
        assert (diff_27 / diff_26) <= test_constants["DIFFICULTY_FACTOR"]

        assert (b.get_next_ips(
            blocks[1].header_hash)) == constants["VDF_IPS_STARTING"]
        assert (b.get_next_ips(blocks[24].header_hash)) == (b.get_next_ips(
            blocks[23].header_hash))
        assert (b.get_next_ips(blocks[25].header_hash)) == (b.get_next_ips(
            blocks[24].header_hash))
        assert (b.get_next_ips(blocks[26].header_hash)) > (b.get_next_ips(
            blocks[25].header_hash))
        assert (b.get_next_ips(blocks[27].header_hash)) == (b.get_next_ips(
            blocks[26].header_hash))
    async def test1(self):
        store = FullNodeStore("fndb_test")
        await store._clear_database()
        blocks = bt.get_consecutive_blocks(test_constants, 10, [], 10)
        b: Blockchain = Blockchain(test_constants)
        await store.add_block(blocks[0])
        await b.initialize({})
        for i in range(1, 9):
            assert (await
                    b.receive_block(blocks[i]
                                    )) == ReceiveBlockResult.ADDED_TO_HEAD
            await store.add_block(blocks[i])

        full_node_1 = FullNode(store, b)
        server_1 = ChiaServer(21234, full_node_1, NodeType.FULL_NODE)
        _ = await server_1.start_server("127.0.0.1", None)
        full_node_1._set_server(server_1)

        full_node_2 = FullNode(store, b)
        server_2 = ChiaServer(21235, full_node_2, NodeType.FULL_NODE)
        full_node_2._set_server(server_2)

        await server_2.start_client(PeerInfo("127.0.0.1", uint16(21234)), None)

        await asyncio.sleep(2)  # Allow connections to get made

        num_unfinished_blocks = 1000
        start_unf = time.time()
        for i in range(num_unfinished_blocks):
            msg = Message("unfinished_block",
                          peer_protocol.UnfinishedBlock(blocks[9]))
            server_1.push_message(
                OutboundMessage(NodeType.FULL_NODE, msg, Delivery.BROADCAST))

        # Send the whole block ast the end so we can detect when the node is done
        block_msg = Message("block", peer_protocol.Block(blocks[9]))
        server_1.push_message(
            OutboundMessage(NodeType.FULL_NODE, block_msg, Delivery.BROADCAST))

        while time.time() - start_unf < 300:
            if max([h.height for h in b.get_current_tips()]) == 9:
                print(
                    f"Time taken to process {num_unfinished_blocks} is {time.time() - start_unf}"
                )
                server_1.close_all()
                server_2.close_all()
                await server_1.await_closed()
                await server_2.await_closed()
                return
            await asyncio.sleep(0.1)

        server_1.close_all()
        server_2.close_all()
        await server_1.await_closed()
        await server_2.await_closed()
        raise Exception("Took too long to process blocks")
Example #7
0
 async def test_get_header_hashes(self):
     blocks = bt.get_consecutive_blocks(test_constants, 5, [], 9, b"0")
     b: Blockchain = Blockchain(test_constants)
     await b.initialize({})
     for block in blocks:
         await b.receive_block(block)
     header_hashes = b.get_header_hashes(blocks[-1].header_hash)
     assert len(header_hashes) == 6
     print(header_hashes)
     print([block.header_hash for block in blocks])
     assert header_hashes == [block.header_hash for block in blocks]
Example #8
0
 async def initial_blockchain(self):
     """
     Provides a list of 10 valid blocks, as well as a blockchain with 9 blocks added to it.
     """
     blocks = bt.get_consecutive_blocks(test_constants, 10, [], 10)
     b: Blockchain = Blockchain(test_constants)
     await b.initialize({})
     for i in range(1, 9):
         assert (await
                 b.receive_block(blocks[i]
                                 )) == ReceiveBlockResult.ADDED_TO_HEAD
     return (blocks, b)
Example #9
0
 async def test_basic_blockchain(self):
     bc1: Blockchain = Blockchain()
     await bc1.initialize({})
     assert len(bc1.get_current_tips()) == 1
     genesis_block = bc1.get_current_tips()[0]
     assert genesis_block.height == 0
     assert genesis_block.challenge
     assert (bc1.get_header_blocks_by_height(
         [uint32(0)], genesis_block.header_hash))[0] == genesis_block
     assert (bc1.get_next_difficulty(
         genesis_block.header_hash)) == genesis_block.challenge.total_weight
     assert bc1.get_next_ips(genesis_block.header_hash) > 0
Example #10
0
    def update_balances(self, chain):
        """
        Update the balance for each address.
        :param chain: <list> The blockchain
        :return: None
        """

        last_block_index = len(chain)

        for address in self.address_to_balance:
            balance = Blockchain.address_balance_at_block_index(
                address, chain, last_block_index)
            self.address_to_balance[address] = balance
Example #11
0
 async def test_get_header_hashes(self):
     blocks = bt.get_consecutive_blocks(test_constants, 5, [], 9, b"0")
     store = FullNodeStore("fndb_test")
     await store._clear_database()
     b: Blockchain = Blockchain(store, test_constants)
     await b.initialize()
     for block in blocks:
         await b.receive_block(block)
     header_hashes = b.get_header_hashes(blocks[-1].header_hash)
     assert len(header_hashes) == 6
     print(header_hashes)
     print([block.header_hash for block in blocks])
     assert header_hashes == [block.header_hash for block in blocks]
Example #12
0
 async def test_basic_blockchain(self):
     store = FullNodeStore("fndb_test")
     await store._clear_database()
     bc1: Blockchain = Blockchain(store)
     await bc1.initialize()
     assert len(bc1.get_current_tips()) == 1
     genesis_block = bc1.get_current_tips()[0]
     assert genesis_block.height == 0
     assert genesis_block.challenge
     assert (bc1.get_header_blocks_by_height(
         [uint32(0)], genesis_block.header_hash))[0] == genesis_block
     assert (await bc1.get_next_difficulty(
         genesis_block.header_hash)) == genesis_block.challenge.total_weight
     assert await bc1.get_next_ips(genesis_block.header_hash) > 0
Example #13
0
 async def initial_blockchain(self):
     """
     Provides a list of 10 valid blocks, as well as a blockchain with 9 blocks added to it.
     """
     store = FullNodeStore("fndb_test")
     await store._clear_database()
     blocks = bt.get_consecutive_blocks(test_constants, 10, [], 10)
     b: Blockchain = Blockchain(store, test_constants)
     await b.initialize()
     for i in range(1, 9):
         assert (await
                 b.receive_block(blocks[i]
                                 )) == ReceiveBlockResult.ADDED_TO_HEAD
     return (blocks, b)
    async def test2(self):
        num_blocks = 100
        store = FullNodeStore("fndb_test")
        await store._clear_database()
        blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10)
        b: Blockchain = Blockchain(test_constants)
        await store.add_block(blocks[0])
        await b.initialize({})

        full_node_1 = FullNode(store, b)
        server_1 = ChiaServer(21236, full_node_1, NodeType.FULL_NODE)
        _ = await server_1.start_server("127.0.0.1", None)
        full_node_1._set_server(server_1)

        full_node_2 = FullNode(store, b)
        server_2 = ChiaServer(21237, full_node_2, NodeType.FULL_NODE)
        full_node_2._set_server(server_2)

        await server_2.start_client(PeerInfo("127.0.0.1", uint16(21236)), None)

        await asyncio.sleep(2)  # Allow connections to get made

        start_unf = time.time()
        for i in range(1, num_blocks):
            msg = Message("block", peer_protocol.Block(blocks[i]))
            server_1.push_message(
                OutboundMessage(NodeType.FULL_NODE, msg, Delivery.BROADCAST))

        while time.time() - start_unf < 300:
            if max([h.height for h in b.get_current_tips()]) == num_blocks - 1:
                print(
                    f"Time taken to process {num_blocks} is {time.time() - start_unf}"
                )
                server_1.close_all()
                server_2.close_all()
                await server_1.await_closed()
                await server_2.await_closed()
                return
            await asyncio.sleep(0.1)

        server_1.close_all()
        server_2.close_all()
        await server_1.await_closed()
        await server_2.await_closed()
        raise Exception("Took too long to process blocks")
Example #15
0
    async def test_basic_reorg(self):
        blocks = bt.get_consecutive_blocks(test_constants, 100, [], 9)
        b: Blockchain = Blockchain(test_constants)
        await b.initialize({})

        for block in blocks:
            await b.receive_block(block)
        assert b.get_current_tips()[0].height == 100

        blocks_reorg_chain = bt.get_consecutive_blocks(test_constants, 30,
                                                       blocks[:90], 9, b"1")
        for reorg_block in blocks_reorg_chain:
            result = await b.receive_block(reorg_block)
            if reorg_block.height < 90:
                assert result == ReceiveBlockResult.ALREADY_HAVE_BLOCK
            elif reorg_block.height < 99:
                assert result == ReceiveBlockResult.ADDED_AS_ORPHAN
            elif reorg_block.height >= 100:
                assert result == ReceiveBlockResult.ADDED_TO_HEAD
        assert b.get_current_tips()[0].height == 119
Example #16
0
    async def test_lca(self):
        blocks = bt.get_consecutive_blocks(test_constants, 5, [], 9, b"0")
        b: Blockchain = Blockchain(test_constants)
        await b.initialize({})
        for block in blocks:
            await b.receive_block(block)

        assert b.lca_block == blocks[3].header_block
        block_5_2 = bt.get_consecutive_blocks(test_constants, 1, blocks[:5], 9,
                                              b"1")[5]
        block_5_3 = bt.get_consecutive_blocks(test_constants, 1, blocks[:5], 9,
                                              b"2")[5]

        await b.receive_block(block_5_2)
        assert b.lca_block == blocks[4].header_block
        await b.receive_block(block_5_3)
        assert b.lca_block == blocks[4].header_block

        reorg = bt.get_consecutive_blocks(test_constants, 6, [], 9, b"3")
        for block in reorg:
            await b.receive_block(block)
        assert b.lca_block == blocks[0].header_block
Example #17
0
    async def test_lca(self):
        blocks = bt.get_consecutive_blocks(test_constants, 5, [], 9, b"0")
        store = FullNodeStore("fndb_test")
        await store._clear_database()
        b: Blockchain = Blockchain(store, test_constants)
        await b.initialize()
        for block in blocks:
            await b.receive_block(block)

        assert b.lca_block == blocks[3]
        block_5_2 = bt.get_consecutive_blocks(test_constants, 1, blocks[:5], 9,
                                              b"1")[5]
        block_5_3 = bt.get_consecutive_blocks(test_constants, 1, blocks[:5], 9,
                                              b"2")[5]

        await b.receive_block(block_5_2)
        assert b.lca_block == blocks[4]
        await b.receive_block(block_5_3)
        assert b.lca_block == blocks[4]

        reorg = bt.get_consecutive_blocks(test_constants, 6, [], 9, b"3")
        for block in reorg:
            await b.receive_block(block)
        assert b.lca_block == blocks[0]
class NetworkHandler:
    def __init__(self, first=False):
        self.other_nodes = {}
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connected_clients = []
        self.blockchain = None
        self.name = None
        self.server_host = get_local_ip()
        self.message_list = []
        self.ip = str(get_local_ip())

        # self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.keep_running_server = True

        self.manual_validation = False
        self.block_to_add = None
        self.wait = False
        self.client = None

        self.updateVisualizer()

    def create_blockchain(self, first):
        self.blockchain = Blockchain(first=first)

    def start_server(self):
        self.server.bind((self.server_host, SERVER_PORT))
        self.server.listen(5)

    def add_node(self, ip, name):
        node = Node(ip, name)
        self.other_nodes[ip] = node
        self.updateVisualizer()

    def remove_node(self, ip):
        try:
            del self.other_nodes[ip]
        except KeyError:
            print(f"{ip} tried to be removed but not in list")
        self.updateVisualizer()

    def process_message(self, message, ip, i):
        print(f"\n\nRECEIVED from {ip} in {i} chunks: \n{message}\n\n")

        message_dict = {"sender": ip, "content": message}
        self.message_list.append(message_dict)
        self.updateVisualizerMessage()

        if message[:4] != "****":
            print("Error: bad request")
        elif message.split("|")[0][4:] == "join":
            self.join_protocol(ip, message)

        elif message[4:] == "leave":
            print("===== Remove node")
            self.remove_node(ip)

        elif message.split("|")[0][4:] == "join_resp":
            self.join_resp_protocol(ip, message)

        elif message.split("|")[0][4:] == "joined":
            self.add_node(ip, message.split("|")[1])
            print("===== Nice to meet you")

        elif message[4:] == "ack":
            print("===== Welcome")

        elif message.split("|")[0][4:] == "mined_block":
            self.mined_block_protocol(message)

        elif message.split("|")[0][4:] == "accept":
            hash_block = message.split("|")[1]
            if self.blockchain.get_block(hash_block) is None:
                mess = "****askblock|" + hash_block
                send_message(ip, mess)
            print("===== Node accepted")

        elif message[4:] == "refuse":
            print("===== Node refused")

        elif message.split("|")[0][4:] == "blockchain":
            self.blockchain_protocol(message)

        elif message.split("|")[0][4:] == "ackdefault":
            print("==== This node may be defective")

        elif message.split("|")[0][4:] == "askblock":
            hash_block = message.split("|")[1]
            block_to_send = self.blockchain.get_block(hash_block)
            mess = "****"
            mess += "mined_block|"
            mess += json.dumps(block_to_send, cls=BlockEncoder)
            send_message(ip, mess)

        else:
            print("Error: bad request")

        print(f"Other nodes: {self.other_nodes}")

    def blockchain_protocol(self, message):
        blockchain = json.loads(message.split("|")[1])
        leaves = json.loads(message.split("|")[2])
        blockchain = [Block(**block) for block in blockchain]
        blockchain.sort()  # The blocks are sorted by height.

        for block in blockchain:
            self.blockchain.new_block(block)

    def mined_block_protocol(self, message):
        block_info_json = json.loads(message.split("|")[1])
        self.block_to_add = Block(**block_info_json)
        self.client.hiddenRefreshButton.click()
        if self.manual_validation:
            self.wait = True
            while self.wait:
                pass

        else:
            message = self.blockchain.new_block(self.block_to_add)
            for ip_node in self.other_nodes:
                send_message(ip_node, message)
            message_dict = {"sender": "Me", "content": message}
            self.message_list.append(message_dict)

        self.block_to_add = None
        self.client.hiddenRefreshButton.click()

    def join_resp_protocol(self, ip, message):
        nodes_dict_str = message.split("|")[1]
        nodes_dict = json.loads(nodes_dict_str)
        for node_dict in nodes_dict.values():
            self.other_nodes[node_dict["ip"]] = Node(node_dict["ip"], node_dict["name"])
        self.add_node(ip, message.split("|")[2])
        for node in self.other_nodes.values():
            send_message(node.ip_address, "****joined|" + self.name)
        message_dict = {"sender": "Me", "content": "****joined"}
        self.message_list.append(message_dict)

    def join_protocol(self, ip, message):
        print("===== Add node")
        mess = "****join_resp|"
        mess += json.dumps(self.other_nodes, cls=NodeEncoder)
        mess += "|"
        mess += self.name
        send_message(ip, mess)
        self.add_node(ip, message.split("|")[1])
        message_dict = {"sender": "Me", "content": mess}
        self.message_list.append(message_dict)
        mess2 = "****blockchain|"
        list_blocks = []

        leaves = self.blockchain.get_leaves()

        for leaf in leaves:
            leaf_block = self.blockchain.get_block(leaf["hash"])
            current_block = leaf_block
            for i in range(0, leaf_block.index + 1):
                if current_block not in list_blocks:
                    list_blocks.append(current_block)
                if current_block.index != 0:
                    current_block = self.blockchain.get_block(
                        current_block.previous_hash
                    )

        mess2 += json.dumps(list_blocks, cls=BlockEncoder)
        mess2 += "|"

        mess2 += json.dumps(leaves)

        if mess2 != "":
            send_message(ip, mess2)
            message_dict2 = {"sender": "Me", "content": mess2}
            self.message_list.append(message_dict)

    def send_message_to_all(self, message):
        self.updateVisualizerMessage()
        for ip in self.other_nodes.keys():
            send_message(ip, message)

    def updateVisualizer(self):
        all_nodes = []
        for node in self.other_nodes.values():
            node_dic = {"name": node.name, "ip": node.ip_address}  # "Prenom" to change
            all_nodes.append(node_dic)
        my_node = {"name": "You", "ip": self.ip}
        all_nodes.insert(0, my_node)

        nodes = {"nodes": all_nodes}
        nodes_json = json.dumps(nodes)
        with open("etc/visudata/nodes.json", "w") as file:
            file.write(nodes_json)

    def updateVisualizerMessage(self):
        messages = {"messages": self.message_list}
        messages_json = json.dumps(messages)
        with open("etc/visudata/messages.json", "w") as file:
            file.write(messages_json)

    def accept_mined_block(self):
        leaves = self.blockchain.get_leaves()
        leaves_hashes = [leaf["hash"] for leaf in leaves]
        if self.blockchain.nb_children(self.block_to_add.previous_hash) > 0:
            # The previous block is not a leaf, so we create a fork
            # if block.previous_hash in leaves_hashes:
            # Just to check
            # raise ValueError(
            #    f"Inconsistent data: block {block.previous_hash} is "
            #    "listed as a leaf but has at least one child block."
            # )
            fork_id = self.blockchain.add_fork(
                self.block_to_add.hash, self.block_to_add.index
            )
            self.block_to_add.branch_id = fork_id
            self.blockchain.add_block(self.block_to_add)

        else:  # The previous block is a leaf, so we stay on the same branch
            parent_leaf = [
                leaf
                for leaf in leaves
                if leaf["hash"] == self.block_to_add.previous_hash
            ]
            if len(parent_leaf) != 1:
                raise ValueError(
                    f"Inconsistent data: block {block.previous_hash} is "
                    f"the leaf block of {len(parent_leaf)} branches (should be 1)."
                )
            parent_leaf = parent_leaf[0]
            self.block_to_add.branch_id = parent_leaf["fork_id"]
            self.blockchain.add_block(self.block_to_add)
            self.blockchain.update_fork(
                parent_leaf["fork_id"], self.block_to_add.hash, self.block_to_add.index
            )

        self.send_message_to_all("****accept|" + self.block_to_add.hash)
        self.wait = False
        self.client.hiddenRefreshButton.click()

    def refuse_mined_block(self):
        self.send_message_to_all("****refuse")

        self.wait = False
        self.block_to_add = None
        self.client.hiddenRefreshButton.click()

    def run_server(self):
        while self.keep_running_server:
            incoming_connections, wlist, xlist = select.select(
                [self.server], [], [], LISTEN_TIME
            )

            for connection in incoming_connections:
                client_connection, client_connection_info = connection.accept()
                self.connected_clients.append(client_connection)

            clients_to_be_read = []
            try:
                clients_to_be_read, wlist, xlist = select.select(
                    self.connected_clients, [], [], LISTEN_TIME
                )
            except select.error:
                pass
            else:
                for client in clients_to_be_read:
                    message = b""
                    chunks = 0
                    while True:
                        chunks += 1
                        part = client.recv(RECV_SIZE)
                        if len(part) == 0:  # We have reached the end of the stream
                            break
                        message += part
                    ip, port = client.getpeername()
                    message = message.decode()
                    self.process_message(message, ip, chunks)
                    self.connected_clients.remove(client)
                    client.close()

        for client in self.connected_clients:
            client.close()
 def create_blockchain(self, first):
     self.blockchain = Blockchain(first=first)
Example #20
0
parser.add_argument(
    '-o',
    type=str,
    help=
    'output file without requiring an initial blockchain file to read from (default: \'blockchain.json\')'
)

args = parser.parse_args()
node_id = uuid()

if __name__ == '__main__':
    # Load Blockchain File
    filename = args.file
    if filename:
        data = json.load(open(filename))
        blockchain = Blockchain(
            list(map(lambda block: block['header'], data['chain'])))
    else:
        filename = args.o
        blockchain = Blockchain()

    node = SPVNode(name=args.n or f'node-{node_id}',
                   port=args.p or 5000,
                   blockchain=blockchain)

    try:
        print(f'Starting node-{node_id}')

        # Establish Connection
        while not node.ready:
            node.send('version',
                      message=json.dumps(
Example #21
0
from flask import Flask, jsonify, request, redirect, url_for
from src.blockchain import Blockchain
from src.wallet import Wallet

app = Flask(__name__)

blockchain = Blockchain('bank')

@app.route('/add_transaction', methods=['POST'])
def add_transaction():
    json = request.get_json()
    transaction_keys = ['sender', 'receiver', 'amount']
    if not all(key in json for key in transaction_keys):
        return 'Está faltando algum elemento.', 400
    index = blockchain.add_transaction(json['sender'], json['receiver'], json['amount'])
    response = {'mensagem': f'Esta transação será adicionada ao bloco {index}'}
    return jsonify(response), 201

@app.route('/delete_transaction')
def delete_transaction():
    blockchain.delete_transaction()
    return jsonify({'mensagem':'Transação deletada!'})



@app.route('/mine_block/<hosting>', methods=['GET'])
def mine_block(hosting):
    w = Wallet()
    if not w.read_wallet(hosting):
        return jsonify({'mensagem':'Falta hosting wallet!'})
    blockchain.wallet = w
Example #22
0
from src.block import Block
from src.blockchain import Blockchain

# genesis = Block.getGenesis()
# bloque1 = Block.mine(genesis,'D4t4-Bloqu3_1')
# bloque2 = Block.mine(bloque1,'D4t4-Bloqu3_2')
# print(bloque1)
# print(bloque2)

print("Test 1 -Every blockchain has a Genesis Block")
blockchain = Blockchain()
genesis = blockchain.blocks[0]
print(genesis)

print("Test 2 - use addBlock")
blockchain = Blockchain()
data = 'd4t4-blk1'
blockchain.addBlock(data)
lastBlock = blockchain.blocks[-1]
print(lastBlock.data == data)
print(len(blockchain.blocks) == 2)

print("Test 3 - replaces the chain with a valid chain")
blockchain = Blockchain()
blockchainb = Blockchain()
data = 'd4t4-blk1'
blockchainb.addBlock(data)
blockchain.replaceBlock(blockchainb.blocks)
print(blockchain.blocks == blockchainb.blocks)

print("Test 4 - Does not replace with one with less blocks")
from flask import Flask, jsonify, request
from flask_restful import reqparse, abort, Api, Resource
from src.blockchain import Blockchain

app = Flask(__name__)
api = Api(app)

blockchain = Blockchain('Alex')


class Get_Chain(Resource):
    def get(self):
        response = {'chain': blockchain.chain, 'length': len(blockchain.chain)}

        return response, 200


class Add_Transaction(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('sender', required=True, help='Obrigatório!')
        parser.add_argument('receiver', required=True, help='Obrigatório!')
        parser.add_argument('amount',
                            type=float,
                            required=True,
                            help='Obrigatório!')
        args = parser.parse_args()
        index = blockchain.add_transaction(args['sender'], args['receiver'],
                                           args['amount'])
        response = {
            'mensagem': f'Esta transação será adicionada ao bloco {index}'
Example #24
0
class MainTestCase(TestCase):
    def setUp(self):
        self.blockchain = Blockchain()
        self.chain = self.blockchain.chain
        self.mempool = self.blockchain.mempool
        self.network = self.blockchain.network
        self.wallet = Wallet()
        self.initial_address = self.wallet.addresses[0]

    def test_initialize_blockchain(self):
        self.assertEqual(len(self.chain), 1)
        self.assertTrue(self.blockchain.valid_chain(self.chain))
        self.assertFalse(self.mempool.current_transactions)
        self.assertFalse(self.network.nodes)

    def test_initialize_wallet(self):
        self.assertEqual(len(self.wallet.addresses), 1)
        self.assertEqual(len(self.wallet.address_to_keys), 1)
        self.assertEqual(len(self.wallet.address_to_balance), 1)
        self.assertEqual(self.wallet.address_to_balance[self.initial_address],
                         0)
        self.assertEqual(self.wallet.total_balance(), 0)
        self.assertEqual(
            privtopub(self.wallet.address_to_keys[self.initial_address][0]),
            self.wallet.address_to_keys[self.initial_address][1])
        self.assertEqual(
            pubtoaddr(self.wallet.address_to_keys[self.initial_address][1]),
            self.initial_address)

    def test_wallet_generate_address(self):
        self.wallet.generate_address()
        new_address = self.wallet.addresses[1]
        self.assertEqual(len(self.wallet.addresses), 2)
        self.assertEqual(len(self.wallet.address_to_keys), 2)
        self.assertEqual(len(self.wallet.address_to_balance), 2)
        self.assertEqual(self.wallet.address_to_balance[new_address], 0)
        self.assertEqual(self.wallet.total_balance(), 0)
        self.assertEqual(
            privtopub(self.wallet.address_to_keys[new_address][0]),
            self.wallet.address_to_keys[new_address][1])
        self.assertEqual(
            pubtoaddr(self.wallet.address_to_keys[new_address][1]),
            new_address)

    def test_wallet_sign_transaction(self):
        signed_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0)
        signature = signed_transaction['signature']
        transaction_content = {
            'sender': self.initial_address,
            'recipient': '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD',
            'amount': 0
        }
        transaction_encoded = json.dumps(transaction_content,
                                         sort_keys=True).encode()
        transaction_hash = hashlib.sha256(transaction_encoded).hexdigest()

        self.assertEqual(
            signature,
            ecdsa_sign(transaction_hash,
                       self.wallet.address_to_keys[self.initial_address][0]))

    def test_proof_of_work(self):
        transactions_hash = self.mempool.hash([])
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)

        encoded = f'{transactions_hash}{previous_block_hash}{nonce}'.encode()
        hashed = hashlib.sha256(encoded).hexdigest()

        self.assertEqual(hashed[:4], '0000')
        self.assertTrue(
            ProofOfWork.valid_proof(transactions_hash, previous_block_hash,
                                    nonce))

    def test_proof_of_work_invalid_nonce(self):
        transactions_hash = self.mempool.hash([])
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = 12345

        self.assertFalse(
            ProofOfWork.valid_proof(transactions_hash, previous_block_hash,
                                    nonce))

    def test_mempool_add_valid_transaction(self):
        signed_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0)

        self.assertTrue(
            self.mempool.valid_transaction(signed_transaction,
                                           self.blockchain))
        self.assertTrue(
            self.mempool.add_transaction(signed_transaction, self.blockchain))
        self.assertEqual(len(self.mempool.current_transactions), 1)

    def test_mempool_add_invalid_transaction(self):
        # too high amount of coins
        invalid_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 10)

        self.assertFalse(
            self.mempool.valid_transaction(invalid_transaction,
                                           self.blockchain))
        self.assertFalse(
            self.mempool.add_transaction(invalid_transaction, self.blockchain))
        self.assertEqual(len(self.mempool.current_transactions), 0)

        # negative amount of coins
        invalid_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', -1)

        self.assertFalse(
            self.mempool.valid_transaction(invalid_transaction,
                                           self.blockchain))
        self.assertFalse(
            self.mempool.add_transaction(invalid_transaction, self.blockchain))
        self.assertEqual(len(self.mempool.current_transactions), 0)

        # invalid signature
        invalid_transaction = {
            'sender':
            self.initial_address,
            'recipient':
            '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD',
            'amount':
            0,
            'signature':
            'GwQr4EOfrRUicb34fgB9ix69PNa8nMjSXEgZfBRFha9tWQCvgaWco5v8JlIU89WDHLX6gTLHn9qIIEaV0mzxFoM='
        }

        self.assertFalse(
            self.mempool.valid_transaction(invalid_transaction,
                                           self.blockchain))
        self.assertFalse(
            self.mempool.add_transaction(invalid_transaction, self.blockchain))
        self.assertEqual(len(self.mempool.current_transactions), 0)

    def test_register_node(self):
        self.network.register_node('http://192.168.0.1:5000')

        self.assertIn('192.168.0.1:5000', self.network.nodes)
        self.assertEqual(len(self.network.nodes), 1)

    def test_register_duplicate_node(self):
        self.network.register_node('http://192.168.0.1:5000')
        self.network.register_node('http://192.168.0.1:5000')

        self.assertEqual(len(self.network.nodes), 1)

    def test_register_invalid_node(self):
        self.network.register_node('http//192.168.0.1:5000')
        self.assertNotIn('192.168.0.1:5000', self.network.nodes)
        self.assertEqual(len(self.network.nodes), 0)

    def test_create_block(self):
        signed_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0)
        self.mempool.add_transaction(signed_transaction, self.blockchain)
        transactions_hash = self.mempool.hash(
            self.mempool.current_transactions)
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)
        self.blockchain.create_block(nonce, previous_block_hash,
                                     self.mempool.current_transactions)
        created_block = self.blockchain.last_block

        self.assertEqual(len(self.blockchain.chain), 2)
        self.assertEqual(created_block, self.blockchain.chain[-1])
        self.assertEqual(created_block['index'], 2)
        self.assertIsNotNone(created_block['timestamp'])
        self.assertEqual(created_block['nonce'], nonce)
        self.assertEqual(created_block['transactions_hash'], transactions_hash)
        self.assertEqual(created_block['previous_block_hash'],
                         previous_block_hash)
        self.assertEqual(created_block['transactions'], [signed_transaction])
        self.assertEqual(len(self.mempool.current_transactions), 0)

    def test_block_hash(self):
        signed_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0)
        self.mempool.add_transaction(signed_transaction, self.blockchain)
        transactions_hash = self.mempool.hash(
            self.mempool.current_transactions)
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)
        self.blockchain.create_block(nonce, previous_block_hash,
                                     self.mempool.current_transactions)
        created_block = self.blockchain.last_block

        block_encoded = json.dumps(created_block, sort_keys=True).encode()
        block_hash = hashlib.sha256(block_encoded).hexdigest()

        self.assertEqual(len(self.blockchain.hash(created_block)), 64)
        self.assertEqual(self.blockchain.hash(created_block), block_hash)

    def test_valid_chain(self):
        signed_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0)
        self.mempool.add_transaction(signed_transaction, self.blockchain)
        transactions_hash = self.mempool.hash(
            self.mempool.current_transactions)
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)
        self.blockchain.create_block(nonce, previous_block_hash,
                                     self.mempool.current_transactions)

        self.assertTrue(self.blockchain.valid_chain(self.blockchain.chain))

    def test_valid_chain_transactions(self):
        # Mine 10 coins to initial_address
        coinbase_transaction = {
            'sender': '0',
            'recipient': self.initial_address,
            'amount': 10
        }
        transactions_hash = self.mempool.hash([coinbase_transaction])
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)
        self.blockchain.create_block(nonce, previous_block_hash,
                                     [coinbase_transaction])

        # Spend the mined coins
        signed_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 10)
        self.mempool.add_transaction(signed_transaction, self.blockchain)
        transactions_hash = self.mempool.hash(
            self.mempool.current_transactions)
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)
        self.blockchain.create_block(nonce, previous_block_hash,
                                     self.mempool.current_transactions)

        self.assertTrue(self.blockchain.valid_chain(self.blockchain.chain))

    def test_invalid_chain_prev_block_hash(self):
        signed_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0)
        transactions_hash = self.mempool.hash(
            self.mempool.current_transactions)
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)

        block = {
            'index': len(self.chain) + 1,
            'timestamp': time(),
            'nonce': nonce,
            'transactions_hash': transactions_hash,
            'previous_block_hash': '12345',
            'transactions': [signed_transaction]
        }

        self.blockchain.chain.append(block)

        self.assertFalse(self.blockchain.valid_chain(self.blockchain.chain))

    def test_invalid_chain_nonce(self):
        signed_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 0)
        transactions_hash = self.mempool.hash(
            self.mempool.current_transactions)
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)

        block = {
            'index': len(self.chain) + 1,
            'timestamp': time(),
            'nonce': 12345,
            'transactions_hash': transactions_hash,
            'previous_block_hash': previous_block_hash,
            'transactions': [signed_transaction]
        }

        self.blockchain.chain.append(block)

        self.assertFalse(self.blockchain.valid_chain(self.blockchain.chain))

    def test_invalid_chain_coinbase_transaction_amount(self):
        coinbase_transaction = {
            'sender': '0',
            'recipient': self.initial_address,
            'amount': 100
        }
        transactions_hash = self.mempool.hash([coinbase_transaction])
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)

        block = {
            'index': len(self.chain) + 1,
            'timestamp': time(),
            'nonce': nonce,
            'transactions_hash': transactions_hash,
            'previous_block_hash': previous_block_hash,
            'transactions': [coinbase_transaction]
        }

        self.blockchain.chain.append(block)

        self.assertFalse(self.blockchain.valid_chain(self.blockchain.chain))

    def test_invalid_chain_coinbase_transaction_duplicate(self):
        coinbase_transaction = {
            'sender': '0',
            'recipient': self.initial_address,
            'amount': 10
        }
        transactions_hash = self.mempool.hash(
            [coinbase_transaction, coinbase_transaction])
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)

        block = {
            'index': len(self.chain) + 1,
            'timestamp': time(),
            'nonce': nonce,
            'transactions_hash': transactions_hash,
            'previous_block_hash': previous_block_hash,
            'transactions': [coinbase_transaction, coinbase_transaction]
        }

        self.blockchain.chain.append(block)

        self.assertFalse(self.blockchain.valid_chain(self.blockchain.chain))

    def test_invalid_chain_transactions(self):
        # Mine 10 coins to initial_address
        coinbase_transaction = {
            'sender': '0',
            'recipient': self.initial_address,
            'amount': 10
        }
        transactions_hash = self.mempool.hash([coinbase_transaction])
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)
        self.blockchain.create_block(nonce, previous_block_hash,
                                     [coinbase_transaction])

        # Include a transaction in block with to much coins spent
        signed_transaction = self.wallet.sign_transaction(
            self.initial_address, '14peaf2JegQP5nmNQESAdpRGLbse8JqgJD', 100)
        self.mempool.current_transactions.append(signed_transaction)
        transactions_hash = self.mempool.hash(
            self.mempool.current_transactions)
        previous_block_hash = self.blockchain.hash(self.blockchain.last_block)
        nonce = ProofOfWork.proof_of_work(transactions_hash,
                                          previous_block_hash)
        self.blockchain.create_block(nonce, previous_block_hash,
                                     self.mempool.current_transactions)

        self.assertFalse(self.blockchain.valid_chain(self.blockchain.chain))
async def main():
    # Create the store (DB) and full node instance
    db_id = 0
    if "-id" in sys.argv:
        db_id = int(sys.argv[sys.argv.index("-id") + 1])
    store = FullNodeStore(f"fndb_{db_id}")

    blockchain = Blockchain(store)
    log.info("Initializing blockchain from disk")
    await blockchain.initialize()

    full_node = FullNode(store, blockchain)
    # Starts the full node server (which full nodes can connect to)
    host, port = parse_host_port(full_node)

    if full_node.config["enable_upnp"]:
        log.info(f"Attempting to enable UPnP (open up port {port})")
        try:
            upnp = miniupnpc.UPnP()
            upnp.discoverdelay = 5
            upnp.discover()
            upnp.selectigd()
            upnp.addportmapping(port, "TCP", upnp.lanaddr, port, "chia", "")
        except Exception as e:
            log.warning(f"UPnP failed: {e}")

    server = ChiaServer(port, full_node, NodeType.FULL_NODE)
    full_node._set_server(server)
    _ = await server.start_server(host, full_node._on_connect)
    wait_for_ui, ui_close_cb = None, None

    def master_close_cb():
        global server_closed
        if not server_closed:
            # Called by the UI, when node is closed, or when a signal is sent
            log.info("Closing all connections, and server...")
            full_node._shutdown()
            server.close_all()
            server_closed = True

    def signal_received():
        if ui_close_cb:
            ui_close_cb()
        master_close_cb()

    asyncio.get_running_loop().add_signal_handler(signal.SIGINT,
                                                  signal_received)
    asyncio.get_running_loop().add_signal_handler(signal.SIGTERM,
                                                  signal_received)

    if "-u" in sys.argv:
        # Starts the UI if -u is provided
        index = sys.argv.index("-u")
        ui_ssh_port = int(sys.argv[index + 1])
        from src.ui.prompt_ui import start_ssh_server

        wait_for_ui, ui_close_cb = await start_ssh_server(
            store,
            blockchain,
            server,
            port,
            ui_ssh_port,
            full_node.config["ssh_filename"],
            master_close_cb,
        )

    connect_to_farmer = "-f" in sys.argv
    connect_to_timelord = "-t" in sys.argv

    full_node._start_bg_tasks()

    log.info("Waiting to connect to some peers...")
    await asyncio.sleep(3)
    log.info(
        f"Connected to {len(server.global_connections.get_connections())} peers."
    )

    if connect_to_farmer and not server_closed:
        peer_info = PeerInfo(
            full_node.config["farmer_peer"]["host"],
            full_node.config["farmer_peer"]["port"],
        )
        _ = await server.start_client(peer_info, None)

    if connect_to_timelord and not server_closed:
        peer_info = PeerInfo(
            full_node.config["timelord_peer"]["host"],
            full_node.config["timelord_peer"]["port"],
        )
        _ = await server.start_client(peer_info, None)

    # Awaits for server and all connections to close
    await server.await_closed()

    # Awaits for all ui instances to close
    if wait_for_ui is not None:
        await wait_for_ui()
    await asyncio.get_running_loop().shutdown_asyncgens()
Example #26
0
parser.add_argument(
    '-o',
    type=str,
    help=
    'output file without requiring an initial blockchain file to read from (default: \'blockchain.json\')'
)

args = parser.parse_args()
node_id = uuid()

if __name__ == '__main__':
    # Load Blockchain File
    filename = args.file
    if filename:
        data = json.load(open(filename))
        blockchain = Blockchain(data['chain'], data['tx_info'])
    else:
        filename = args.o
        blockchain = Blockchain()

    node = MinerNode(name=args.n or f'node-{node_id}',
                     port=args.p or 5000,
                     blockchain=blockchain)

    try:
        print(f'Starting node-{node_id}')

        # Establish Connection
        while not node.ready:
            node.send('version',
                      message=json.dumps(
Example #27
0
 def setUp(self):
     self.blockchain = Blockchain()
 def __init__(self):
     self.transactions = {}
     self.blockchain = Blockchain()
Example #29
0
from time import time
from uuid import uuid4
from flask import Flask, jsonify, request
from src.blockchain import Blockchain
try:
    from urllib.parse import urlparse
except ImportError:
    from urlparse import urlparse

# instantiate our node
app = Flask(__name__)
# generate a globally unique adress for this node
node_identifier = str(uuid4()).replace('-', '')
cprint('> this node key: {}'.format(node_identifier), 'cyan')
# instantiate the blockchain
blockchain = Blockchain()


# define routes
@app.route('/mine', methods=['GET'])
def mine():
    # 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 recieve a reward for finding the proof
    # the sender is "0" to signify that this node has mined a new coin
    blockchain.new_transaction(sender="Mined",
                               recipient=node_identifier,
                               amount=1)
    # forge the new block by adding it to the chain
Example #30
0
from fastapi import APIRouter

from src.blockchain import Blockchain
from src.model import NewBlock, Transaction

router = APIRouter()
bc = Blockchain()


@router.get("/last-block")
async def get_last_block():
    return bc.last_block


@router.post("/new-block")
async def new_block(block: NewBlock):
    return bc.new_block(block.proof, block.previous_hash)


@router.post("/transaction")
async def new_transaction(transaction: Transaction):
    return bc.new_transaction(transaction.sender, transaction.recipient,
                              transaction.amount)