def test_serialize_txgroup(self): address = "7ZUECA7HFLZTXENRV24SHLU4AVPUTMTTDUFUBNBD64C73F3UHRTHAIOF6Q" gh = "JgsgCaCTqIaLeVhyL6XlRu3n7Rfk2FxMeK+wRSaQ7dI=" txn = transaction.PaymentTxn(address, 3, 1, 100, gh, address, 1000, gen="testnet-v1.0", close_remainder_to=address) txid = txn.get_txid().encode() txid = base64.decodebytes(txid) txgroup = transaction.TxGroup([txid]) enc = encoding.msgpack_encode(txgroup) re_enc = encoding.msgpack_encode(encoding.msgpack_decode(enc)) self.assertEqual(enc, re_enc) txgroup = transaction.TxGroup([txid] * 11) enc = encoding.msgpack_encode(txgroup) re_enc = encoding.msgpack_encode(encoding.msgpack_decode(enc)) self.assertEqual(enc, re_enc) # check group field serialization gid = transaction.calculate_group_id([txn, txn]) txn.group = gid enc = encoding.msgpack_encode(txn) re_enc = encoding.msgpack_encode(encoding.msgpack_decode(enc)) self.assertEqual(enc, re_enc)
def sendTransaction(privateKey_def, addr_def, addr_acl_1, addr_acl_2, addr_acl_3, amount): # Create two seperate transactions trxn_1 = create_transaction(privateKey_def, addr_def, addr_acl_1, amount) trxn_2 = create_transaction(privateKey_def, addr_def, addr_acl_2, amount) trxn_3 = create_transaction(privateKey_def, addr_def, addr_acl_3, amount) # Make transactions into group gid = transaction.calculate_group_id([trxn_1, trxn_2, trxn_3]) trxn_1.group = gid trxn_2.group = gid trxn_3.group = gid # sign the transaction signTrxn_1 = trxn_1.sign(privateKey_def) signTrxn_2 = trxn_2.sign(privateKey_def) signTrxn_3 = trxn_3.sign(privateKey_def) # trxn_id = signTrxn.transaction.get_txid() try: return ("Transactions were signed with: ", algodClient.send_transactions( [signTrxn_1, signTrxn_2, signTrxn_3], headers={'content-type': 'application/x-binary'})) except Exception as e: print(e) # gn="testnet-v1.0" # genhash="SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI="
def sc_opt_in(self,sc_addr,sc_lsig,asset_id): txn = self.sc_opt_in_asset(sc_addr,asset_id) gid = transaction.calculate_group_id([txn]) txn.group = gid lstx = LogicSigTransaction(txn, sc_lsig) signedGroup = [] signedGroup.append(lstx) tx_id = self.algod_client.send_transactions(signedGroup) self.wait_for_confirmation(tx_id)
def group_transactions() : # recover a account passphrase1 = <25-word-passphrase> pk_account_a = mnemonic.to_private_key(passphrase1) account_a = account.address_from_private_key(pk_account_a) # recover b account passphrase2 = <25-word-passphrase> pk_account_b = mnemonic.to_private_key(passphrase2) account_b = account.address_from_private_key(pk_account_b) # recover c account passphrase3 = <25-word-passphrase> pk_account_c = mnemonic.to_private_key(passphrase3) account_c = account.address_from_private_key(pk_account_c) # connect to node acl = connect_to_network() # get suggested parameters params = acl.suggested_params() gen = params["genesisID"] gh = params["genesishashb64"] last_round = params["lastRound"] fee = params["fee"] amount = 1000 # create transaction1 txn1 = transaction.PaymentTxn(account_a, fee, last_round, last_round+100, gh, account_c, amount) # create transaction2 txn2 = transaction.PaymentTxn(account_b, fee, last_round, last_round+100, gh, account_a, amount) # get group id and assign it to transactions gid = transaction.calculate_group_id([txn1, txn2]) txn1.group = gid txn2.group = gid # sign transaction1 stxn1 = txn1.sign(pk_account_a) # sign transaction2 stxn2 = txn2.sign(pk_account_b) signedGroup = [] signedGroup.append(stxn1) signedGroup.append(stxn2) # send them over network sent = acl.send_transactions(signedGroup) # print txid print(sent) # wait for confirmation wait_for_confirmation( acl, sent)
def group_transactions(): # recover a account passphrase1 = os.getenv("MNEMONIC1") pk_account_a = mnemonic.to_private_key(passphrase1) account_a = account.address_from_private_key(pk_account_a) # recover b account account_b = "4O6BRAPVLX5ID23AZWV33TICD35TI6JWOHXVLPGO4VRJATO6MZZQRKC7RI" # connect to node acl = connect_to_network() # get suggested parameters params = acl.suggested_params() gen = params["genesisID"] gh = params["genesishashb64"] last_round = params["lastRound"] fee = params["fee"] asset_index = 14035004 # create transaction1 txn1 = transaction.PaymentTxn(account_a, fee, last_round, last_round + 100, gh, account_b, 42000000) # create transaction2 txn2 = transaction.AssetTransferTxn(account_b, fee, last_round, last_round + 100, gh, account_a, 1, asset_index) # get group id and assign it to transactions gid = transaction.calculate_group_id([txn1, txn2]) txn1.group = gid txn2.group = gid # sign transaction1 stxn1 = txn1.sign(pk_account_a) # sign transaction2 with open("buildweb3/step5.lsig", "rb") as f: lsig = encoding.future_msgpack_decode(base64.b64encode(f.read())) stxn2 = transaction.LogicSigTransaction(txn2, lsig) signedGroup = [] signedGroup.append(stxn1) signedGroup.append(stxn2) # send them over network sent = acl.send_transactions(signedGroup) # print txid print(sent) # wait for confirmation wait_for_confirmation(acl, sent)
def test_transaction_group(self): # get the default wallet wallets = self.kcl.list_wallets() wallet_id = None for w in wallets: if w["name"] == wallet_name: wallet_id = w["id"] # get a new handle for the wallet handle = self.kcl.init_wallet_handle(wallet_id, wallet_pswd) # get private key private_key_0 = self.kcl.export_key(handle, wallet_pswd, self.account_0) # get suggested parameters and fee params = self.acl.suggested_params() gen = params["genesisID"] gh = params["genesishashb64"] last_round = params["lastRound"] fee = params["fee"] # create transaction txn = transaction.PaymentTxn(self.account_0, fee, last_round, last_round + 100, gh, self.account_0, 1000, gen=gen) # calculate group id gid = transaction.calculate_group_id([txn]) txn.group = gid # sign using kmd stxn1 = self.kcl.sign_transaction(handle, wallet_pswd, txn) # sign using transaction call stxn2 = txn.sign(private_key_0) # check that they are the same self.assertEqual(encoding.msgpack_encode(stxn1), encoding.msgpack_encode(stxn2)) try: send = self.acl.send_transactions([stxn1]) self.assertEqual(send, txn.get_txid()) except error.AlgodHTTPError as ex: self.assertIn( "TransactionPool.Remember: transaction groups not supported", str(ex))
def bet_atomic_transfer(algod_client, dealer, addr_opponent, addr_dealer_bet_escrow, addr_opponent_bet_escrow, microalgo_bet_amount): """HELP bet_atomic_transfer: (AlgodClient, dict, str, str, str, int) - Returns Bet Atomic Transfer partially signed by the Dealer, to be signed by the Opponent. """ dealer_bet_txn = unsigned_send(algod_client, dealer['pk'], addr_dealer_bet_escrow, microalgo_bet_amount) opponent_bet_txn = unsigned_send(algod_client, addr_opponent, addr_opponent_bet_escrow, microalgo_bet_amount) # Gorup Transaction gid = transaction.calculate_group_id([dealer_bet_txn, opponent_bet_txn]) dealer_bet_txn.group = gid opponent_bet_txn.group = gid dealer_bet_stxn = dealer_bet_txn.sign(dealer['sk']) return dealer_bet_stxn, opponent_bet_txn
def complete_trade(update, context): """ To complete the atomic transaction, Buyer signs and submit half-signed transaction. :param update: Telegram obj. :param context: Telegram obj. :param context: Authorization key from the buyer. :return: """ sk = context.user_data['Authorization_key'] _address = account.address_from_private_key(sk) sk_bytes = rf(update, context, _address) bt = base64.decodebytes(sk_bytes) s = bt.decode() key = _address[:10] seller = TRANSACTIONS["{}".format(key)]['Seller'] update.message.reply_text("Completing trade...\nbetween:\nSeller - {} and Buyer - {}".format(seller, _address)) file = _address[:11] if _address in ex_file and _address == TRANSACTIONS["{}".format(key)]['Buyer']: rtv = transaction.retrieve_from_file("./asa{}.txn".format(file)) grid = transaction.calculate_group_id([rtv[0], rtv[1], rtv[2], rtv[3]]) rtv[0].group = grid rtv[1].group = grid rtv[2].group = grid rtv[3].group = grid txn1 = rtv[0].sign(sk) txn2 = rtv[1].sign(sk) txn3 = rtv[2].sign(s) txn4 = rtv[3].sign(s) tx_id = client.send_transactions([txn1, txn2, txn3, txn4]) wait_for_confirmation(update, context, client, tx_id) else: update.message.reply_text("Trade could not be completed!") context.user_data.clear() remove_data(update, context, _address) return ConversationHandler.conversation_timeout
def play_last_turn(algod_client, player, addr_adversary, addr_game_table, game_table_lsig, addr_sink, sink_lsig, addr_adversary_bet_escrow, adversary_bet_escrow_lsig, asa_turn_id, asa_pieces_id, asa_pieces_amount, asa_pieces_total): """HELP play_last_turn: (AlgodClient, dict, str, str, str, str, str, str, str, int, int, int, int) - Play last turn moving ASA Pieces form the Game Table to the Sink and show the winning proof to the opponent's Bet Escrow. """ txn0 = unsigned_asset_send(algod_client, player['pk'], addr_adversary, asa_turn_id, 1) txn1 = unsigned_asset_send(algod_client, addr_game_table, addr_sink, asa_pieces_id, asa_pieces_amount) txn2 = unsigned_asset_send(algod_client, addr_sink, player['pk'], asa_pieces_id, asa_pieces_total) txn3 = unsigned_closeto(algod_client, addr_adversary_bet_escrow, player['pk']) # Gorup Transaction gid = transaction.calculate_group_id([txn0, txn1, txn2, txn3]) txn0.group = gid txn1.group = gid txn2.group = gid txn3.group = gid stxn0 = txn0.sign(player['sk']) lstxn1 = transaction.LogicSigTransaction(txn1, game_table_lsig) lstxn2 = transaction.LogicSigTransaction(txn2, sink_lsig) lstxn3 = transaction.LogicSigTransaction(txn3, adversary_bet_escrow_lsig) sgtxn = [stxn0, lstxn1, lstxn2, lstxn3] txid = algod_client.send_transactions(sgtxn) print("\nI WON !!! Arrivederci " + addr_adversary) print("Transaction ID: ", txid) wait_for_tx_confirmation(algod_client, txid)
def test_sign(self): mn = ("advice pudding treat near rule blouse same whisper inner " + "electric quit surface sunny dismiss leader blood seat " + "clown cost exist hospital century reform able sponsor") gh = "JgsgCaCTqIaLeVhyL6XlRu3n7Rfk2FxMeK+wRSaQ7dI=" address = "PNWOET7LLOWMBMLE4KOCELCX6X3D3Q4H2Q4QJASYIEOF7YIPPQBG3YQ5YI" close = "IDUTJEUIEVSMXTU4LGTJWZ2UE2E6TIODUKU6UW3FU3UKIQQ77RLUBBBFLA" sk = mnemonic.to_private_key(mn) pk = account.address_from_private_key(sk) txn = transaction.PaymentTxn(pk, 4, 12466, 13466, gh, address, 1000, note=base64.b64decode("6gAVR0Nsv5Y="), gen="devnet-v33.0", close_remainder_to=close) stx = txn.sign(sk) golden = ("gqNzaWfEQPhUAZ3xkDDcc8FvOVo6UinzmKBCqs0woYSfodlmBMfQvGbeU" + "x3Srxy3dyJDzv7rLm26BRv9FnL2/AuT7NYfiAWjdHhui6NhbXTNA+ilY2" + "xvc2XEIEDpNJKIJWTLzpxZpptnVCaJ6aHDoqnqW2Wm6KRCH/xXo2ZlZc0" + "EmKJmds0wsqNnZW6sZGV2bmV0LXYzMy4womdoxCAmCyAJoJOohot5WHIv" + "peVG7eftF+TYXEx4r7BFJpDt0qJsds00mqRub3RlxAjqABVHQ2y/lqNyY" + "3bEIHts4k/rW6zAsWTinCIsV/X2PcOH1DkEglhBHF/hD3wCo3NuZMQg5/" + "D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKGkdHlwZaNwYXk=") self.assertEqual(golden, encoding.msgpack_encode(stx)) txid_golden = "5FJDJD5LMZC3EHUYYJNH5I23U4X6H2KXABNDGPIL557ZMJ33GZHQ" self.assertEqual(txn.get_txid(), txid_golden) # check group field serialization gid = transaction.calculate_group_id([txn]) stx.group = gid enc = encoding.msgpack_encode(stx) re_enc = encoding.msgpack_encode(encoding.msgpack_decode(enc)) self.assertEqual(enc, re_enc)
def play_turn(algod_client, player, addr_adversary, addr_game_table, game_table_lsig, addr_sink, sink_lsig, addr_adversary_bet_escrow, adversary_bet_escrow_lsig, asa_turn_id, asa_pieces_id, asa_pieces_max_remove, asa_pieces_amount, asa_pieces_total): """HELP play_turn: (AlgodClient, dict, str, str, str, str, str, str, str, int, int, int, int) - Play turn moving ASA Pieces form the Game Table to the Sink. """ game_table_info = algod_client.account_info(addr_game_table) pieces_on_table = next((asa['amount'] for asa in game_table_info['assets'] if asa['asset-id'] == asa_pieces_id), None) if pieces_on_table > asa_pieces_max_remove: txn0 = unsigned_asset_send(algod_client, player['pk'], addr_adversary, asa_turn_id, 1) txn1 = unsigned_asset_send(algod_client, addr_game_table, addr_sink, asa_pieces_id, asa_pieces_amount) # Gorup Transaction gid = transaction.calculate_group_id([txn0, txn1]) txn0.group = gid txn1.group = gid stxn0 = txn0.sign(player['sk']) lstxn1 = transaction.LogicSigTransaction(txn1, game_table_lsig) sgtxn = [stxn0, lstxn1] txid = algod_client.send_transactions(sgtxn) print("\nRemoving", asa_pieces_amount, "pieces from the Game Table...") print("Transaction ID: ", txid) wait_for_tx_confirmation(algod_client, txid) else: play_last_turn(algod_client, player, addr_adversary, addr_game_table, game_table_lsig, addr_sink, sink_lsig, addr_adversary_bet_escrow, adversary_bet_escrow_lsig, asa_turn_id, asa_pieces_id, asa_pieces_amount, asa_pieces_total)
def match_setup(algod_client, dealer_passphrase, addr_opponent, match_hours_timeout, microalgo_bet_amount, asa_pieces_total, asa_pieces_max_remove): """HELP match_setup: (AlgodClient, str, str, float, int, int, int) - Sets up a new AlgoNim match. """ # AlgoNim Players # Palyer 1 (Dealer) - Match Set Up costs about: 0.8 ALGO dealer = { 'pk': mnemonic.to_public_key(dealer_passphrase), 'sk': mnemonic.to_private_key(dealer_passphrase) } # Player 2 (Opponent) - Must Opt-In AlgoNim ASAs to play the match opponent = {'pk': addr_opponent} print(" ") print(" _ __ ____ _____ _ ") print(" / \ [ | |_ \|_ _| (_) ") print(" / _ \ | | .--./) .--. | \ | | __ _ .--..--. ") print(" / ___ \ | | / /'`\;/ .'`\ \ | |\ \| | [ | [ `.-. .-. | ") print(" _/ / \ \_ | | \ \._//| \__. |_| |_\ |_ | | | | | | | | ") print("|____| |____|[___].',__` '.__.'|_____|\____|[___][___||__||__]") print(" ( ( __)) ") print(" by cusma") print(" ") print(" Welcome to AlgoNim, the first crypto-mini-game on Algorand! ") # Asset Create: AlgoNim ASA Pieces print("") print("Dealer creating AlgoNim ASA Piece for this match...") asa_pieces_id = asa_pieces_create(algod_client, dealer, asa_pieces_total) # Asset Create: AlgoNim ASA Turn print("") print("Dealer creating AlgoNim ASA Turn for this match...") asa_turn_id = asa_turn_create(algod_client, dealer) # TEAL: AlgoNim ASC1 Sink print("") print("Dealer writing AlgoNim ASC1 Sink TEAL for this match...") asc1_sink_source = asc1_sink_teal(asa_pieces_total, asa_pieces_id, dealer['pk'], opponent['pk']) asc1_sink_compiled = algod_client.compile(asc1_sink_source) sink_lsig = transaction.LogicSig( base64.decodebytes(asc1_sink_compiled['result'].encode())) addr_sink = asc1_sink_compiled['hash'] # Initialize AlgoNim ASC1 Sink Account with ALGO print("") print("Initializing Sink Account...") send(algod_client, dealer, addr_sink, 300000) # AlgoNim ASC1 Sink Account Opt-In print("") print("Sink Account AlgoNim ASA Piece Opt-In...") sink_opt_in_txn = unsigned_asset_send(algod_client, addr_sink, addr_sink, asa_pieces_id, 0) sink_opt_in_lstxn = transaction.LogicSigTransaction( sink_opt_in_txn, sink_lsig) txid = algod_client.send_transactions([sink_opt_in_lstxn]) print("Transaction ID:", txid) wait_for_tx_confirmation(algod_client, txid) # TEAL: AlgoNim ASC1 Game Table print("") print("Dealer writing AlgoNim ASC1 Game Table TEAL for this match...") asc1_game_table_source = asc1_game_table_teal(asa_pieces_total, asa_pieces_id, asa_pieces_max_remove, asa_turn_id, dealer['pk'], opponent['pk'], addr_sink) asc1_game_table_compiled = algod_client.compile(asc1_game_table_source) game_table_lsig = transaction.LogicSig( base64.decodebytes(asc1_game_table_compiled['result'].encode())) addr_game_table = asc1_game_table_compiled['hash'] # Initialize AlgoNim ASC1 Game Table Account with ALGO print("") print("Initializing Game Table Account...") send(algod_client, dealer, addr_game_table, 300000) # Dealer Sets Up the Game Table with AlgoNim ASA Pieces print("") print("Dealer distributing ASA Pieces on the Game Table...") gt_opt_in_txn = unsigned_asset_send(algod_client, addr_game_table, addr_game_table, asa_pieces_id, 0) deal_pieces_txn = unsigned_asset_send(algod_client, dealer['pk'], addr_game_table, asa_pieces_id, asa_pieces_total) # Dealer Gorup Transaction dealer_gid = transaction.calculate_group_id( [gt_opt_in_txn, deal_pieces_txn]) gt_opt_in_txn.group = dealer_gid deal_pieces_txn.group = dealer_gid gt_opt_in_lstxn = transaction.LogicSigTransaction(gt_opt_in_txn, game_table_lsig) deal_pieces_stxn = deal_pieces_txn.sign(dealer['sk']) dealer_sgtxn = [gt_opt_in_lstxn, deal_pieces_stxn] txid = algod_client.send_transactions(dealer_sgtxn) print("Transaction ID: ", txid) wait_for_tx_confirmation(algod_client, txid) # TEAL: AlgoNim ASC1 Bet Escrow print("") print("Dealer writing AlgoNim ASC1 Bet Escrow TEAL for Palyer 1...") asc1_dealer_bet_escrow_source, dealer_bet_escrow_expiry_block = asc1_bet_escrow_teal( algod_client, asa_pieces_total, asa_pieces_id, asa_turn_id, dealer['pk'], opponent['pk'], addr_sink, addr_game_table, match_hours_timeout) asc1_dealer_bet_escrow_compiled = algod_client.compile( asc1_dealer_bet_escrow_source) dealer_bet_escrow_lsig = transaction.LogicSig( base64.decodebytes(asc1_dealer_bet_escrow_compiled['result'].encode())) addr_dealer_bet_escrow = asc1_dealer_bet_escrow_compiled['hash'] print("") print("Dealer writing AlgoNim ASC1 Bet Escrow TEAL for Palyer 2...") asc1_opponent_bet_escrow_source, opponent_bet_escrow_expiry_block = asc1_bet_escrow_teal( algod_client, asa_pieces_total, asa_pieces_id, asa_turn_id, opponent['pk'], dealer['pk'], addr_sink, addr_game_table, match_hours_timeout) asc1_opponent_bet_escrow_compiled = algod_client.compile( asc1_opponent_bet_escrow_source) opponent_bet_escrow_lsig = transaction.LogicSig( base64.decodebytes( asc1_opponent_bet_escrow_compiled['result'].encode())) addr_opponent_bet_escrow = asc1_opponent_bet_escrow_compiled['hash'] # Initialize AlgoNim ASC1 Escrows with 0.1 ALGO print("") print("Initializing Bet Escrow Accounts...") send(algod_client, dealer, addr_dealer_bet_escrow, 100000) print("") send(algod_client, dealer, addr_opponent_bet_escrow, 100000) # Creating Bet Atomic Transfer to be signed by the Opponent dealer_bet_stxn, opponent_bet_txn = bet_atomic_transfer( algod_client, dealer, opponent['pk'], addr_dealer_bet_escrow, addr_opponent_bet_escrow, microalgo_bet_amount) match_data = {} match_data['dealer'] = dealer['pk'] match_data['opponent'] = opponent['pk'] match_data['asa_pieces_id'] = asa_pieces_id match_data['asa_pieces_max_remove'] = asa_pieces_max_remove match_data['asa_turn_id'] = asa_turn_id match_data['sink'] = addr_sink match_data['sink_lsig'] = encoding.msgpack_encode(sink_lsig) match_data['game_table'] = addr_game_table match_data['game_table_lsig'] = encoding.msgpack_encode(game_table_lsig) match_data['dealer_bet_escrow'] = addr_dealer_bet_escrow match_data['dealer_bet_escrow_lsig'] = encoding.msgpack_encode( dealer_bet_escrow_lsig) match_data['opponent_bet_escrow'] = addr_opponent_bet_escrow match_data['opponent_bet_escrow_lsig'] = encoding.msgpack_encode( opponent_bet_escrow_lsig) match_data['dealer_bet_stxn'] = encoding.msgpack_encode(dealer_bet_stxn) match_data['opponent_bet_txn'] = encoding.msgpack_encode(opponent_bet_txn) match_data['microalgo_bet_amount'] = microalgo_bet_amount match_data['match_hours_timeout'] = match_hours_timeout match_data['dealer_bet_escrow_expiry'] = dealer_bet_escrow_expiry_block match_data['opponent_bet_escrow_expiry'] = opponent_bet_escrow_expiry_block match_data_bytes = msgpack.packb(match_data) match_data_fname = 'algonim.match' with open(match_data_fname, "wb") as f: f.write(match_data_bytes) f.close() print(" ") print(" _ _ ") print(" /\/\ __ _| |_ ___| |__ _ ") print(" / \ / _` | __/ __| '_ \ (_)") print("/ /\/\ \ (_| | || (__| | | | _ ") print("\/ \/\__,_|\__\___|_| |_| (_)") print(" ") print("MATCH DURATION:\t\t", match_data['match_hours_timeout'] * 60, "min") print("PIECES ON GAME TABLE:\t", asa_pieces_total, "\n") print("RULES:") print("1. Players on each turn must remove at least 1 ASA Piece") print("2. Players on each turn must remove at most", match_data['asa_pieces_max_remove'], "ASA Piece") print("3. Who removes the last ASA Piece form the Game Table wins the " + "match!\n") print("Player 1 - Dealer:\t" + match_data['dealer']) print("Player 2 - Opponent:\t" + match_data['opponent'], "\n") print("AlgoNim ASA Pieces ID:\t", match_data['asa_pieces_id']) print("AlgoNim ASA Turn ID:\t", match_data['asa_turn_id'], "\n") print("AlgoNim Sink Account:\t\t\t" + match_data['sink']) print("AlgoNim Game Table Account:\t\t" + match_data['game_table']) print("AlgoNim Bet Escrow Player 1 Account:\t" + match_data['dealer_bet_escrow']) print("AlgoNim Bet Escrow Player 2 Account:\t" + match_data['opponent_bet_escrow']) print("\nSend 'algonim.match' file to your opponent join the match!\n") print("May the best win!\n")
def test_group_id(self): address = "UPYAFLHSIPMJOHVXU2MPLQ46GXJKSDCEMZ6RLCQ7GWB5PRDKJUWKKXECXI" fromAddress, toAddress = address, address fee = 1000 amount = 2000 genesisID = "devnet-v1.0" genesisHash = "sC3P7e2SdbqKJK0tbiCdK9tdSpbe6XeCGKdoNzmlj0E=" firstRound1 = 710399 note1 = base64.b64decode("wRKw5cJ0CMo=") tx1 = transaction.PaymentTxn(fromAddress, fee, firstRound1, firstRound1 + 1000, genesisHash, toAddress, amount, note=note1, gen=genesisID, flat_fee=True) firstRound2 = 710515 note2 = base64.b64decode("dBlHI6BdrIg=") tx2 = transaction.PaymentTxn(fromAddress, fee, firstRound2, firstRound2 + 1000, genesisHash, toAddress, amount, note=note2, gen=genesisID, flat_fee=True) # goal clerk send dumps unsigned transaction as signed with empty signature in order to save tx type stx1 = transaction.SignedTransaction(tx1, None) stx2 = transaction.SignedTransaction(tx2, None) goldenTx1 = ( "gaN0eG6Ko2FtdM0H0KNmZWXNA+iiZnbOAArW/6NnZW6rZGV2bmV0LXYxLjCiZ2j" + "EILAtz+3tknW6iiStLW4gnSvbXUqW3ul3ghinaDc5pY9Bomx2zgAK2uekbm90Zc" + "QIwRKw5cJ0CMqjcmN2xCCj8AKs8kPYlx63ppj1w5410qkMRGZ9FYofNYPXxGpNL" + "KNzbmTEIKPwAqzyQ9iXHremmPXDnjXSqQxEZn0Vih81g9fEak0spHR5cGWjcGF5") goldenTx2 = ( "gaN0eG6Ko2FtdM0H0KNmZWXNA+iiZnbOAArXc6NnZW6rZGV2bmV0LXYxLjCiZ2j" + "EILAtz+3tknW6iiStLW4gnSvbXUqW3ul3ghinaDc5pY9Bomx2zgAK21ukbm90Zc" + "QIdBlHI6BdrIijcmN2xCCj8AKs8kPYlx63ppj1w5410qkMRGZ9FYofNYPXxGpNL" "KNzbmTEIKPwAqzyQ9iXHremmPXDnjXSqQxEZn0Vih81g9fEak0spHR5cGWjcGF5") self.assertEqual(goldenTx1, encoding.msgpack_encode(stx1)) self.assertEqual(goldenTx2, encoding.msgpack_encode(stx2)) # preserve original tx{1,2} objects tx1 = copy.deepcopy(tx1) tx2 = copy.deepcopy(tx2) gid = transaction.calculate_group_id([tx1, tx2]) stx1.transaction.group = gid stx2.transaction.group = gid # goal clerk group sets Group to every transaction and concatenate them in output file # simulating that behavior here txg = base64.b64encode( base64.b64decode(encoding.msgpack_encode(stx1)) + base64.b64decode(encoding.msgpack_encode(stx2))).decode() goldenTxg = ( "gaN0eG6Lo2FtdM0H0KNmZWXNA+iiZnbOAArW/6NnZW6rZGV2bmV0LXYxLjCiZ2j" + "EILAtz+3tknW6iiStLW4gnSvbXUqW3ul3ghinaDc5pY9Bo2dycMQgLiQ9OBup9H" + "/bZLSfQUH2S6iHUM6FQ3PLuv9FNKyt09SibHbOAAra56Rub3RlxAjBErDlwnQIy" + "qNyY3bEIKPwAqzyQ9iXHremmPXDnjXSqQxEZn0Vih81g9fEak0so3NuZMQgo/AC" + "rPJD2Jcet6aY9cOeNdKpDERmfRWKHzWD18RqTSykdHlwZaNwYXmBo3R4boujYW1" + "0zQfQo2ZlZc0D6KJmds4ACtdzo2dlbqtkZXZuZXQtdjEuMKJnaMQgsC3P7e2Sdb" + "qKJK0tbiCdK9tdSpbe6XeCGKdoNzmlj0GjZ3JwxCAuJD04G6n0f9tktJ9BQfZLq" + "IdQzoVDc8u6/0U0rK3T1KJsds4ACttbpG5vdGXECHQZRyOgXayIo3JjdsQgo/AC" + "rPJD2Jcet6aY9cOeNdKpDERmfRWKHzWD18RqTSyjc25kxCCj8AKs8kPYlx63ppj" + "1w5410qkMRGZ9FYofNYPXxGpNLKR0eXBlo3BheQ==") self.assertEqual(goldenTxg, txg) # repeat test above for assign_group_id txa1 = copy.deepcopy(tx1) txa2 = copy.deepcopy(tx2) txns = transaction.assign_group_id([txa1, txa2]) self.assertEqual(len(txns), 2) stx1 = transaction.SignedTransaction(txns[0], None) stx2 = transaction.SignedTransaction(txns[1], None) # goal clerk group sets Group to every transaction and concatenate them in output file # simulating that behavior here txg = base64.b64encode( base64.b64decode(encoding.msgpack_encode(stx1)) + base64.b64decode(encoding.msgpack_encode(stx2))).decode() self.assertEqual(goldenTxg, txg) # check filtering txns = transaction.assign_group_id([tx1, tx2], address=fromAddress) self.assertEqual(len(txns), 2) self.assertEqual(stx1.transaction.group, txns[0].group) txns = transaction.assign_group_id([tx1, tx2], address="NONEXISTENT") self.assertEqual(len(txns), 0)