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)
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))
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)
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")
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
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}")
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)
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.")
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
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}")
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)
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.")
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))
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)
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())
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
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
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)
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))
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())
def genkey(): w = Wallet() w.create_keys() pkey = w.get_private_key() output = pkey.decode("utf-8") return output
def pubkey(): sin = sys.stdin.read().encode("utf-8") w = Wallet.load_keys_from_bytes(sin) pkey = w.get_address() return pkey
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)