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 __create_account(self, label: str, pwd: str, salt: str, priv_key: str, account_flag: bool): print(priv_key) account = Account(priv_key, self.scheme) # initialization if self.scheme == SignatureScheme.SHA256withECDSA: acct = AccountData() else: raise ValueError("scheme type is error") # set key if pwd is not None: acct.key = account.export_gcm_encrypted_private_key(pwd, salt, Scrypt().get_n()) else: acct.key = account.serialize_private_key().hex() acct.address = account.get_address_base58() # set label if label is None or label == "": label = str(uuid.uuid4())[0:8] if account_flag: for index in range(len(self.wallet_in_mem.accounts)): if acct.address == self.wallet_in_mem.accounts[index].address: raise ValueError("wallet account exists") if len(self.wallet_in_mem.accounts) == 0: acct.isDefault = True self.wallet_in_mem.defaultAccountAddress = acct.address acct.label = label acct.salt = base64.b64encode(salt.encode()).decode('ascii') acct.publicKey = account.serialize_public_key().hex() self.wallet_in_mem.accounts.append(acct) else: for index in range(len(self.wallet_in_mem.identities)): if self.wallet_in_mem.identities[index].ont_id == did_ont + acct.address: raise ValueError("wallet identity exists") idt = Identity() idt.ontid = did_ont + acct.address idt.label = label if len(self.wallet_in_mem.identities) == 0: idt.isDefault = True self.wallet_in_mem.defaultOntid = idt.ontid ctl = Control(id="keys-1", key=acct.key, salt=base64.b64encode(salt.encode()).decode('ascii'), address=acct.address, public_key=account.serialize_public_key().hex()) idt.controls.append(ctl) self.wallet_in_mem.identities.append(idt) return account
def __create_account(self, label: str, pwd: str, salt: str, private_key: str, account_flag: bool) -> Account: account = Account(private_key, self.scheme) if self.scheme == SignatureScheme.SHA256withECDSA: acct_data = AccountData() else: raise SDKException(ErrorCode.other_error('Scheme type is error.')) if pwd is not None: acct_data.key = account.export_gcm_encrypted_private_key(pwd, salt) else: acct_data.key = account.get_private_key_hex() acct_data.b58_address = account.get_address_base58() # set label if label is None or label == '': label = uuid.uuid4().hex[0:8] if account_flag: for memory_acct in self.wallet_in_mem.accounts: if memory_acct.b58_address == account.get_address_base58(): raise SDKException(ErrorCode.other_error('Wallet account exists.')) if len(self.wallet_in_mem.accounts) == 0: acct_data.is_default = True self.wallet_in_mem.default_account_address = acct_data.b58_address acct_data.label = label acct_data.salt = base64.b64encode(salt.encode('latin-1')).decode('ascii') acct_data.public_key = account.get_public_key_hex() self.wallet_in_mem.accounts.append(acct_data) else: for identity in self.wallet_in_mem.identities: if identity.ont_id == DID_ONT + acct_data.b58_address: raise SDKException(ErrorCode.other_error('Wallet identity exists.')) idt = Identity() idt.ont_id = DID_ONT + acct_data.b58_address idt.label = label if len(self.wallet_in_mem.identities) == 0: idt.is_default = True self.wallet_in_mem.default_ont_id = idt.ont_id ctl = Control(kid='keys-1', key=acct_data.key, salt=base64.b64encode(salt.encode()).decode('ascii'), address=acct_data.b58_address, public_key=account.get_public_key_hex()) idt.controls.append(ctl) self.wallet_in_mem.identities.append(idt) return account
def test_send_registry(self): ont_id = sdk.native_vm().ont_id() private_key = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' acct = Account(private_key, SignatureScheme.SHA256withECDSA) label = 'label' password = '******' identity = sdk.wallet_manager.create_identity_from_private_key( label, password, private_key) gas_limit = 20000 gas_price = 500 try: ont_id.send_registry_ont_id_transaction(identity, password, acct, gas_limit, gas_price) except SDKException as e: self.assertEqual(59000, e.args[0]) msg = 'Other Error, [NeoVmService] service system call error!: [SystemCall] ' \ 'service execute error!: [Invoke] Native serivce function execute error!: ' \ 'register ONT ID error: already registered' self.assertEqual(msg, e.args[1])
def import_identity(self, label: str, encrypted_pri_key: str, pwd: str, salt: str, b58_address: str) -> Identity: """ This interface is used to import identity by providing encrypted private key, password, salt and base58 encode address which should be correspond to the encrypted private key provided. :param label: a label for identity. :param encrypted_pri_key: an encrypted private key in base64 encoding from. :param pwd: a password which is used to encrypt and decrypt the private key. :param salt: a salt value which will be used in the process of encrypt private key. :param b58_address: a base58 encode address which correspond with the encrypted private key provided. :return: if succeed, an Identity object will be returned. """ scrypt_n = Scrypt().n pri_key = Account.get_gcm_decoded_private_key(encrypted_pri_key, pwd, b58_address, salt, scrypt_n, self.scheme) info = self.__create_identity(label, pwd, salt, pri_key) for identity in self.wallet_in_mem.identities: if identity.ont_id == info.ont_id: return identity raise SDKException(ErrorCode.other_error('Import identity failed.'))
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 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_verify_signature(self): identity = sdk.wallet_manager.create_identity(password) ctrl_acct = sdk.wallet_manager.get_control_account_by_index( identity.ont_id, 0, password) ont_id = sdk.native_vm.ont_id() tx_hash = ont_id.registry_ont_id(identity.ont_id, ctrl_acct, acct3, self.gas_price, self.gas_limit) self.assertEqual(64, len(tx_hash)) time.sleep(randint(10, 15)) event = sdk.default_network.get_contract_event_by_tx_hash(tx_hash) hex_contract_address = ont_id.contract_address notify = Event.get_notify_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]) private_key = utils.get_random_bytes(32) public_key = Signature.ec_get_public_key_by_private_key( private_key, Curve.P256) new_ctrl_acct = Account(private_key) hex_new_public_key = public_key.hex() tx_hash = ont_id.add_public_key(identity.ont_id, ctrl_acct, hex_new_public_key, acct4, self.gas_price, self.gas_limit) time.sleep(randint(10, 15)) event = sdk.default_network.get_contract_event_by_tx_hash(tx_hash) notify = Event.get_notify_by_contract_address(event, hex_contract_address) self.assertIn('PublicKey', notify['States']) self.assertIn('add', notify['States']) self.assertIn(identity.ont_id, notify['States']) self.assertIn(hex_new_public_key, notify['States']) result = ont_id.verify_signature(identity.ont_id, 1, ctrl_acct) self.assertTrue(result) result = ont_id.verify_signature(identity.ont_id, 2, ctrl_acct) self.assertFalse(result) result = ont_id.verify_signature(identity.ont_id, 1, new_ctrl_acct) self.assertFalse(result) result = ont_id.verify_signature(identity.ont_id, 2, new_ctrl_acct) self.assertTrue(result)
def test_signature(self): for strength in self.strengths: master_key = HDPrivateKey.master_key_from_mnemonic( self.mnemonic.generate(strength)) acct = Account(master_key.hex()) signature = acct.generate_signature(self.msg) self.assertTrue(acct.verify_signature(self.msg, signature)) root_sk = HDPrivateKey.from_path(master_key)[-1] root_pk = root_sk.public_key bip32_root_pk = root_pk.b58encode() for index in range(10): child_sk = HDPrivateKey.from_path(root_sk, f'0/{index}')[-1] child_pk = HDPublicKey.from_path( HDPublicKey.b58decode(bip32_root_pk), f'0/{index}')[-1] child_acct = Account(child_sk.hex()) signature = child_acct.generate_signature(self.msg) handler = SignatureHandler(SignatureScheme.SHA256withECDSA) handler.verify_signature(child_pk.hex(), self.msg, signature)
def send_transfer(self, admin_identity: Identity, password: str, key_no: int, contract_address: str, new_admin_ont_id, payer: Account, gas_limit: int, gas_price: int): if admin_identity is None or password is None or password == '' or contract_address is None or contract_address == '' or new_admin_ont_id is None or new_admin_ont_id == '' or payer is None: raise SDKException( ErrorCode.param_err("parameter should not be None")) if key_no < 0 or gas_limit < 0 or gas_price < 0: raise SDKException( ErrorCode.param_err( 'key_no or gas_limit or gas_price should not less than 0')) tx = self.make_transfer(contract_address, new_admin_ont_id, key_no, payer, gas_limit, gas_price) account = self.__sdk.wallet_manager.get_account( admin_identity.ont_id, password) 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_add_attributes(self): ont_id = sdk.native_vm().ont_id() attribute = {'key': 'try', 'type': 'string', 'value': 'attribute'} attribute_list = [attribute] private_key = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' acct = Account(private_key, SignatureScheme.SHA256withECDSA) password = '******' identity = sdk.wallet_manager.create_identity_from_private_key( 'label', password, private_key) gas_limit = 20000 gas_price = 500 tx_hash = ont_id.send_add_attribute_transaction( identity, password, attribute_list, acct, gas_limit, gas_price) time.sleep(6) notify = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash)['Notify'] self.assertEqual('Attribute', notify[0]['States'][0]) self.assertEqual('add', notify[0]['States'][1]) self.assertEqual(identity.ont_id, notify[0]['States'][2]) self.assertEqual('try', bytes.fromhex(notify[0]['States'][3][0]).decode())
def assign_ont_ids_to_role(self, admin_identity: Identity, password: str, key_no: int, contract_address: str, role: str, ont_ids: list, payer: Account, gas_limit: int, gas_price: int): contract_address = bytearray.fromhex(contract_address) param = {"contract_address": contract_address, "ontid": admin_identity.ont_id.encode('utf-8'), "role": role.encode('utf-8')} param['length'] = len(ont_ids) for i in range(len(ont_ids)): param['name' + str(i)] = ont_ids[i] param['key_no'] = key_no invoke_code = build_native_invoke_code(bytearray.fromhex(self.contract_address), b'\x00', "assignOntIDsToRole", 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(), []) account = self.__sdk.wallet_manager.get_account_by_ont_id(admin_identity.ont_id, password) tx.sign_transaction(account) tx.add_sign_transaction(payer) res = self.__sdk.get_network().send_raw_transaction(tx) return res
def send_registry_ont_id_transaction(self, identity: Identity, password: str, payer: Account, gas_limit: int, gas_price: int): """ This interface is used to send a Transaction object which is used to registry ontid. :param identity: an Identity object. :param password: a password which is used to decrypt the encrypted private key. :param payer: an Account object which indicate who will 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: a hexadecimal transaction hash value. """ tx = OntId.new_registry_ont_id_transaction( identity.ont_id, identity.controls[0].public_key, payer.get_address_base58(), gas_limit, gas_price) account = self.__sdk.wallet_manager.get_account( identity.ont_id, password) self.__sdk.sign_transaction(tx, account) self.__sdk.add_sign_transaction(tx, payer) return self.__sdk.rpc.send_raw_transaction(tx)
def test_transfer_from(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' spender_acct = Account(private_key2, SignatureScheme.SHA256withECDSA) from_acct = Account(private_key1, SignatureScheme.SHA256withECDSA) hex_from_address = from_acct.get_address_hex() to_acct = Account(private_key3, SignatureScheme.SHA256withECDSA) hex_to_address = to_acct.get_address_hex() b58_to_address = to_acct.get_address_base58() gas_limit = 20000000 gas_price = 500 value = 1 tx_hash = oep4.transfer_from(spender_acct, from_acct, b58_to_address, value, from_acct, 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'][0] self.assertEqual(2, len(notify)) self.assertEqual(hex_from_address, notify['States'][0]) self.assertEqual(hex_to_address, notify['States'][1]) self.assertEqual('01', notify['States'][2]) except SDKException as e: raised = False self.assertTrue(raised, e)
def get_item_list_from_contract(identity_acct: Account) -> list: get_item_list_func = InvokeFunction('get_item_list') get_item_list_func.set_params_value(identity_acct.get_address()) contract_address_bytearray = app.config['CONTRACT_ADDRESS_BYTEARRAY'] response = app.config['ONTOLOGY'].rpc.send_neo_vm_tx_pre_exec(contract_address_bytearray, get_item_list_func) item_list = list() if isinstance(response, dict): item_list = response.get('Result') if item_list is None: item_list = list() if item_list is None or None in item_list: return list() album_list = list() for item in item_list: encrypted_ipfs_address_bytes = binascii.a2b_hex(item[0]) ext = binascii.a2b_hex(item[1]).decode('ascii') aes_iv = binascii.a2b_hex(item[2]) encode_g_tilde = binascii.a2b_hex(item[3]) ipfs_address = ECIES.decrypt_with_ont_id_in_cbc(aes_iv, encode_g_tilde, encrypted_ipfs_address_bytes, identity_acct) album_list.append([ipfs_address.decode('ascii'), ext]) return album_list
def import_account(self, label: str, encrypted_pri_key: str, pwd: str, base58_address: str, base64_salt: str) -> AccountData or None: """ This interface is used to import account by providing account data. :param label: str, wallet label :param encrypted_pri_key: str, an encrypted private key in base64 encoding from :param pwd: str, a password which is used to encrypt and decrypt the private key :param base58_address: str, a base58 encode wallet address value :param base64_salt: str, a base64 encode salt value which is used in the encryption of private key :return: if succeed, return an data structure which contain the information of a wallet account. if failed, return a None object. """ salt = base64.b64decode(base64_salt.encode('ascii')).decode('latin-1') private_key = Account.get_gcm_decoded_private_key(encrypted_pri_key, pwd, base58_address, salt, Scrypt().get_n(), self.scheme) info = self.create_account_info(label, pwd, salt, private_key) for index in range(len(self.wallet_in_mem.accounts)): if info.address_base58 == self.wallet_in_mem.accounts[index].address: return self.wallet_in_mem.accounts[index] return None
def test_transfer_from(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" spender_acct = Account(private_key2, SignatureScheme.SHA256withECDSA) from_acct = Account(private_key1, SignatureScheme.SHA256withECDSA) hex_from_address = from_acct.get_address_hex() to_acct = Account(private_key3, SignatureScheme.SHA256withECDSA) hex_to_address = to_acct.get_address_hex() b58_to_address = to_acct.get_address_base58() gas_limit = 20000000 gas_price = 0 value = 1 tx_hash = oep4.transfer_from(spender_acct, from_acct, b58_to_address, value, from_acct, gas_limit, gas_price) self.assertEqual(64, len(tx_hash)) sdk = OntologySdk() sdk.set_rpc(local_rpc_address) time.sleep(6) try: event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash) notify = event['Notify'][0] self.assertEqual(2, len(notify)) self.assertEqual(hex_from_address, notify['States'][1]) self.assertEqual(hex_to_address, notify['States'][2]) self.assertEqual('01', notify['States'][3]) except SDKException as e: raised = False self.assertTrue(raised, e)
def transfer(self, from_acct: Account, b58_to_address: str, value: int, payer_acct: Account, gas_limit: int, gas_price: int) -> str: """ This interface is used to call the Transfer method in ope4 that transfer an amount of tokens from one account to another account. :param from_acct: an Account class that send the oep4 token. :param b58_to_address: a base58 encode address that receive the oep4 token. :param value: an int value that indicate the amount oep4 token that will be transferred 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('transfer') if not isinstance(value, int) or isinstance(value, float): raise SDKException( ErrorCode.param_err( 'the data type of value should be number.')) if value < 0: raise SDKException( ErrorCode.param_err( 'the value should be equal or great than 0.')) if not isinstance(from_acct, Account): raise SDKException( ErrorCode.param_err( 'the data type of from_acct should be Account.')) Oep4.__b58_address_check(b58_to_address) from_address = from_acct.get_address().to_array() to_address = Address.b58decode(b58_to_address).to_array() value = self.__to_int_according_to_decimal(value) params = (from_address, to_address, value) func.set_params_value(params) tx_hash = self.__sdk.neo_vm().send_transaction(self.__contract_address, from_acct, payer_acct, gas_limit, gas_price, func, False) return tx_hash
async def test_verify_signature(self): identity = sdk.wallet_manager.create_identity(password) ctrl_acct = sdk.wallet_manager.get_control_account_by_index(identity.ont_id, 0, password) tx_hash = await sdk.native_vm.aio_ont_id().registry_ont_id(identity.ont_id, ctrl_acct, acct3, self.gas_price, self.gas_limit) await self.check_register_ont_id_event(identity.ont_id, tx_hash) private_key = utils.get_random_bytes(32) public_key = Signature.ec_get_public_key_by_private_key(private_key, Curve.P256) new_ctrl_acct = Account(private_key) hex_new_public_key = public_key.hex() tx_hash = await sdk.native_vm.aio_ont_id().add_public_key(identity.ont_id, ctrl_acct, hex_new_public_key, acct4, self.gas_price, self.gas_limit) await self.check_add_pk_event(identity.ont_id, tx_hash, hex_new_public_key) result = await sdk.native_vm.aio_ont_id().verify_signature(identity.ont_id, 1, ctrl_acct) self.assertTrue(result) result = await sdk.native_vm.aio_ont_id().verify_signature(identity.ont_id, 2, ctrl_acct) self.assertFalse(result) result = await sdk.native_vm.aio_ont_id().verify_signature(identity.ont_id, 1, new_ctrl_acct) self.assertFalse(result) result = await sdk.native_vm.aio_ont_id().verify_signature(identity.ont_id, 2, new_ctrl_acct) self.assertTrue(result)
def import_account(self, label: str, encrypted_pri_key: str, pwd: str, b58_address: str, b64_salt: str, n: int = 16384) -> AccountData: """ This interface is used to import account by providing account data. :param label: str, wallet label :param encrypted_pri_key: str, an encrypted private key in base64 encoding from :param pwd: str, a password which is used to encrypt and decrypt the private key :param b58_address: str, a base58 encode wallet address value :param b64_salt: str, a base64 encode salt value which is used in the encryption of private key :param n: int, CPU/Memory cost parameter. It must be a power of 2 and less than :math:`2^{32}` :return: if succeed, return an data structure which contain the information of a wallet account. if failed, return a None object. """ salt = base64.b64decode(b64_salt.encode('ascii')).decode('latin-1') private_key = Account.get_gcm_decoded_private_key(encrypted_pri_key, pwd, b58_address, salt, n, self.scheme) acct_info = self.create_account_info(label, pwd, salt, private_key) for acct in self.wallet_in_mem.accounts: if not isinstance(acct, AccountData): raise SDKException(ErrorCode.other_error('Invalid account data in memory.')) if acct_info.address_base58 == acct.b58_address: return acct raise SDKException(ErrorCode.other_error('Import account failed.'))
def test_remove_attribute(self): ont_id = sdk.native_vm().ont_id() label = 'label' password = '******' private_key = '75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf' acct = Account(private_key, SignatureScheme.SHA256withECDSA) identity = sdk.wallet_manager.create_identity_from_private_key(label, password, private_key) gas_limit = 20000 gas_price = 500 path = 'try' try: tx_hash = ont_id.send_remove_attribute_transaction(identity, password, path, acct, gas_limit, gas_price) time.sleep(6) notify = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash)['Notify'] self.assertEqual('Attribute', notify[0]['States'][0]) self.assertEqual('remove', notify[0]['States'][1]) self.assertEqual(identity.ont_id, notify[0]['States'][2]) self.assertEqual('try', bytes.fromhex(notify[0]['States'][3]).decode()) except SDKException as e: msg = 'Other Error, [NeoVmService] service system call error!: ' \ '[SystemCall] service execute error!: [Invoke] Native serivce function execute error!: ' \ 'remove attribute failed: attribute not exist' self.assertEqual(59000, e.args[0]) self.assertEqual(msg, e.args[1])
def withdraw(self, initiator_identity: Identity, password: str, key_no: int, contract_address: str, delegate: str, role: str, payer: Account, gas_limit: int, gas_price: int): contract_address = bytearray.fromhex(contract_address) param = { "contract_address": contract_address, "ont_id": initiator_identity.ont_id.encode('utf-8'), "delegate": delegate.encode('utf-8'), "role": role.encode('utf-8'), "key_no": key_no } invoke_code = build_native_invoke_code( bytearray.fromhex(self.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()) account = self.__sdk.wallet_manager.get_account( initiator_identity.ont_id, password) self.__sdk.sign_transaction(tx, account) self.__sdk.add_sign_transaction(tx, payer) res = self.__sdk.rpc.send_raw_transaction(tx) return res
def approve(self, owner_acct: Account, b58_spender_address: str, amount: int, payer_acct: Account, gas_limit: int, gas_price: int): """ This interface is used to call the Approve method in ope4 that allows spender to withdraw a certain amount of oep4 token from owner account multiple times. If this function is called again, it will overwrite the current allowance with new value. :param owner_acct: an Account class that indicate the owner. :param b58_spender_address: a base58 encode address that be allowed to spend the oep4 token in owner's account. :param amount: an int value that indicate the amount oep4 token that will be transferred 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('approve') if not isinstance(amount, int): raise SDKException( ErrorCode.param_err('the data type of amount should be int.')) if amount < 0: raise SDKException( ErrorCode.param_err( 'the amount should be equal or great than 0.')) owner_address = owner_acct.get_address().to_array() Oep4.__b58_address_check(b58_spender_address) spender_address = Address.b58decode(b58_spender_address).to_array() amount = self.__to_int_according_to_decimal(amount) params = (owner_address, spender_address, amount) func.set_params_value(params) tx_hash = self.__sdk.neo_vm().send_transaction(self.__contract_address, owner_acct, payer_acct, gas_limit, gas_price, func, False) return tx_hash
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 test_approve(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' owner_acct = Account(private_key1, SignatureScheme.SHA256withECDSA) hex_owner_address = owner_acct.get_address_hex() spender = Account(private_key2, SignatureScheme.SHA256withECDSA) b58_spender_address = spender.get_address_base58() hex_spender_address = spender.get_address_hex() amount = 100 gas_limit = 20000000 gas_price = 500 tx_hash = oep4.approve(owner_acct, b58_spender_address, amount, owner_acct, gas_limit, gas_price) self.assertEqual(len(tx_hash), 64) 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'][0] states = notify['States'] self.assertEqual('approval', bytes.fromhex(states[0]).decode()) self.assertEqual(hex_owner_address, states[1]) self.assertEqual(hex_spender_address, states[2]) array = bytearray(binascii.a2b_hex(states[3].encode('ascii'))) array.reverse() notify_value = int(binascii.b2a_hex(array).decode('ascii'), 16) self.assertEqual((10 ** decimal) * amount, notify_value) except SDKException as e: raised = False self.assertTrue(raised, e)
import unittest from ontology.account.account import Account from ontology.crypto.signature_handler import SignatureHandler from ontology.crypto.key_type import KeyType from ontology.crypto.signature_scheme import SignatureScheme from ontology.ont_sdk import OntologySdk acc = Account( "75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf") sdk = OntologySdk() class TestSignatureHandler(unittest.TestCase): def test_signature_data(self): sig = sdk.signature_data(acc, "sss".encode()) self.assertTrue( sdk.verify_signature(acc.serialize_public_key(), "sss".encode(), sig)) def testTx(self): tx = sdk.native_vm().asset().new_transfer_transaction( "ont", acc.get_address_base58(), acc.get_address_base58(), 10, acc.get_address_base58(), 20000, 0) sdk.add_sign_transaction(tx, acc) self.assertTrue( sdk.verify_signature(tx.sigs[0].public_keys[0], tx.hash256_bytes(), tx.sigs[0].sig_data[0])) def test_generateSignature(self):
def test_generate_signature(self): raw_hex_data = "523c5fcf74823831756f0bcb3634234f10b3beb1c05595058534577752ad2d9f" account = Account(raw_hex_data, SignatureScheme.SHA256withECDSA) data = account.generate_signature(bytes("test".encode()), SignatureScheme.SHA256withECDSA)
key = self.wallet_in_mem.identities[index].controls[0].key salt = base64.b64decode( self.wallet_in_mem.identities[index].controls[0].salt) private_key = Account.get_gcm_decoded_private_key( key, pwd, addr, salt, Scrypt().get_n(), self.scheme) return Account(private_key, self.scheme) return None if __name__ == '__main__': # test wallet load and save private_key = '99bbd375c745088b372c6fc2ab38e2fb6626bc552a9da47fc3d76baa21537a1c' private_key = a2b_hex(private_key.encode()) scheme = SignatureScheme.SHA256withECDSA acct0 = Account(private_key, scheme) encrypted_key = 'T3uep1USsEqiJbP4O+CKsl2AWfpGjvuVSKxpoKeGdEUa0nfLHHjIq3G4xOz7a4PC' wallet_path = 'test.json' w = WalletManager() w.open_wallet(wallet_path) salt = get_random_bytes(16) # w.import_account("123", encrypted_key, '234', acct0.get_address_base58(), salt) if False: w.create_random_account("label", "1") w.create_random_identity("label-ontid", "1") w.create_account_from_prikey("label123", "1", private_key) w.create_identity_from_prikey("label123-ontid", "1", private_key) if True: acctTmp = w.get_account("AMJYVc3vHK7vZ3XfFXsBP9r9sGN1cYYeQN", "1") print(acctTmp.get_address_base58()) print(w.wallet_in_mem.accounts[0].__dict__)
import unittest from ontology.ont_sdk import OntologySdk from ontology.common.address import Address from ontology.account.account import Account from ontology.utils.util import get_random_str from ontology.crypto.signature_scheme import SignatureScheme from ontology.smart_contract.native_contract.asset import Asset sdk = OntologySdk() rpc_address = "http://polaris3.ont.io:20336" sdk.rpc.set_address(rpc_address) private_key = "523c5fcf74823831756f0bcb3634234f10b3beb1c05595058534577752ad2d9f" private_key2 = "75de8489fcb2dcaf2ef3cd607feffde18789de7da129b5e97c81e001793cb7cf" private_key3 = "1383ed1fe570b6673351f1a30a66b21204918ef8f673e864769fa2a653401114" acc = Account(private_key, SignatureScheme.SHA256withECDSA) acc2 = Account(private_key2, SignatureScheme.SHA256withECDSA) acc3 = Account(private_key3, SignatureScheme.SHA256withECDSA) pubkeys = [acc.get_public_key(), acc2.get_public_key(), acc3.get_public_key()] multi_addr = Address.address_from_multi_pub_keys(2, pubkeys) class TestRpcClient(unittest.TestCase): def test_get_version(self): version = sdk.rpc.get_version() self.assertEqual("v1.0.3-rc", version) def test_get_node_count(self): count = sdk.rpc.get_node_count() self.assertGreaterEqual(count, 0)