示例#1
0
    def test_post_transaction(self):
        self.prepare_app()

        # prepare a valid transaction
        w = Wallet()
        w.create_keys()
        tx = Transaction("0", w.get_address(), 1)
        w.sign_transaction(tx)

        client = app.test_client()

        response = client.post("/block/new", data=tx.to_json())
        self.assertEqual(response.status_code, 201)

        b = Block.from_json(response.get_data())
        mine(b)
        response = client.post("/block", data=b.to_json())
        self.assertEqual(response.status_code, 201)

        tx = Transaction(w.get_address(), 1, 0.5)

        # test without signature
        response = client.post("/transaction", data=tx.to_json())
        self.assertEqual(response.status_code, 400)

        # test with signature
        w.sign_transaction(tx)
        response = client.post("/transaction", data=tx.to_json())
        self.assertEqual(response.status_code, 201)
示例#2
0
    def test_verify_foreign_transaction(self):
        w = Wallet()
        w.create_keys()
        t = Transaction(w.get_address(), 1, 1)
        w.sign_transaction(t)

        # Create different keypair
        w.create_keys()

        self.assertTrue(w.verify_transaction(t))
示例#3
0
    def test_use_pool(self):
        bc = BlockChain()
        w = Wallet()
        w.create_keys()

        # make some cash
        tx0 = Transaction("0", w.get_address(), 1)
        b = bc.new_block(tx0)
        mine(b)
        self.assertTrue(bc.discard_block(b))

        self.assertEqual(bc.get_wallet_balance(w.get_address()), 1)
        tx_count = 10
        for i in range(tx_count):
            t = Transaction(w.get_address(), 1, 1 / 100)
            w.sign_transaction(t)
            self.assertTrue(bc.add_transaction(t))
        self.assertEqual(len(bc.transaction_pool), tx_count)
        b = bc.new_block(self.tx)

        max_txs_in_block = 2**Tree.MAX_DEPTH
        self.assertEqual(len(list(b.get_transactions())),
                         min(max_txs_in_block, tx_count + 1))

        # Transactions in new block are removed from tx pool when new block is successfully discarded to chain
        b = bc.new_block(self.tx)  # coinbase tx
        mine(b)
        bc.discard_block(b)

        expected_txs_in_tx_pool = max(0, tx_count - (max_txs_in_block - 1))
        self.assertEqual(len(bc.transaction_pool), expected_txs_in_tx_pool)

        leftover_count = min(max_txs_in_block - 1, expected_txs_in_tx_pool)
        self.assertEqual(len(list(bc.new_block(self.tx).get_transactions())),
                         1 + leftover_count)
示例#4
0
 def load_wallets(self):
     """Load existing wallets from disk."""
     count = 0
     for path in glob("webwallet_*.wallet"):
         w = Wallet.load_keys(path)
         self.wallets[path] = w
         count += 1
     logging.debug(f"Successfully loaded {count} wallets from disk")
示例#5
0
    def generate_wallet_and_coinbase():
        w = Wallet()
        w.create_keys()
        tx = Transaction("0", w.get_address(), 1)  # coinbase
        w.sign_transaction(tx)

        return w, tx
示例#6
0
def do_wallet_show(args):
    """Display wallet information."""
    print("Showing wallet")
    w = Wallet.load_keys(args.wallet)

    addr = w.get_address()
    balance = args.api.get_balance(addr)
    print(f"Address: {addr}")
    print(f"Balance: {balance}")
示例#7
0
    def test_save_and_load_key(self):
        # Create a temporary directory
        self.test_dir = tempfile.mkdtemp()
        self.test_file = path.join(self.test_dir, "test.pem")

        t = Wallet()
        t.create_keys()
        t.save_key(self.test_file)
        t2 = Wallet.load_keys(self.test_file)

        self.assertIsNotNone(t.get_address())
        self.assertIsNotNone(t2.get_address())
        self.assertEqual(t2.get_address(), t.get_address())

        shutil.rmtree(self.test_dir)
示例#8
0
def do_mine(args):
    """Mine a block."""
    w = Wallet.load_keys(args.wallet)
    magic = args.api.get_magic()
    coinbase = transaction.Transaction("0", w.get_address(), 1, magic=magic)

    print("Mining block...")
    b = mine(coinbase, args.api)
    print("Pushing block...")
    args.api.push_block(b)
    print("Successfully mined block.")
