def ensure_transaction_posted(ext_api, signed_tx): tx_object = Tx(tx=signed_tx) tx_hash = ext_api.post_transaction(tx_object).tx_hash top = ext_api.get_current_key_block() wait_until_height(ext_api, top.height + 1) wait(lambda: ext_api.get_transaction_by_hash(tx_hash).block_hash != 'none', timeout_seconds=20, sleep_seconds=0.25)
def test_contract_create(): test_settings = settings["test_contract_create"] (node, (root_dir, external_api, top)) = setup_node_with_tokens(test_settings, "node") internal_api = common.internal_api(node) private_key = keys.new_private() public_key = keys.public_key(private_key) alice_address = keys.address(public_key) test_settings["alice"]["pubkey"] = alice_address send_tokens_to_user("alice", test_settings, external_api, internal_api) encoded_tx, contract_address = get_unsigned_contract_create( alice_address, test_settings["create_contract"], external_api) print("Unsigned encoded transaction: " + encoded_tx) print("Contract address: " + contract_address) unsigned_tx = common.base58_decode(encoded_tx) tx = common.decode_unsigned_tx(unsigned_tx) print("Unsigned decoded transaction: " + str(tx)) # make sure same tx assert_equals(tx['type'], 'contract_create_tx') assert_equals(tx['owner'], common.base58_decode(test_settings["alice"]["pubkey"])) assert_equals(tx['vm_version'], test_settings["create_contract"]["vm_version"]) assert_equals(tx['deposit'], test_settings["create_contract"]["deposit"]) assert_equals(tx['amount'], test_settings["create_contract"]["amount"]) assert_equals(tx['gas'], test_settings["create_contract"]["gas"]) assert_equals(tx['gas_price'], test_settings["create_contract"]["gas_price"]) assert_equals(tx['fee'], test_settings["create_contract"]["fee"]) signed = keys.sign_verify_encode_tx(unsigned_tx, private_key, public_key) print("Signed transaction " + signed) alice_balance0 = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance tx_object = Tx(tx=signed) external_api.post_tx(tx_object) top = external_api.get_top_block() common.wait_until_height(external_api, top.height + 3) alice_balance = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance assert_equals( alice_balance0, alice_balance + test_settings["create_contract"]["fee"] + test_settings["create_contract"]["gas_used"] + test_settings["create_contract"]["deposit"] + test_settings["create_contract"]["amount"]) print("Fee was consumed, transaction is part of the chain") cleanup(node, root_dir)
def test_spend(): test_settings = settings["test_spend"] (root_dir, node, external_api, top) = setup_node_with_tokens(test_settings, "node") internal_api = common.internal_api(node) private_key = keys.new_private() public_key = keys.public_key(private_key) alice_address = keys.address(public_key) bob_address = test_settings["spend_tx"]["recipient"] test_settings["alice"]["pubkey"] = alice_address send_tokens_to_user("alice", test_settings, internal_api, external_api) spend_data_obj = SpendTx(sender=alice_address, recipient_pubkey=bob_address, amount=test_settings["spend_tx"]["amount"], fee=test_settings["spend_tx"]["fee"]) unsigned_spend_obj = external_api.post_spend(spend_data_obj) unsigned_spend_enc = unsigned_spend_obj.tx tx_hash = unsigned_spend_obj.tx_hash unsigned_tx = common.base58_decode(unsigned_spend_enc) unpacked_tx = common.unpack_tx(unsigned_tx) print("Tx " + str(common.parse_tx(unpacked_tx))) alice_balance0 = common.get_account_balance(internal_api, pub_key=alice_address).balance bob_balance0 = common.get_account_balance(internal_api, pub_key=bob_address).balance signed = keys.sign_verify_encode_tx(unsigned_tx, unpacked_tx, private_key, public_key) print("Signed transaction " + signed) print("Tx hash " + tx_hash) tx_object = Tx(tx=signed) external_api.post_tx(tx_object) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3) alice_balance = common.get_account_balance(internal_api, pub_key=alice_address).balance bob_balance = common.get_account_balance(internal_api, pub_key=bob_address).balance tx = external_api.get_tx( tx_hash=tx_hash) # it is there - either in mempool or in a block print("Alice balance now is " + str(alice_balance)) print("Bob balance now is " + str(bob_balance)) print("Balances are updated, transaction has been executed") assert_equals( alice_balance0, alice_balance + test_settings["spend_tx"]["fee"] + test_settings["spend_tx"]["amount"]) assert_equals(bob_balance0, bob_balance - test_settings["spend_tx"]["amount"]) cleanup(node, root_dir)
def register_name(name, address, external_api, private_key): salt = 42 commitment = external_api.get_commitment_hash(name, salt).commitment # preclaim unsigned_preclaim = common.base58_decode(\ external_api.post_name_preclaim(\ NamePreclaimTx(commitment=commitment, fee=1, account=address)).tx) signed_preclaim = keys.sign_encode_tx(unsigned_preclaim, private_key) external_api.post_tx(Tx(tx=signed_preclaim)) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3) # claim encoded_name = common.encode_name(name) unsigned_claim = common.base58_decode(\ external_api.post_name_claim(\ NameClaimTx(name=encoded_name, name_salt=salt, fee=1, account=address)).tx) signed_claim = keys.sign_encode_tx(unsigned_claim, private_key) external_api.post_tx(Tx(tx=signed_claim)) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3) name_entry0 = external_api.get_name(name) print("Name " + name_entry0.name + " has been claimed and has hash " + name_entry0.name_hash) # set pointers pointers_str = json.dumps({'account_pubkey': address}) unsigned_update = common.base58_decode(\ external_api.post_name_update(\ NameUpdateTx(name_hash=name_entry0.name_hash, name_ttl=600000, ttl=50,\ pointers=pointers_str, fee=1, account=address)).tx) signed_update = keys.sign_encode_tx(unsigned_update, private_key) external_api.post_tx(Tx(tx=signed_update)) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3) name_entry = external_api.get_name(name) received_pointers = json.loads(name_entry.pointers) assert_equals(address, received_pointers['account_pubkey'])
def register_name(name, address, external_api, private_key): salt = 42 commitment_id = external_api.get_commitment_hash(name, salt).commitment_id # preclaim unsigned_preclaim = common.base58_decode(\ external_api.post_name_preclaim(\ NamePreclaimTx(commitment_id=commitment_id, fee=1, ttl=100, account_id=address)).tx) signed_preclaim = keys.sign_encode_tx(unsigned_preclaim, private_key) external_api.post_tx(Tx(tx=signed_preclaim)) top = external_api.get_top_block() common.wait_until_height(external_api, top.height + 3) # claim encoded_name = common.encode_name(name) unsigned_claim = common.base58_decode(\ external_api.post_name_claim(\ NameClaimTx(name=encoded_name, name_salt=salt, fee=1, ttl=100, account_id=address)).tx) signed_claim = keys.sign_encode_tx(unsigned_claim, private_key) external_api.post_tx(Tx(tx=signed_claim)) top = external_api.get_top_block() common.wait_until_height(external_api, top.height + 3) name_entry0 = external_api.get_name(name) # set pointers pointers = [ NamePointer(key='account_pubkey', id=address) ] unsigned_update = common.base58_decode(\ external_api.post_name_update(\ NameUpdateTx(name_id=name_entry0.id, name_ttl=6000, client_ttl=50,\ pointers=pointers, fee=1, ttl=100, account_id=address)).tx) signed_update = keys.sign_encode_tx(unsigned_update, private_key) external_api.post_tx(Tx(tx=signed_update)) top = external_api.get_top_block() common.wait_until_height(external_api, top.height + 3) name_entry = external_api.get_name(name) received_pointers = name_entry.pointers[0] assert_equals('account_pubkey', received_pointers.key) assert_equals(address, received_pointers.id)
def send_tokens_to_unchanging_user(sender, address, tokens, fee, external_api, internal_api): spend_tx_obj = SpendTx( sender_id=sender['enc_pubk'], recipient_id=address, amount=tokens, fee=fee, ttl=100, payload="sending tokens") spend_tx = internal_api.post_spend(spend_tx_obj).tx unsigned_tx = api_decode(spend_tx) signed_tx = integration.keys.sign_encode_tx(unsigned_tx, sender['privk']) external_api.post_transaction(Tx(tx=signed_tx))
def send_tokens_to_name(name, tokens, sender_address, private_key, external_api): name_entry = external_api.get_name(name) resolved_address = json.loads(name_entry.pointers)['account_pubkey'] print("Name " + name + " resolved to address " + resolved_address) unsigned_spend = common.base58_decode(\ external_api.post_spend(\ SpendTx(sender=sender_address, recipient_pubkey=resolved_address, amount=tokens, fee=1)).tx) signed_spend = keys.sign_encode_tx(unsigned_spend, private_key) external_api.post_tx(Tx(tx=signed_spend)) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3)
def send_tokens_to_name(name, tokens, sender_address, private_key, external_api): name_entry = external_api.get_name(name) resolved_address = name_entry.pointers[0].id print("Name " + name + " resolved to address " + resolved_address) unsigned_spend = common.base58_decode(\ external_api.post_spend(\ SpendTx(sender_id=sender_address, recipient_id=resolved_address, amount=tokens, fee=1,\ ttl=100, payload="foo")).tx) signed_spend = keys.sign_encode_tx(unsigned_spend, private_key) external_api.post_tx(Tx(tx=signed_spend)) top = external_api.get_top_block() common.wait_until_height(external_api, top.height + 3)
def test_contract_create(): test_settings = settings["test_contract_create"] (root_dir, node, external_api, top) = setup_node_with_tokens(test_settings, "node") internal_api = common.internal_api(node) send_tokens_to_user("alice", test_settings, internal_api, external_api) encoded_tx = get_unsigned_contract_create(test_settings["alice"]["pubkey"], test_settings["create_contract"], external_api) print("Unsigned encoded transaction: " + encoded_tx) unsigned_tx = common.base58_decode(encoded_tx) unpacked_tx = common.unpack_tx(unsigned_tx) tx = common.parse_tx(unpacked_tx) print("Unsigned decoded transaction: " + str(tx)) # make sure same tx assert_equals(tx['type'], 'contract_create') assert_equals(tx['owner'], common.base58_decode(test_settings["alice"]["pubkey"])) assert_equals(tx['vm_version'], test_settings["create_contract"]["vm_version"]) assert_equals(tx['deposit'], test_settings["create_contract"]["deposit"]) assert_equals(tx['amount'], test_settings["create_contract"]["amount"]) assert_equals(tx['gas'], test_settings["create_contract"]["gas"]) assert_equals(tx['gas_price'], test_settings["create_contract"]["gas_price"]) assert_equals(tx['fee'], test_settings["create_contract"]["fee"]) code = bytearray.fromhex(test_settings["create_contract"]["code"][2:]) # without 0x assert_equals(tx['code'], code) call_data = bytearray.fromhex(test_settings["create_contract"]["call_data"][2:]) # without 0x assert_equals(tx['call_data'], call_data) signature = bytearray(list(map(int, test_settings["create_contract"]["signature"].split(",")))) signed = common.encode_signed_tx(unpacked_tx, [signature]) print("Signed transaction " + signed) alice_balance0 = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance tx_object = Tx(tx=signed) external_api.post_tx(tx_object) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3) alice_balance = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance assert_equals(alice_balance0, alice_balance + test_settings["create_contract"]["fee"]) cleanup(node, root_dir)
def test_contract_on_chain_call_off_chain(): test_settings = settings["test_contract_call"] create_settings = settings["test_contract_create"] beneficiary = common.setup_beneficiary() (node, (root_dir, external_api, top)) = setup_node_with_tokens(test_settings, beneficiary, "node") internal_api = common.internal_api(node) private_key = keys.new_private() public_key = keys.public_key(private_key) alice_address = keys.address(public_key) test_settings["alice"]["pubkey"] = alice_address send_tokens_to_user(beneficiary, "alice", test_settings, external_api, internal_api) ## create contract encoded_tx, encoded_contract_id = get_unsigned_contract_create( alice_address, create_settings["create_contract"], external_api, internal_api) unsigned_tx = common.base58_decode(encoded_tx) signed = keys.sign_verify_encode_tx(unsigned_tx, private_key, public_key) alice_balance0 = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance tx_object = Tx(tx=signed) external_api.post_transaction(tx_object) top = external_api.get_top_block() common.wait_until_height(external_api, top.height + 3) call_contract = test_settings["contract_call"] call_input = ContractCallInput("sophia-address", encoded_contract_id,\ call_contract["data"]["function"],\ call_contract["data"]["argument"]) result = internal_api.call_contract(call_input) assert_equals( '0x000000000000000000000000000000000000000000000000000000000000002a', result.out) cleanup(node, root_dir)
def send_tokens_to_unchanging_user(beneficiary, address, tokens, fee, external_api, internal_api): import keys def get_balance(k): return get_account_balance(external_api, internal_api, k).balance bal0 = get_balance(address) spend_tx_obj = SpendTx(sender_id=beneficiary['enc_pubk'], recipient_id=address, amount=tokens, fee=fee, ttl=100, payload="sending tokens") spend_tx = internal_api.post_spend(spend_tx_obj).tx unsigned_tx = base58_decode(spend_tx) signed_tx = keys.sign_encode_tx(unsigned_tx, beneficiary['privk']) external_api.post_transaction(Tx(tx=signed_tx)) wait(lambda: get_balance(address) == (bal0 + tokens), timeout_seconds=20, sleep_seconds=0.25)
def test_contract_call(): test_settings = settings["test_contract_call"] create_settings = settings["test_contract_create"] (root_dir, node, external_api, top) = setup_node_with_tokens(test_settings, "node") internal_api = common.internal_api(node) private_key = keys.new_private() public_key = keys.public_key(private_key) alice_address = keys.address(public_key) test_settings["alice"]["pubkey"] = alice_address send_tokens_to_user("alice", test_settings, external_api, internal_api) ## create contract encoded_tx, encoded_contract_address = get_unsigned_contract_create(alice_address, create_settings["create_contract"], external_api) unsigned_tx = common.base58_decode(encoded_tx) signed = keys.sign_verify_encode_tx(unsigned_tx, private_key, public_key) alice_balance0 = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance tx_object = Tx(tx=signed) external_api.post_tx(tx_object) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3) alice_balance = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance # assert contract created: call_contract = test_settings["contract_call"] assert_equals(alice_balance0, alice_balance + create_settings["create_contract"]["fee"] + create_settings["create_contract"]["gas_used"] + create_settings["create_contract"]["deposit"] + create_settings["create_contract"]["amount"]) call_input = ContractCallInput("sophia", create_settings["create_contract"]["code"],\ call_contract["data"]["function"],\ call_contract["data"]["argument"]) result = external_api.call_contract(call_input) contract_call_obj = ContractCallData( caller=test_settings["alice"]["pubkey"], contract=encoded_contract_address, vm_version=call_contract["vm_version"], fee=call_contract["fee"], ttl=100, amount=call_contract["amount"], gas=call_contract["gas"], gas_price=call_contract["gas_price"], call_data=result.out) call_tx_obj = external_api.post_contract_call(contract_call_obj) encoded_call_tx = call_tx_obj.tx print("Unsigned encoded transaction: " + encoded_call_tx) unsigned_call_tx = common.base58_decode(encoded_call_tx) signed_call = keys.sign_verify_encode_tx(unsigned_call_tx, private_key, public_key) print("Signed transaction: " + signed_call) alice_balance0 = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance tx_object = Tx(tx=signed_call) external_api.post_tx(tx_object) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3) alice_balance = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance # The call runs out of gas and all gas is consumed # assert contract called: assert_equals(alice_balance0, alice_balance + test_settings["contract_call"]["fee"] + test_settings["contract_call"]["gas"] + test_settings["contract_call"]["amount"]) print("Fee and gas was consumed, transaction is part of the chain") cleanup(node, root_dir)
def test_spend(): # Alice should be able to create a spend transaction to send tokens to # Bob. In a controlled environment, Alice should see her transaction # appear in the next block or two that are added to the blockchain. # # Once that happens, Alice should see her account debited and Bob's # account credited with the same number of tokens. # # The debit/credit should not happen until the transaction is confirmed, # e.g. included in at least one block in the chain. # Setup test_settings = settings["test_spend"] (root_dir, node, external_api, top) = setup_node_with_tokens(test_settings, "node") internal_api = common.internal_api(node) private_key = keys.new_private() public_key = keys.public_key(private_key) alice_address = keys.address(public_key) bob_address = test_settings["spend_tx"]["recipient"] test_settings["alice"]["pubkey"] = alice_address send_tokens_to_user("alice", test_settings, external_api, internal_api) alice_balance0 = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance bob_balance0 = common.get_account_balance(external_api, internal_api, pub_key=bob_address).balance # Alice creates spend tx spend_data_obj = SpendTx( sender=alice_address, recipient_pubkey=bob_address, amount=test_settings["spend_tx"]["amount"], fee=test_settings["spend_tx"]["fee"], ttl=100, payload="foo") unsigned_spend_obj = external_api.post_spend(spend_data_obj) unsigned_spend_enc = unsigned_spend_obj.tx unsigned_tx = common.base58_decode(unsigned_spend_enc) # Alice signs spend tx signed = keys.sign_verify_encode_tx(unsigned_tx, private_key, public_key) tx_hash = keys.tx_hash_from_signed_encoded(signed) print("Tx hash " + tx_hash) print("Signed transaction " + signed) # Alice posts spend tx tx_object = Tx(tx=signed) external_api.post_tx(tx_object) _ = external_api.get_tx(tx_hash=tx_hash) # it is there - either in mempool or in a block # Wait until spend tx is mined wait(lambda: common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance < alice_balance0, timeout_seconds=120, sleep_seconds=0.25) _ = external_api.get_tx(tx_hash=tx_hash) # it is there - shall be in a block print("Tx in chain ") # Check that Alice was debited and Bob was credited alice_balance = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance bob_balance = common.get_account_balance(external_api, internal_api, pub_key=bob_address).balance print("Alice balance now is " + str(alice_balance)) print("Bob balance now is " + str(bob_balance)) assert_equals(alice_balance0, alice_balance + test_settings["spend_tx"]["fee"] + test_settings["spend_tx"]["amount"]) assert_equals(bob_balance0, bob_balance - test_settings["spend_tx"]["amount"]) # Cleanup cleanup(node, root_dir)
def post_transaction(ext_api, signed_tx): tx_object = Tx(tx=signed_tx) return ext_api.post_transaction(tx_object).tx_hash
def test_contract_call(): test_settings = settings["test_contract_call"] create_settings = settings["test_contract_create"] (root_dir, node, external_api, top) = setup_node_with_tokens(test_settings, "node") internal_api = common.internal_api(node) send_tokens_to_user("alice", test_settings, internal_api, external_api) ## create contract encoded_tx = get_unsigned_contract_create(test_settings["alice"]["pubkey"], create_settings["create_contract"], external_api) unsigned_tx = common.base58_decode(encoded_tx) unpacked_tx = common.unpack_tx(unsigned_tx) signature = bytearray(list(map(int, create_settings["create_contract"]["signature"].split(",")))) signed = common.encode_signed_tx(unpacked_tx,[signature]) alice_balance0 = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance tx_object = Tx(tx=signed) external_api.post_tx(tx_object) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3) alice_balance = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance # assert contract created: call_contract = test_settings["contract_call"] assert_equals(alice_balance0, alice_balance + create_settings["create_contract"]["fee"]) call_input = ContractCallInput("ring", create_settings["create_contract"]["code"],\ call_contract["data"]["function"],\ call_contract["data"]["argument"]) result = external_api.call_contract(call_input) contract_call_obj = ContractCallData( caller=test_settings["alice"]["pubkey"], contract=call_contract["contract"], vm_version=call_contract["vm_version"], fee=call_contract["fee"], amount=call_contract["amount"], gas=call_contract["gas"], gas_price=call_contract["gas_price"], call_data=result.out) call_tx_obj = external_api.post_contract_call(contract_call_obj) encoded_call_tx = call_tx_obj.tx print("Unsigned encoded transaction: " + encoded_call_tx) unsigned_call_tx = common.base58_decode(encoded_call_tx) unpacked_call_tx = common.unpack_tx(unsigned_call_tx) tx = common.parse_tx(unpacked_call_tx) print("Unsigned decoded transaction: " + str(tx)) signature = bytearray(list(map(int, test_settings["contract_call"]["signature"].split(",")))) signed = common.encode_signed_tx(unpacked_call_tx,[signature]) print("Signed transaction: " + signed) alice_balance0 = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance tx_object = Tx(tx=signed) external_api.post_tx(tx_object) top = external_api.get_top() common.wait_until_height(external_api, top.height + 3) alice_balance = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance print("BALANCE0 " + str(alice_balance0)) print("BALANCE " + str(alice_balance)) # assert contract created: assert_equals(alice_balance0, alice_balance + test_settings["contract_call"]["fee"]) cleanup(node, root_dir)