def send_transaction(self, contract_address: bytes or bytearray, acct: Account, payer_acct: Account, gas_limit: int, gas_price: int, func: AbiFunction, pre_exec: bool): if func is not None: params = BuildParams.serialize_abi_function(func) else: params = bytearray() if pre_exec: if isinstance(contract_address, bytes): tx = NeoVm.make_invoke_transaction(bytearray(contract_address), bytearray(params), b'', 0, 0) elif isinstance(contract_address, bytearray): tx = NeoVm.make_invoke_transaction(contract_address, bytearray(params), b'', 0, 0) else: raise SDKException(ErrorCode.param_err('the data type of contract address is incorrect.')) if acct is not None: self.__sdk.sign_transaction(tx, acct) return self.__sdk.rpc.send_raw_transaction_pre_exec(tx) else: unix_time_now = int(time()) params.append(0x67) for i in contract_address: params.append(i) if payer_acct is None: raise SDKException(ErrorCode.param_err('payer account is None.')) tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer_acct.get_address().to_array(), params, bytearray(), [], bytearray()) self.__sdk.sign_transaction(tx, acct) if acct.get_address_base58() != payer_acct.get_address_base58(): self.__sdk.add_sign_transaction(tx, payer_acct) return self.__sdk.rpc.send_raw_transaction(tx)
def test_new_add_recovery_transaction(self): ont_id = sdk.native_vm().ont_id() gas_limit = 20000 gas_price = 500 private_key = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' acct = Account(private_key, SignatureScheme.SHA256withECDSA) b58_address = acct.get_address_base58() acct_did = "did:ont:" + b58_address hex_public_key = acct.get_public_key_hex() rand_private_key = util.get_random_bytes(32).hex() recovery = Account(rand_private_key, SignatureScheme.SHA256withECDSA) b58_recovery_address = recovery.get_address_base58() tx = ont_id.new_add_recovery_transaction(acct_did, hex_public_key, b58_recovery_address, b58_address, gas_limit, gas_price) tx = sdk.sign_transaction(tx, acct) try: sdk.rpc.send_raw_transaction(tx) except SDKException as e: msg = 'Other Error, [NeoVmService] service system call error!: [SystemCall] service execute ' \ 'error!: [Invoke] Native serivce function execute error!: add recovery failed: already ' \ 'set recovery' self.assertEqual(59000, e.args[0]) self.assertEqual(msg, e.args[1])
def send_transaction(self, contract_address: bytearray, acct: Account, payer_acct: Account, gas_limit: int, gas_price: int, func: AbiFunction, pre_exec: bool): params = bytearray() if func is not None: params = BuildParams.serialize_abi_function(func) if pre_exec: tx = NeoVm.make_invoke_transaction(bytearray(contract_address), bytearray(params), b'', 0, 0) if acct is not None: self.__sdk.sign_transaction(tx, acct) return self.__sdk.rpc.send_raw_transaction_pre_exec(tx) unix_time_now = int(time()) params.append(0x67) for i in contract_address: params.append(i) tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer_acct.get_address().to_array(), params, bytearray(), [], bytearray()) if acct is not None: self.__sdk.sign_transaction(tx, acct) if payer_acct is not None and acct is not None and acct.get_address_base58( ) != payer_acct.get_address_base58(): self.__sdk.add_sign_transaction(tx, payer_acct) return self.__sdk.rpc.send_raw_transaction(tx)
def unauthorize_for_peer(self, account: Account, peer_publickeys: [], pos_lists: [], payer: Account, gas_limit: int, gas_price: int): contract_address = bytearray.fromhex(self.CONTRACT_ADDRESS) if len(peer_publickeys) != len(pos_lists): raise Exception( "the length of peer_publickeys should equal the length of pos_lists" ) param = { "address": account.get_address().to_bytes(), "publickeys_length": len(peer_publickeys) } for i in range(len(peer_publickeys)): param["publickey" + str(i)] = peer_publickeys[i] param["pos_lists_length"] = len(pos_lists) for i in range(len(pos_lists)): param["pos_lists" + str(i)] = pos_lists[i] invoke_code = build_native_invoke_code(contract_address, b'\x00', "unAuthorizeForPeer", param) unix_time_now = int(time()) tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer.get_address().to_bytes(), invoke_code, bytearray(), []) tx.sign_transaction(account) if payer is not None and account.get_address_base58( ) is not payer.get_address_base58(): tx.add_sign_transaction(payer) return self.__sdk.get_network().send_raw_transaction(tx)
def send_approve(self, asset, sender: Account, b58_recv_address: str, amount: int, payer: Account, gas_limit: int, gas_price: int) -> str: """ This is an interface used to send an approve transaction which allow receiver to spend a amount of ONT or ONG asset in sender's account. :param asset: a string which is used to indicate what asset we want to approve. :param sender: an Account class that send the approve transaction. :param b58_recv_address: a base58 encode address which indicate where the approve to. :param amount: the amount of asset want to approve. :param payer: an Account class that used to pay for the transaction. :param gas_limit: an int value that indicate the gas limit. :param gas_price: an int value that indicate the gas price. :return: hexadecimal transaction hash value. """ if sender is None: raise SDKException(ErrorCode.param_err('the sender should not be None.')) if payer is None: raise SDKException(ErrorCode.param_err('the payer should not be None.')) if amount <= 0: raise SDKException(ErrorCode.other_error('the amount should be greater than than zero.')) if gas_price < 0: raise SDKException(ErrorCode.other_error('the gas price should be equal or greater than zero.')) if gas_limit < 0: raise SDKException(ErrorCode.other_error('the gas limit should be equal or greater than zero.')) b58_sender_address = sender.get_address_base58() b58_payer_address = payer.get_address_base58() tx = self.new_approve_transaction(asset, b58_sender_address, b58_recv_address, amount, b58_payer_address, gas_limit, gas_price) tx.sign_transaction(sender) if sender.get_address_base58() != payer.get_address_base58(): tx.add_sign_transaction(payer) return self.__sdk.get_network().send_raw_transaction(tx)
def send_transfer_from(self, asset: str, sender: Account, b58_from_address: str, b58_recv_address: str, amount: int, payer: Account, gas_limit: int, gas_price: int) -> str: """ This interface is used to generate a Transaction object for transfer that allow one account to transfer a amount of ONT or ONG Asset to another account, in the condition of the first account had been approved. :param asset: a string which is used to indicate which asset we want to transfer. :param sender: an Account class that send the transfer transaction. :param b58_from_address: a base58 encode address which indicate where the asset from. :param b58_recv_address: a base58 encode address which indicate where the asset to. :param amount: the amount of asset want to transfer from from-address. :param payer: an Account class that used to pay for the transaction. :param gas_limit: an int value that indicate the gas limit. :param gas_price: an int value that indicate the gas price. :return: hexadecimal transaction hash value. """ if sender is None: raise SDKException(ErrorCode.param_err('the sender should not be None.')) if payer is None: raise SDKException(ErrorCode.param_err('the payer should not be None.')) if amount <= 0: raise SDKException(ErrorCode.other_error('the amount should be greater than than zero.')) if gas_price < 0: raise SDKException(ErrorCode.other_error('the gas price should be equal or greater than zero.')) if gas_limit < 0: raise SDKException(ErrorCode.other_error('the gas limit should be equal or greater than zero.')) b58_payer_address = payer.get_address_base58() b58_sender_address = sender.get_address_base58() tx = self.new_transfer_from_transaction(asset, b58_sender_address, b58_from_address, b58_recv_address, amount, b58_payer_address, gas_limit, gas_price) tx.sign_transaction(sender) if b58_sender_address != b58_payer_address: tx.add_sign_transaction(payer) return self.__sdk.get_network().send_raw_transaction(tx)
def test_transfer_multi(self): sdk = OntologySdk() sdk.set_rpc(local_rpc_address) oep4 = sdk.neo_vm().oep4() oep4.set_contract_address(contract_address) private_key1 = "5f2fe68215476abb9852cfa7da31ef00aa1468782d5ca809da5c4e1390b8ee45" private_key2 = "f00dd7f5356e8aee93a049bdccc44ce91169e07ea3bec9f4e0142e456fd39bae" private_key3 = "da213fb4cb1b12269c20307dadda35a7c89869c0c791b777fd8618d4159db99c" acct1 = Account(private_key1, SignatureScheme.SHA256withECDSA) acct2 = Account(private_key2, SignatureScheme.SHA256withECDSA) acct3 = Account(private_key3, SignatureScheme.SHA256withECDSA) b58_from_address1 = acct1.get_address_base58() hex_from_address1 = acct1.get_address_hex() from_address_list = [hex_from_address1, hex_from_address1] b58_to_address2 = acct2.get_address_base58() b58_to_address3 = acct3.get_address_base58() hex_to_address2 = acct2.get_address_hex() hex_to_address3 = acct3.get_address_hex() to_address_list = [hex_to_address2, hex_to_address3] value_list = [1, 2] # print("b58 addr 1 is ", b58_from_address1) # print("b58 addr 1 is ", b58_to_address2) # print("b58 addr 1 is ", b58_to_address3) transfer1 = [b58_from_address1, b58_to_address2, value_list[0]] transfer2 = [b58_from_address1, b58_to_address3, value_list[1]] signers = [acct1] args = [] args.append(transfer1) args.append(transfer2) gas_limit = 20000000 gas_price = 500 tx_hash = oep4.transfer_multi(args, signers[0], signers, gas_limit, gas_price) self.assertEqual(64, len(tx_hash)) sdk = OntologySdk() sdk.set_rpc(local_rpc_address) time.sleep(10) try: event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash) # print("event is ", event) notify = event['Notify'][0:-1] # print("notify is ", notify) self.assertEqual(len(args), len(notify)) for index in range(len(notify)): self.assertEqual(from_address_list[index], notify[index]['States'][1]) self.assertEqual(to_address_list[index], notify[index]['States'][2]) self.assertEqual(value_list[index], int(notify[index]['States'][3])) except SDKException as e: raised = False self.assertTrue(raised, e)
def send_withdraw_ong_transaction(self, claimer: Account, b58_recv_address: str, amount: int, payer: Account, gas_limit: int, gas_price: int) -> str: """ This interface is used to withdraw a amount of ong and transfer them to receive address. :param claimer: the owner of ong that remained to claim. :param b58_recv_address: the address that received the ong. :param amount: the amount of ong want to claim. :param payer: an Account class that used to pay for the transaction. :param gas_limit: an int value that indicate the gas limit. :param gas_price: an int value that indicate the gas price. :return: hexadecimal transaction hash value. """ if claimer is None: raise SDKException(ErrorCode.param_err('the claimer should not be None.')) if payer is None: raise SDKException(ErrorCode.param_err('the payer should not be None.')) if amount <= 0: raise SDKException(ErrorCode.other_error('the amount should be greater than than zero.')) if gas_price < 0: raise SDKException(ErrorCode.other_error('the gas price should be equal or greater than zero.')) if gas_limit < 0: raise SDKException(ErrorCode.other_error('the gas limit should be equal or greater than zero.')) b58_claimer = claimer.get_address_base58() b58_payer = payer.get_address_base58() tx = self.new_withdraw_ong_transaction(b58_claimer, b58_recv_address, amount, b58_payer, gas_limit, gas_price) tx.sign_transaction(claimer) if claimer.get_address_base58() != payer.get_address_base58(): tx.add_sign_transaction(payer) return self.__sdk.get_network().send_raw_transaction(tx)
def send_neo_vm_transaction(self, contract_address: str or bytes or bytearray, acct: Account, payer_acct: Account, gas_limit: int, gas_price: int, func: AbiFunction or InvokeFunction, pre_exec: bool, is_full: bool = False): if isinstance(func, AbiFunction): params = BuildParams.serialize_abi_function(func) elif isinstance(func, InvokeFunction): params = func.create_invoke_code() else: raise SDKException(ErrorCode.other_error('the type of func is error.')) if isinstance(contract_address, str) and len(contract_address) == 40: contract_address = bytearray(binascii.a2b_hex(contract_address)) contract_address.reverse() if pre_exec: if isinstance(contract_address, bytes): tx = NeoVm.make_invoke_transaction(bytearray(contract_address), bytearray(params), b'', 0, 0) elif isinstance(contract_address, bytearray): tx = NeoVm.make_invoke_transaction(contract_address, bytearray(params), b'', 0, 0) else: raise SDKException(ErrorCode.param_err('the data type of contract address is incorrect.')) if acct is not None: tx.sign_transaction(acct) return self.send_raw_transaction_pre_exec(tx, is_full) else: unix_time_now = int(time()) params.append(0x67) for i in contract_address: params.append(i) if payer_acct is None: raise SDKException(ErrorCode.param_err('payer account is None.')) tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer_acct.get_address().to_bytes(), params, bytearray(), []) tx.sign_transaction(payer_acct) if isinstance(acct, Account) and acct.get_address_base58() != payer_acct.get_address_base58(): tx.add_sign_transaction(acct) return self.send_raw_transaction(tx, is_full)
def withdraw(self, account: Account, peer_publickeys: list, withdraw_list: list, payer: Account, gas_limit: int, gas_price: int): contract_address = bytearray.fromhex(self.CONTRACT_ADDRESS) if len(peer_publickeys) != len(withdraw_list): raise Exception( "the length of peer_publickeys should equal the length of pos_lists" ) param = { "address": account.get_address().to_array(), "publickeys_length": len(peer_publickeys) } for i in range(len(peer_publickeys)): param["publickey" + str(i)] = peer_publickeys[i] param["pos_lists_length"] = len(withdraw_list) for i in range(len(withdraw_list)): param["pos_lists" + str(i)] = withdraw_list[i] invoke_code = build_native_invoke_code(contract_address, bytes([0]), "withdraw", param) unix_time_now = int(time()) tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer.get_address().to_array(), invoke_code, bytearray(), [], bytearray()) self.__sdk.sign_transaction(tx, account) if payer is not None and account.get_address_base58( ) is not payer.get_address_base58(): self.__sdk.add_sign_transaction(tx, payer) self.__sdk.rpc.send_raw_transaction(tx) return tx.hash256_explorer()
def test_transfer_multi(self): sdk = OntologySdk() sdk.set_rpc(remote_rpc_address) contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9' oep4 = sdk.neo_vm().oep4() oep4.set_contract_address(contract_address) private_key1 = '523c5fcf74823831756f0bcb3634234f10b3beb1c05595058534577752ad2d9f' private_key2 = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' private_key3 = '1383ed1fe570b6673351f1a30a66b21204918ef8f673e864769fa2a653401114' acct1 = Account(private_key1, SignatureScheme.SHA256withECDSA) acct2 = Account(private_key2, SignatureScheme.SHA256withECDSA) acct3 = Account(private_key3, SignatureScheme.SHA256withECDSA) args = list() b58_from_address1 = acct1.get_address_base58() b58_from_address2 = acct2.get_address_base58() hex_from_address1 = acct1.get_address_hex() hex_from_address2 = acct2.get_address_hex() from_address_list = [hex_from_address1, hex_from_address2] b58_to_address1 = acct2.get_address_base58() b58_to_address2 = acct3.get_address_base58() hex_to_address1 = acct2.get_address_hex() hex_to_address2 = acct3.get_address_hex() to_address_list = [hex_to_address1, hex_to_address2] value_list = [1.1, 2.2] transfer1 = [b58_from_address1, b58_to_address1, value_list[0]] transfer2 = [b58_from_address2, b58_to_address2, value_list[1]] signers = [acct1, acct2, acct3] args.append(transfer1) args.append(transfer2) gas_limit = 20000000 gas_price = 500 tx_hash = oep4.transfer_multi(args, signers[0], signers, gas_limit, gas_price) self.assertEqual(64, len(tx_hash)) sdk = OntologySdk() sdk.set_rpc(remote_rpc_address) time.sleep(6) try: decimal = oep4.get_decimal() event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash) notify = event['Notify'][:-1] self.assertEqual(len(args), len(notify)) for index in range(len(notify)): self.assertEqual('transfer', bytes.fromhex(notify[index]['States'][0]).decode()) self.assertEqual(from_address_list[index], notify[index]['States'][1]) self.assertEqual(to_address_list[index], notify[index]['States'][2]) array = bytearray(binascii.a2b_hex(notify[index]['States'][3].encode('ascii'))) array.reverse() notify_value = int(binascii.b2a_hex(array).decode('ascii'), 16) self.assertEqual((10 ** decimal) * value_list[index], notify_value) except SDKException as e: raised = False self.assertTrue(raised, e)
def send_transfer(self, asset: str, from_acct: Account, to_addr: str, amount: int, payer: Account, gas_limit: int, gas_price: int): tx = Asset.new_transfer_transaction(asset, from_acct.get_address_base58(), to_addr, amount, payer.get_address_base58(), gas_limit, gas_price) self.__sdk.sign_transaction(tx, from_acct) if from_acct.get_address_base58() != payer.get_address_base58(): self.__sdk.add_sign_transaction(tx, payer) return self.__sdk.rpc.send_raw_transaction(tx)
def send_withdraw_ong_transaction(self, claimer: Account, recv_addr: str, amount: int, payer: Account, gas_limit: int, gas_price: int) -> str: b58_claimer = claimer.get_address_base58() b58_payer = payer.get_address_base58() tx = Asset.new_withdraw_ong_transaction(b58_claimer, recv_addr, amount, b58_payer, gas_limit, gas_price) tx = self.__sdk.sign_transaction(tx, payer) tx = self.__sdk.add_sign_transaction(tx, claimer) res = self.__sdk.rpc.send_raw_transaction_pre_exec(tx) return res
def test_transfer_multi(self): sdk = OntologySdk() sdk.set_rpc(remote_rpc_address) contract_address = '6fe70af535887a820a13cfbaff6b0b505f855e5c' oep4 = sdk.neo_vm().oep4() oep4.set_contract_address(contract_address) private_key1 = '523c5fcf74823831756f0bcb3634234f10b3beb1c05595058534577752ad2d9f' private_key2 = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' private_key3 = '1383ed1fe570b6673351f1a30a66b21204918ef8f673e864769fa2a653401114' acct1 = Account(private_key1, SignatureScheme.SHA256withECDSA) acct2 = Account(private_key2, SignatureScheme.SHA256withECDSA) acct3 = Account(private_key3, SignatureScheme.SHA256withECDSA) args = list() b58_from_address1 = acct1.get_address_base58() b58_from_address2 = acct2.get_address_base58() hex_from_address1 = acct1.get_address_hex() hex_from_address2 = acct2.get_address_hex() from_address_list = [hex_from_address1, hex_from_address2] b58_to_address1 = acct2.get_address_base58() b58_to_address2 = acct3.get_address_base58() hex_to_address1 = acct2.get_address_hex() hex_to_address2 = acct3.get_address_hex() to_address_list = [hex_to_address1, hex_to_address2] value_list = [1, 2] transfer1 = [b58_from_address1, b58_to_address1, value_list[0]] transfer2 = [b58_from_address2, b58_to_address2, value_list[1]] signers = [acct1, acct2, acct3] args.append(transfer1) args.append(transfer2) gas_limit = 20000000 gas_price = 500 tx_hash = oep4.transfer_multi(args, signers[0], signers, gas_limit, gas_price) self.assertEqual(64, len(tx_hash)) sdk = OntologySdk() sdk.set_rpc(remote_rpc_address) time.sleep(6) try: event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash) notify = event['Notify'][:-1] self.assertEqual(len(args), len(notify)) for index in range(len(notify)): self.assertEqual(from_address_list[index], notify[index]['States'][0]) self.assertEqual(to_address_list[index], notify[index]['States'][1]) self.assertEqual(value_list[index], int(notify[index]['States'][2])) except SDKException as e: raised = False self.assertTrue(raised, e)
def test_change_recovery(self): identity = sdk.wallet_manager.create_identity(password) ctrl_acct = sdk.wallet_manager.get_control_account_by_index(identity.ont_id, 0, password) gas_limit = 20000 gas_price = 500 tx_hash = sdk.native_vm.ont_id().registry_ont_id(identity.ont_id, ctrl_acct, acct3, gas_limit, gas_price) self.assertEqual(64, len(tx_hash)) time.sleep(randint(7, 12)) event = sdk.restful.get_smart_contract_event_by_tx_hash(tx_hash) hex_contract_address = sdk.native_vm.ont_id().contract_address notify = ContractEventParser.get_notify_list_by_contract_address(event, hex_contract_address) self.assertEqual(hex_contract_address, notify['ContractAddress']) self.assertEqual('Register', notify['States'][0]) self.assertEqual(identity.ont_id, notify['States'][1]) rand_private_key = utils.get_random_bytes(32).hex() recovery = Account(rand_private_key, SignatureScheme.SHA256withECDSA) b58_recovery_address = recovery.get_address_base58() tx_hash = sdk.native_vm.ont_id().add_recovery(identity.ont_id, ctrl_acct, b58_recovery_address, acct2, gas_limit, gas_price) time.sleep(randint(7, 12)) event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash) notify = ContractEventParser.get_notify_list_by_contract_address(event, hex_contract_address) self.assertEqual(hex_contract_address, notify['ContractAddress']) self.assertEqual('Recovery', notify['States'][0]) self.assertEqual('add', notify['States'][1]) self.assertEqual(identity.ont_id, notify['States'][2]) self.assertEqual(recovery.get_address_hex_reverse(), notify['States'][3]) ddo = sdk.native_vm.ont_id().get_ddo(identity.ont_id) self.assertIn(ctrl_acct.get_ont_id(), ddo['Owners'][0]['PubKeyId']) self.assertEqual('ECDSA', ddo['Owners'][0]['Type']) self.assertEqual('P256', ddo['Owners'][0]['Curve']) self.assertEqual(ctrl_acct.get_public_key_hex(), ddo['Owners'][0]['Value']) self.assertEqual(0, len(ddo['Attributes'])) self.assertEqual(recovery.get_address_base58(), ddo['Recovery']) self.assertEqual(identity.ont_id, ddo['OntId']) rand_private_key = utils.get_random_bytes(32).hex() new_recovery = Account(rand_private_key, SignatureScheme.SHA256withECDSA) b58_new_recovery_address = new_recovery.get_address_base58() try: sdk.native_vm.ont_id().change_recovery(identity.ont_id, b58_new_recovery_address, ctrl_acct, acct2, gas_limit, gas_price) except SDKException as e: self.assertIn('operator is not the recovery', e.args[1]) tx_hash = sdk.native_vm.ont_id().change_recovery(identity.ont_id, b58_new_recovery_address, recovery, acct2, gas_limit, gas_price) time.sleep(randint(7, 12)) event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash) notify = ContractEventParser.get_notify_list_by_contract_address(event, hex_contract_address) self.assertEqual(hex_contract_address, notify['ContractAddress']) self.assertEqual('Recovery', notify['States'][0]) self.assertEqual('change', notify['States'][1]) self.assertEqual(identity.ont_id, notify['States'][2]) self.assertEqual(new_recovery.get_address_hex_reverse(), notify['States'][3])
def change_recovery(self, ont_id: str, b58_new_recovery_address: str, recovery: Account, payer: Account, gas_limit: int, gas_price: int): b58_payer_address = payer.get_address_base58() b58_recovery_address = recovery.get_address_base58() tx = self.new_change_recovery_transaction(ont_id, b58_new_recovery_address, b58_recovery_address, b58_payer_address, gas_limit, gas_price) tx.sign_transaction(recovery) tx.add_sign_transaction(payer) tx_hash = self.__sdk.get_network().send_raw_transaction(tx) return tx_hash
def send_approve(self, asset, sender: Account, recv_addr: str, amount: int, payer: Account, gas_limit: int, gas_price: int) -> str: b58_sender = sender.get_address_base58() b58_payer = payer.get_address_base58() tx = Asset.new_approve(asset, b58_sender, recv_addr, amount, b58_payer, gas_limit, gas_price) tx = self.__sdk.sign_transaction(tx, sender) if sender.get_address_base58() != payer.get_address_base58(): tx = self.__sdk.add_sign_transaction(tx, payer) self.__sdk.rpc.send_raw_transaction(tx) return tx.hash256_explorer()
def send_approve(self, asset, sender: Account, recv_addr: str, amount: int, payer: Account, gas_limit: int, gas_price: int): tx = self.new_approve(asset, sender.get_address_base58(), recv_addr, amount, payer.get_address_base58(), gas_limit, gas_price) tx = self.__sdk.sign_transaction(tx, sender) if sender.get_address_base58() != payer.get_address_base58(): tx = self.__sdk.add_sign_transaction(tx, payer) flag = self.__sdk.rpc.send_raw_transaction(tx) return tx.hash256().hex() if flag else None
def change_max_authorization(self, account: Account, peer_publickey: str, max_authorize: int, payer: Account, gas_limit: int, gas_price: int): contract_address = bytearray.fromhex(self.CONTRACT_ADDRESS) param = {"peer_publickey": peer_publickey, "address": account.get_address().to_array(), "maxAuthorize": max_authorize} invoke_code = build_native_invoke_code(contract_address, bytes([0]), "changeMaxAuthorization", param) unix_time_now = int(time()) tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer.get_address().to_array(), invoke_code, bytearray(), [], bytearray()) self.__sdk.sign_transaction(tx, account) if payer is not None and account.get_address_base58() is not payer.get_address_base58(): self.__sdk.add_sign_transaction(tx, payer) self.__sdk.rpc.send_raw_transaction(tx) return tx.hash256_explorer()
def send_withdraw_ong_transaction(self, claimer: Account, recv_addr: str, amount: int, payer: Account, gas_limit: int, gas_price: int): tx = self.new_withdraw_ong_transaction(claimer.get_address_base58(), recv_addr, amount, payer.get_address_base58(), gas_limit, gas_price) tx = self.__sdk.sign_transaction(tx, payer) tx = self.__sdk.add_sign_transaction(tx, claimer) res = self.__sdk.rpc.send_raw_transaction_preexec(tx) return res
def transfer_from(self, spender_acct: Account, from_acct: Account, b58_to_address: str, value: int, payer_acct: Account, gas_limit: int, gas_price: int): """ This interface is used to call the Allowance method in ope4 that allow spender to withdraw amount of oep4 token from from-account to to-account. :param spender_acct: an Account class that spend the oep4 token. :param from_acct: an Account class that actually pay oep4 token for the spender's spending. :param b58_to_address: a base58 encode address that receive the oep4 token. :param value: the amount of ope4 token in this transaction. :param payer_acct: an Account class that used to pay for the transaction. :param gas_limit: an int value that indicate the gas limit. :param gas_price: an int value that indicate the gas price. :return: the hexadecimal transaction hash value. """ func = self.__abi_info.get_function('TransferFrom') Oep4.__b58_address_check(b58_to_address) if not isinstance(from_acct, Account): raise SDKException( ErrorCode.param_err( 'the data type of from_acct should be Account.')) if not isinstance(spender_acct, Account): raise SDKException( ErrorCode.param_err( 'the data type of spender_acct should be Account.')) spender_address_array = spender_acct.get_address().to_array() from_address_array = from_acct.get_address().to_array() to_address_array = Address.b58decode(b58_to_address).to_array() if not isinstance(value, int): raise SDKException( ErrorCode.param_err('the data type of value should be int.')) params = (spender_address_array, from_address_array, to_address_array, value) func.set_params_value(params) params = BuildParams.serialize_abi_function(func) unix_time_now = int(time.time()) params.append(0x67) for i in self.__contract_address: params.append(i) if payer_acct is None: raise SDKException(ErrorCode.param_err('payer account is None.')) payer_address_array = payer_acct.get_address().to_array() tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer_address_array, params, bytearray(), [], bytearray()) self.__sdk.sign_transaction(tx, payer_acct) if spender_acct.get_address_base58() != payer_acct.get_address_base58( ): self.__sdk.add_sign_transaction(tx, spender_acct) if from_acct.get_address_base58() != payer_acct.get_address_base58(): self.__sdk.add_sign_transaction(tx, payer_acct) tx_hash = self.__sdk.rpc.send_raw_transaction(tx) return tx_hash
def withdraw_fee(self, account: Account, payer: Account, gas_limit: int, gas_price: int): contract_address = bytearray.fromhex(self.CONTRACT_ADDRESS) param = {"address": account.get_address().to_array()} invoke_code = build_native_invoke_code(contract_address, bytes([0]), "withdrawFee", param) unix_time_now = int(time()) tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer.get_address().to_array(), invoke_code, bytearray(), [], bytearray()) self.__sdk.sign_transaction(tx, account) if payer is not None and account.get_address_base58() is not payer.get_address_base58(): self.__sdk.add_sign_transaction(tx, payer) self.__sdk.rpc.send_raw_transaction(tx) return tx.hash256_explorer()
def test_send_raw_transaction(self): private_key = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' acct = Account(a2b_hex(private_key.encode())) private_key2 = get_random_bytes(32) acct2 = Account(private_key2) tx = Asset.new_transfer_transaction("ont", acct.get_address_base58(), acct2.get_address_base58(), 2, acct.get_address_base58(), 20000, 500) tx = sdk.sign_transaction(tx, acct) res = sdk.rpc.send_raw_transaction(tx) self.assertEqual(len(res), 64)
def send_remove_pubkey_by_recovery(self, ont_id: str, recovery: Account, remove_pubkey: str, payer: Account, gas_limit: int, gas_price: int): tx = OntId.new_remove_pubkey_transaction( ont_id, recovery.get_address().to_array(), bytearray.fromhex(remove_pubkey), payer.get_address_base58(), gas_limit, gas_price) self.__sdk.sign_transaction(tx, recovery) if recovery.get_address_base58() != payer.get_address_base58(): self.__sdk.add_sign_transaction(tx, payer) return self.__sdk.rpc.send_raw_transaction(tx)
def test_allowance(self): sdk = OntologySdk() sdk.set_rpc(local_rpc_address) oep4 = sdk.neo_vm().oep4() oep4.set_contract_address(contract_address) private_key1 = "5f2fe68215476abb9852cfa7da31ef00aa1468782d5ca809da5c4e1390b8ee45" private_key2 = "f00dd7f5356e8aee93a049bdccc44ce91169e07ea3bec9f4e0142e456fd39bae" acct1 = Account(private_key1, SignatureScheme.SHA256withECDSA) acct2 = Account(private_key2, SignatureScheme.SHA256withECDSA) b58_owner_address = acct1.get_address_base58() b58_spender_address = acct2.get_address_base58() allowance = oep4.allowance(b58_owner_address, b58_spender_address) self.assertGreaterEqual(allowance, 1)
def test_send_raw_transaction_pre_exec(self): pri_key_1 = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' acct = Account(pri_key_1) pri_key2 = get_random_str(64) acct2 = Account(pri_key2) b58_address_1 = acct.get_address_base58() b58_address_2 = acct2.get_address_base58() tx = Asset.new_transfer_transaction("ont", b58_address_1, b58_address_2, 2, b58_address_1, 20000, 500) tx = sdk.sign_transaction(tx, acct) result = sdk.rpc.send_raw_transaction_pre_exec(tx) self.assertEqual(result, '01')
def test_allowance(self): sdk = OntologySdk() sdk.set_rpc(remote_rpc_address) contract_address = '6fe70af535887a820a13cfbaff6b0b505f855e5c' oep4 = sdk.neo_vm().oep4() oep4.set_contract_address(contract_address) private_key1 = '523c5fcf74823831756f0bcb3634234f10b3beb1c05595058534577752ad2d9f' private_key2 = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' acct1 = Account(private_key1, SignatureScheme.SHA256withECDSA) acct2 = Account(private_key2, SignatureScheme.SHA256withECDSA) b58_owner_address = acct1.get_address_base58() b58_spender_address = acct2.get_address_base58() allowance = oep4.allowance(b58_owner_address, b58_spender_address) self.assertGreaterEqual(allowance, 1)
def test_send_raw_transaction(self): pri_key_1 = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' acct = Account(pri_key_1) length = 64 pri_key_2 = get_random_str(length) acct2 = Account(pri_key_2) b58_address_1 = acct.get_address_base58() b58_address_2 = acct2.get_address_base58() tx = Asset.new_transfer_transaction("ont", b58_address_1, b58_address_2, 2, b58_address_1, 20000, 500) tx = sdk.sign_transaction(tx, acct) tx_hash = sdk.rpc.send_raw_transaction(tx) self.assertEqual(tx_hash, tx.hash256_explorer())
def send_remove_public_key_transaction_by_recovery( self, ont_id: str, recovery: Account, hex_remove_public_key: str, payer: Account, gas_limit: int, gas_price: int): bytes_recovery_address = recovery.get_address().to_array() b58_payer_address = payer.get_address_base58() tx = OntId.new_remove_public_key_transaction(ont_id, bytes_recovery_address, hex_remove_public_key, b58_payer_address, gas_limit, gas_price) self.__sdk.sign_transaction(tx, recovery) if recovery.get_address_base58() != payer.get_address_base58(): self.__sdk.add_sign_transaction(tx, payer) return self.__sdk.rpc.send_raw_transaction(tx)
def send_transfer_from(self, asset: str, sender: Account, from_address: str, recv_address: str, amount: int, payer: Account, gas_limit: int, gas_price: int) -> str: if sender is None or payer is None: raise SDKException(ErrorCode.param_err('parameters should not be null')) if amount <= 0 or gas_price < 0 or gas_limit < 0: raise SDKException(ErrorCode.param_error) b58_payer = payer.get_address_base58() b58_sender = sender.get_address_base58() tx = Asset.new_transfer_from(asset, b58_sender, from_address, recv_address, amount, b58_payer, gas_limit, gas_price) tx = self.__sdk.sign_transaction(tx, sender) if b58_sender != b58_payer: tx = self.__sdk.add_sign_transaction(tx, payer) self.__sdk.rpc.send_raw_transaction(tx) return tx.hash256_explorer()