示例#9
0
    def enrich_wallet_coinbase(cls):
        w = Wallet()
        w.create_keys()
        tx = Transaction("0", w.get_address(), 1)  # coinbase
        w.sign_transaction(tx)

        cls.w = w
        cls.tx = tx

        return w, tx
示例#10
0
def do_wallet_generate(args):
    """Generate a new wallet."""
    print("Generating new wallet...")
    w = Wallet()
    w.create_keys()
    w.save_key(args.filepath)
    print(f"New wallet successfully saved at {args.filepath}")
示例#11
0
    def test_sign_and_verify(self):
        t = Wallet()
        t.create_keys()
        sig = t.sign(bytes.fromhex("d8e8fca2dc0f896fd7cb4cb0031ba249"))
        res = t.verify(sig, bytes.fromhex("d8e8fca2dc0f896fd7cb4cb0031ba249"))

        self.assertTrue(res)
示例#12
0
def do_transaction(args):
    """Perform a transaction."""
    w = Wallet.load_keys(args.wallet)
    magic = args.api.get_magic()
    tx = transaction.Transaction(w.get_address(),
                                 args.destination,
                                 args.amount,
                                 magic=magic)
    w.sign_transaction(tx)

    if args.api.push_transaction(tx):
        print("Transaction successfully broadcasted.")
    else:
        print("[Error] Failed to broadcast transaction.")
示例#13
0
    def test_sign_transaction(self):
        w = Wallet()
        w.create_keys()

        t = Transaction(w.get_address(), 1, 1)
        th = t.get_hash()

        self.assertIsNone(t.signature)

        self.assertTrue(w.sign_transaction(t))

        self.assertIsNotNone(t.signature)
        self.assertEqual(t.get_hash(), th)

        self.assertTrue(w.verify_transaction(t))
示例#14
0
    def test_post_new_block(self):
        self.prepare_app()

        # prepare a valid transaction
        w = Wallet()
        w.create_keys()
        tx = Transaction(0, w.get_address(), 1)
        w.sign_transaction(tx)

        client = app.test_client()

        response = client.post("/block/new", data=tx.to_json())
        self.assertEqual(response.status_code, 201)

        b = Block.from_json(response.get_data())
        self.assertTrue(type(b) == Block)
示例#15
0
    def test_add_transactions(self):
        tp = TransactionPool()
        w = Wallet()
        w.create_keys()

        t = Transaction(w.get_address(), 1, 1)
        # Transaction is not signed
        self.assertFalse(tp.add_transaction(t))

        w.sign_transaction(t)
        self.assertTrue(tp.add_transaction(t))

        # Canot add the same transaciton multiple times
        self.assertFalse(tp.add_transaction(t))

        self.assertEqual(len(tp), 1)

        t2 = tp.pull_transaction()
        self.assertEqual(t.get_hash(), t2.get_hash())
示例#16
0
    def create_wallet(self, label):
        """
        Create Wallet associated with user
        :param label: name to identify this wallet
        :return: generated wallet
        """
        wallet = Wallet(label=label)
        wallet.save()

        wallet.owner.connect(self)

        self.wallets.connect(wallet)
        self.save()
        wallet.save()

        return wallet
示例#17
0
    def generate_wallet(self):
        """Generate a new wallet."""
        w = Wallet()
        w.create_keys()
        first_free_count = 1
        while True:
            path = f"webwallet_{first_free_count}.wallet"
            if not os.path.exists(path):
                break
            first_free_count += 1

        # save wallet to disk
        w.save_key(path)

        # save wallet to memory
        self.wallets[path] = w
示例#18
0
    def test_secure_wallet_balance(self):
        bc = BlockChain()

        w1 = Wallet()
        w1.create_keys()
        addr1 = w1.get_address()

        tx0 = Transaction("0", addr1, 1)
        b = bc.new_block(tx0)
        mine(b)
        bc.discard_block(b)

        balance = bc.get_secure_wallet_balance(addr1)
        self.assertEqual(balance, None)

        tx1 = Transaction(addr1, "toto", 1)
        w1.sign_transaction(tx1)

        cbtx = WalletHelper.generate_coinbase_with_unused_wallet()
        b1 = bc.new_block(cbtx)
        b1.add_transaction(tx1)
        mine(b1)
        bc.discard_block(b1)

        self.assertEqual(bc.get_secure_wallet_balance("toto"), None)

        for i in range(5):
            tx0 = Transaction("0", addr1, 1)
            b = bc.new_block(tx0)
            mine(b)
            bc.discard_block(b)

        # only 5 confirmations so far, tx is not there yet for secure balance
        self.assertEqual(bc.get_secure_wallet_balance("toto"), None)

        cbtx = WalletHelper.generate_coinbase_with_unused_wallet()
        b6 = bc.new_block(cbtx)
        mine(b6)
        bc.discard_block(b6)

        # tx appears after 6 confirmations only
        self.assertEqual(bc.get_secure_wallet_balance("toto"), 1)
