def test_sign_offline(cluster): """ check simple transfer tx success - send 1cro from community to reserve """ # 1. first create two hd new wallet seed = "dune car envelope chuckle elbow slight proud fury remove candy uphold \ puzzle call select sibling sport gadget please want vault glance verb damage gown" wallet_1 = Wallet(seed) address_1 = wallet_1.address wallet_2 = Wallet.new() address_2 = wallet_2.address sender_addr = cluster.address("signer1") sender_balance = cluster.balance(sender_addr) assert sender_balance > 100 * 10**8 balance_1 = cluster.balance(wallet_1.address) assert balance_1 == 0 balance_2 = cluster.balance(wallet_2.address) assert balance_2 == 0 # 2. transfer some coin to wallet_1 cluster.transfer(sender_addr, address_1, "100cro") wait_for_new_blocks(cluster, 2) assert cluster.balance(sender_addr) == sender_balance - 100 * 10**8 assert cluster.balance(address_1) == 100 * 10**8 # 3. get the send's account info port = ports.api_port(cluster.base_port(0)) api = ApiUtil(port) amount = 1 * 10**8 # make transaction without/with fee for fee in [0, 600000]: sender_account_info = api.account_info(address_1) balance_1_before = api.balance(address_1) balance_2_before = api.balance(address_2) tx = Transaction( wallet=wallet_1, account_num=sender_account_info["account_num"], sequence=sender_account_info["sequence"], chain_id=cluster.chain_id, fee=fee, ) tx.add_transfer(to_address=address_2, amount=amount, base_denom="basecro") signed_tx = tx.get_pushable() assert isinstance(signed_tx, dict) api.broadcast_tx(signed_tx) wait_for_new_blocks(cluster, 3) balance_1_after = api.balance(address_1) balance_2_after = api.balance(address_2) assert balance_2_after == balance_2_before + amount assert balance_1_after == balance_1_before - amount - fee
def test_2_msgs_in_1_tx(blockchain_accounts, local_test_network_config: "NetworkConfig"): client = GrpcClient(local_test_network_config) alice_info = get_blockchain_account_info(blockchain_accounts, ALICE) alice_wallet = Wallet(alice_info["mnemonic"]) alice_account = client.query_account(alice_info["address"]) bob_info = get_blockchain_account_info(blockchain_accounts, BOB) bob_wallet = Wallet(bob_info["mnemonic"]) alice_bal_init = client.query_account_balance(alice_wallet.address) bob_bal_init = client.query_account_balance(bob_wallet.address) alice_coin_init = CROCoin(alice_bal_init.balance.amount, alice_bal_init.balance.denom, local_test_network_config) bob_coin_init = CROCoin(bob_bal_init.balance.amount, bob_bal_init.balance.denom, local_test_network_config) ten_cro = CROCoin("10", CRO_DENOM, local_test_network_config) twnenty_cro = CROCoin("20", CRO_DENOM, local_test_network_config) one_cro_fee = CROCoin("1", CRO_DENOM, local_test_network_config) msg_send_10_cro = MsgSend( from_address=alice_info["address"], to_address=bob_info["address"], amount=[ten_cro.protobuf_coin_message], ) msg_send_20_cro = MsgSend( from_address=alice_info["address"], to_address=bob_info["address"], amount=[twnenty_cro.protobuf_coin_message], ) tx = Transaction( chain_id=local_test_network_config.chain_id, from_wallets=[alice_wallet], msgs=[msg_send_10_cro], account_number=alice_account.account_number, fee=[one_cro_fee.protobuf_coin_message], client=client, ).append_message(msg_send_20_cro) signature_alice = alice_wallet.sign(tx.sign_doc.SerializeToString()) signed_tx = tx.set_signatures(signature_alice).signed_tx client.broadcast_transaction(signed_tx.SerializeToString()) alice_bal_aft = client.query_account_balance(alice_wallet.address) bob_bal_aft = client.query_account_balance(bob_wallet.address) alice_coin_aft = CROCoin(alice_bal_aft.balance.amount, alice_bal_aft.balance.denom, local_test_network_config) bob_coin_aft = CROCoin(bob_bal_aft.balance.amount, bob_bal_aft.balance.denom, local_test_network_config) assert alice_coin_aft == alice_coin_init - ten_cro - twnenty_cro - one_cro_fee assert bob_coin_aft == bob_coin_init + ten_cro + twnenty_cro
def simple_transaction(): client = GrpcClient(LOCAL_NETWORK) sending_wallet = Wallet( MNEMONIC_PHRASE, LOCAL_NETWORK.derivation_path, LOCAL_NETWORK.address_prefix ) sending_account = client.query_account(sending_wallet.address) sending_account_init_bal = client.query_account_balance(sending_wallet.address) receiving_account_init_bal = client.query_account_balance(TO_ADDRESS) print( f"sending account initial balance: {sending_account_init_bal.balance.amount}" f"{sending_account_init_bal.balance.denom}" ) print( f"receiving account initial balance: {receiving_account_init_bal.balance.amount}" f"{receiving_account_init_bal.balance.denom}" ) ten_cro = CROCoin("10", "cro", LOCAL_NETWORK) one_cro_fee = CROCoin("1", "cro", LOCAL_NETWORK) msg_send = MsgSend( from_address=sending_wallet.address, to_address=TO_ADDRESS, amount=[ten_cro.protobuf_coin_message], ) tx = Transaction( chain_id=LOCAL_NETWORK.chain_id, from_wallets=[sending_wallet], msgs=[msg_send], account_number=sending_account.account_number, fee=[one_cro_fee.protobuf_coin_message], client=client, ) signature_alice = sending_wallet.sign(tx.sign_doc.SerializeToString()) signed_tx = tx.set_signatures(signature_alice).signed_tx client.broadcast_transaction(signed_tx.SerializeToString()) sending_account_aft_bal = client.query_account_balance(sending_wallet.address) receiving_account_aft_bal = client.query_account_balance(TO_ADDRESS) print("After transaction of sending 10cro with a 1cro fee:") print( f"sending account after balance: {sending_account_aft_bal.balance.amount}" f"{sending_account_aft_bal.balance.denom}" ) print( f"receiving account after balance: {receiving_account_aft_bal.balance.amount}" f"{receiving_account_aft_bal.balance.denom}" )
def main(): seed = "dune car envelope chuckle elbow slight proud fury remove candy uphold puzzle call select sibling sport gadget please want vault glance verb damage gown" wallet_1 = Wallet(seed) address_1 = wallet_1.address print(address_1) wallet_2 = Wallet.new() address_2 = wallet_2.address print(address_2) # the api port setted in ${home_dir of chain-maind}/config/app.toml, the default is ~/.chain-maind/config/app.toml base_url = "http://127.0.0.1:1317" url_tx = f"{base_url}/txs" url_account = f"{base_url}/cosmos/auth/v1beta1/accounts/{address_1}" url_balance = f"{base_url}/cosmos/bank/v1beta1/balances/{address_1}" # get the balance of address_1 response = requests.get(url_balance) balance_1 = int(response.json()["balances"][0]["amount"]) print(f"balance of address 1: {balance_1}") # get the account info response = requests.get(url_account) account_info = response.json()["account"] account_num = int(account_info["account_number"]) sequence = int(account_info["sequence"]) # make transaction tx = Transaction( wallet=wallet_1, account_num=account_num, sequence=sequence, chain_id="test", fee=100000, gas=300000, ) amount = 1 * 10 ** 8 tx.add_transfer(to_address=address_2, amount=amount) signed_tx = tx.get_pushable() print("signed tx:", signed_tx) response = requests.post(url_tx, json=signed_tx) if not response.ok: raise Exception(response.reason) result = response.json() print(result) if result.get("code"): raise Exception(result["raw_log"]) # get the balance after sync time.sleep(5) response = requests.get(url_balance) balance_1_after = int(response.json()["balances"][0]["amount"]) print(f"balance of address 1 after transfer: {balance_1_after}")
def test_sign(): unordered_sign_message = { "chain_id": "tendermint_test", "account_number": "1", "fee": { "gas": "21906", "amount": [{ "amount": "0", "denom": "" }] }, "memo": "", "sequence": "0", "msgs": [{ "type": "cosmos-sdk/Send", "value": { "inputs": [{ "address": "tcro1qperwt9wrnkg5k9e5gzfgjppzpqhyav5j24d66", "coins": [{ "amount": "1", "denom": "STAKE" }], }], "outputs": [{ "address": "tcro1yeckxz7tapz34kjwnjxvmxzurerquhtrmxmuxt", "coins": [{ "amount": "1", "denom": "STAKE" }], }], }, }], } seed = "dune car envelope chuckle elbow slight proud fury remove candy uphold puzzle call select sibling sport gadget please want vault glance verb damage gown" wallet = Wallet(seed) dummy_num = 1337 tx = Transaction( wallet=wallet, account_num=dummy_num, sequence=dummy_num, fee=dummy_num, gas=dummy_num, ) tx._get_sign_message = Mock( return_value=unordered_sign_message) # type: ignore expected_signature = ( "s2Yz6UjEpLJuNcyWn5E2adUu5Vn7gbKwrtyoBrQWEhUTomnxlASRnP/1GD/j1MD4PeJsNtE0MOjwOyFt8dU2cw==" ) actual_signature = tx._sign() assert actual_signature == expected_signature
def test_generate_wallet(): seed = "burst negative solar evoke traffic yard lizard next series foster seminar enter wrist captain bulb trap giggle country sword season shoot boy bargain deal" wallet = Wallet(seed) assert wallet.private_key == bytes.fromhex( "dc81c553efffdce74035a194ea7a58f1d67bdfd1329e33f684460d9ed6223faf" ) assert wallet.public_key == bytes.fromhex( "02089cf50d9fc7d98e650dadd5569671ccc6389d845b00dfbcfc01bd5b58969a0c" ) assert wallet.address == "cro1yj3fd8gxrqd2662p8ywp26t4hfws9p5n75xjum"
def test_get_pushable_tx(): expected_pushable_tx = '{"tx":{"msg":[{"type":"cosmos-sdk/MsgSend","value":{"from_address":"cro1u9q8mfpzhyv2s43js7l5qseapx5kt3g2rf7ppf","to_address":"cro103l758ps7403sd9c0y8j6hrfw4xyl70j4mmwkf","amount":[{"denom":"basecro","amount":"288000"}]}}],"fee":{"gas":"30000","amount":[{"amount":"100000","denom":"basecro"}]},"memo":"","signatures":[{"signature":"WjB3aB3k/nUK33iyGvbMPu55iiyCJBr7ooKQXwxE1BFAdBjJXIblp1aVPUjlr/blFAlHW7fLJct9zc/7ty8ZQA==","pub_key":{"type":"tendermint/PubKeySecp256k1","value":"AntL+UxMyJ9NZ9DGLp2v7a3dlSxiNXMaItyOXSRw8iYi"},"account_number":"11335","sequence":"0"}]},"mode":"sync"}' seed = "dune car envelope chuckle elbow slight proud fury remove candy uphold puzzle call select sibling sport gadget please want vault glance verb damage gown" wallet = Wallet(seed) fee = 100000 _tx_total_cost = 388000 amount = _tx_total_cost - fee tx = Transaction( wallet=wallet, account_num=11335, sequence=0, fee=fee, gas=30000, chain_id="test", ) tx.add_transfer(to_address="cro103l758ps7403sd9c0y8j6hrfw4xyl70j4mmwkf", amount=amount) pushable_tx = tx.get_pushable() assert pushable_tx == expected_pushable_tx
def main(): print("### STARTING FLODDING ###") # create a wallet from my seed seed = "slogan initial run clock nasty clever aisle trumpet label doll comic fit gas game casino knife outside hunt genuine nerve mad notable alarm camera" wallet_1 = Wallet(seed, path="m/44'/1'/0'/0/0", hrp="tcro") address_1 = wallet_1.address print(address_1) # the api port setted in ${home_dir of chain-maind}/config/app.toml, the default is ~/.chain-maind/config/app.toml local_url = "http://localhost:1317" url_tx = f"{local_url}/txs" #url_info = f"https://crossfire.crypto.com:443/status" url_block = f"http://127.0.0.1:26657/block" url_account = f"{local_url}/cosmos/auth/v1beta1/accounts/{address_1}" url_balance = f"{local_url}/cosmos/bank/v1beta1/balances/{address_1}" # init request session to reuse tcp socket r = requests.Session() response = r.get(url_account) account_info = response.json()["account"] account_num = int(account_info["account_number"]) sequence = int(account_info["sequence"]) stop_at = sequence # create transaction object send_object = Envoi(wallet_1, account_num) send_object.set_mode("sync") #create a logger logger = logging.getLogger('mylogger') seq = 0 now = datetime.now() amount = 1 * 10 ** 8 break_block = 0 # get the account info while True: # get the balance of address_1 response = r.get(url_balance) balance_1 = int(response.json()["balances"][0]["amount"]) #if account_num == 0 or sequence == 0: # get account number and sequence ID response = r.get(url_account) account_info = response.json()["account"] account_num = int(account_info["account_number"]) sequence = int(account_info["sequence"]) response = r.get(url_block) block_height = int(response.json()["result"]["block"]["header"]["height"]) if (sequence != stop_at) and (break_block >= block_height): print(f"{block_height} {sequence} different than {stop_at}", end='\r') sync_block(r) #time.sleep(1) continue else : print("") send_object.set_mode("sync") print(f"balance of address 1: {balance_1}") print(f"sequence start: {sequence}") # check the balance is enought to not drain all our tcro if balance_1 >= 3000000000 : # each loop cost 30TCRO # define last sequence number for the loop stop_at = sequence + 1000 seq = sequence for seq in range(sequence, stop_at): #while True: # make transaction break_block = block_height+20 signed_tx = send_object.get_pushTx_sync(amount=1, sequence=seq, timeout_block=break_block) try: # send the Tx #print(signed_tx) response = r.post(url_tx, json=signed_tx) response.raise_for_status() except HTTPError as e: print(e) time.sleep(1) continue result = response.json() code = result.get("code") # error code managment if not code: print(block_height+5, end=' ') print(seq, end=' ') #print(response.text) print(response.text) # update sequence start number seq += 1 sequence = seq #send_object.set_mode("async") continue if code == 0: print(f"error {code} tx OK") # increment the sequence number seq += 1 # update sequence start number sequence = seq elif code == 4: print(f"sequence {seq} error {code} unauthorized") # unauthorized print(response.text) p = re.compile('\d+') int(p.findall(result['raw_log'])[1]) time.sleep(5) # force retrieve sequence num seq = 0 sequence = seq exit("resync") break elif code == 19: # the Tx already exist, sequence number not up to date print(f"error {code} tx {seq} already in mempool", end='\n') # force retrieve sequence num seq = 0 # update sequence start number sequence = seq break elif code == 20: # mempool is full, give time to purge print(f"index {seq} error {code} mempool is full") # update sequence start number sequence = seq stop_at = seq break elif code == 32: print(f"index {seq} error {code} sequence error (congestion?)") else : # any other code print(f"index {seq} error {code} ") seq = 0 exit("new unknow error") # update sequence start number sequence = seq # end for loop #sync_block(r) #send_object.set_mode("sync") time.sleep(5) else: print("no Tcro left") withdraw_cmd = f"chain-maind tx distribution withdraw-all-rewards --from {address_1} -y --gas-prices 0.1basetcro --chain-id testnet-croeseid-2 --keyring-backend test --home /home/dpierret/.chain-maind" subprocess.check_output(withdraw_cmd, shell=True).decode("utf-8") sync_block(r)
def test_new_wallet(): wallet = Wallet.new() assert len(str(wallet.private_key)) > 0