示例#19
0
    def test_import_transactions(self):
        b = Block(0, 0)
        w = Wallet()
        w.create_keys()
        t = Transaction(w.get_address(), 1, 1)
        w.sign_transaction(t)
        b.add_transaction(t)

        tp = TransactionPool()
        self.assertTrue(tp.import_transactions(b))
        self.assertEqual(len(tp), 1)

        t2 = tp.pull_transaction()
        self.assertEqual(t.get_hash(), t2.get_hash())

        # Importing unsigned transactions returns False
        tp = TransactionPool()
        t2 = Transaction(0, 1, 1)
        b.add_transaction(t2)
        self.assertFalse(tp.import_transactions(b))
示例#20
0
    def test_transaction_serialize(self):
        t1 = Transaction(0, 1, 2)
        t2 = Transaction(0, 1, 2)

        self.assertNotEqual(t1.get_hash(), t2.get_hash())

        t3 = Transaction.from_json(t1.to_json())
        self.assertEqual(t1.get_hash(), t3.get_hash())
        self.assertEqual(t1.src, t3.src)
        self.assertEqual(t1.dst, t3.dst)
        self.assertEqual(t1.qty, t3.qty)

        w = Wallet()
        w.create_keys()
        w.sign_transaction(t1)
        t4 = Transaction.from_json(t1.to_json())
        self.assertEqual(t1.get_hash(), t4.get_hash())
示例#21
0
def genkey():
    w = Wallet()
    w.create_keys()
    pkey = w.get_private_key()
    output = pkey.decode("utf-8")
    return output
示例#22
0
def pubkey():
    sin = sys.stdin.read().encode("utf-8")
    w = Wallet.load_keys_from_bytes(sin)
    pkey = w.get_address()
    return pkey
示例#23
0
    def test_wallet_balance(self):
        bc = BlockChain()

        w1 = Wallet()
        w1.create_keys()
        addr1 = w1.get_address()

        w2 = Wallet()
        w2.create_keys()
        addr2 = w2.get_address()

        w3 = Wallet()
        w3.create_keys()
        addr3 = w3.get_address()

        tx0 = Transaction("0", addr1, 1)
        b = bc.new_block(tx0)
        mine(b)
        bc.discard_block(b)

        balance = bc.get_wallet_balance(addr1)
        self.assertEqual(balance, 1)

        tx1 = Transaction(addr1, addr2, 0.1)
        tx2 = Transaction(addr1, addr3, 0.2)
        tx3 = Transaction(addr2, addr3, 133)

        w1.sign_transaction(tx1)
        w1.sign_transaction(tx2)
        w2.sign_transaction(tx3)

        self.assertTrue(bc.add_transaction(tx1))
        self.assertTrue(bc.add_transaction(tx2))
        self.assertFalse(bc.add_transaction(tx3))

        tx4 = Transaction(addr1, addr2, 1)
        w1.sign_transaction(tx4)
        self.assertFalse(bc.add_transaction(tx4))

        balance = bc.get_wallet_balance(addr1)
        self.assertEqual(balance, 0.7)

        balance = bc.get_wallet_balance(addr2)
        self.assertEqual(balance, 0.1)

        balance = bc.get_wallet_balance(addr3)
        self.assertEqual(balance, 0.2)

        w4 = Wallet()
        w4.create_keys()
        addr4 = w4.get_address()

        cbtx4 = Transaction("0", addr4, 1)
        b4 = bc.new_block(cbtx4)
        mine(b4)
        bc.discard_block(b4)
        self.assertTrue(bc.get_wallet_balance(addr4), 1)

        ntx4 = Transaction(addr4, "toto", 1, magic=bc.magic)
        w4.sign_transaction(ntx4)
        self.assertTrue(bc.add_transaction(ntx4))
        coinbase4 = Transaction("0", addr4, 1)
        nb4 = bc.new_block(
            coinbase4
        )  # new block nb4 is filled with coinbase4 and ntx4 (fill_block() was called)
        mine(nb4)  # mine block before adding to chain
        logger.debug("DISCARDING...")
        discarded = bc.discard_block(nb4)
        logger.debug("END DISCARD")
        self.assertTrue(discarded)