Example #1
0
 def validate_blk_proof(self, is_big_endian: bool = False) -> bool:
     if self.__blk_proof.get('Type', '') != 'MerkleProof':
         raise SDKException(ErrorCode.invalid_blk_proof)
     try:
         tx_hash = self.__blk_proof['TxnHash']
     except KeyError:
         raise SDKException(ErrorCode.invalid_blk_proof)
     proof_node = self.__blk_proof.get('Nodes', list())
     merkle_root = self.__blk_proof.get('MerkleRoot', '')
     try:
         blk_height = self.__blk_proof['BlockHeight']
     except KeyError:
         raise SDKException(ErrorCode.invalid_blk_proof)
     block = self.__sdk.default_network.get_block_by_height(blk_height)
     tx_list = block.get('Transactions', list())
     tx_exist = False
     for tx in tx_list:
         if tx.get('Hash', '') == tx_hash:
             tx_exist = True
             break
     if not tx_exist:
         return False
     blk_head = block.get('Header', dict())
     target_hash = blk_head.get('TransactionsRoot', '')
     try:
         result = MerkleVerifier.validate_proof(proof_node, target_hash,
                                                merkle_root, is_big_endian)
     except SDKException:
         result = False
     return result
Example #2
0
 def add_multi_sign_transaction(self, m: int, pub_keys: List[bytes]
                                or List[str], signer: Account):
     """
     This interface is used to generate an Transaction object which has multi signature.
     """
     for index, pk in enumerate(pub_keys):
         if isinstance(pk, str):
             pub_keys[index] = pk.encode('ascii')
     pub_keys = ProgramBuilder.sort_public_keys(pub_keys)
     tx_hash = self.hash256()
     sig_data = signer.generate_signature(tx_hash)
     if self.sig_list is None or len(self.sig_list) == 0:
         self.sig_list = []
     elif len(self.sig_list) >= TX_MAX_SIG_SIZE:
         raise SDKException(
             ErrorCode.param_err(
                 'the number of transaction signatures should not be over 16'
             ))
     else:
         for i in range(len(self.sig_list)):
             if self.sig_list[i].public_keys == pub_keys:
                 if len(self.sig_list[i].sig_data) + 1 > len(pub_keys):
                     raise SDKException(
                         ErrorCode.param_err('too more sigData'))
                 if self.sig_list[i].m != m:
                     raise SDKException(ErrorCode.param_err('M error'))
                 self.sig_list[i].sig_data.append(sig_data)
                 return
     sig = Sig(pub_keys, m, [sig_data])
     self.sig_list.append(sig)
Example #3
0
    def get_gcm_decoded_private_key(encrypted_key_str: str, password: str, b58_address: str, salt: str, n: int,
                                    scheme: SignatureScheme) -> str:
        """
        This interface is used to decrypt an private key which has been encrypted.

        :param encrypted_key_str: an gcm encrypted private key in the form of string.
        :param password: the secret pass phrase to generate the keys from.
        :param b58_address: a base58 encode address which should be correspond with the private key.
        :param salt: a string to use for better protection from dictionary attacks.
        :param n: CPU/memory cost parameter.
        :param scheme: the signature scheme.
        :return: a private key in the form of string.
        """
        r = 8
        p = 8
        dk_len = 64
        scrypt = Scrypt(n, r, p, dk_len)
        derived_key = scrypt.generate_kd(password, salt)
        iv = derived_key[0:12]
        key = derived_key[32:64]
        encrypted_key = base64.b64decode(encrypted_key_str).hex()
        mac_tag = bytes.fromhex(encrypted_key[64:96])
        cipher_text = bytes.fromhex(encrypted_key[0:64])
        private_key = AESHandler.aes_gcm_decrypt_with_iv(cipher_text, b58_address.encode(), mac_tag, key, iv)
        if len(private_key) == 0:
            raise SDKException(ErrorCode.decrypt_encrypted_private_key_error)
        acct = Account(private_key, scheme)
        if acct.get_address().b58encode() != b58_address:
            raise SDKException(ErrorCode.other_error('Address error.'))
        return private_key.hex()
Example #4
0
 def controls(self, ctrl_lst: List[Control]):
     if not isinstance(ctrl_lst, list):
         raise SDKException(ErrorCode.require_list_params)
     for ctrl in ctrl_lst:
         if not isinstance(ctrl, Control):
             raise SDKException(ErrorCode.require_control_params)
     self.__controls = ctrl_lst
Example #5
0
 def new_transfer_multi_tx(self, transfer_list: list,
                           payer: Union[str, bytes,
                                        Address], gas_price: int,
                           gas_limit: int) -> InvokeTransaction:
     """
     This interface is used to generate a transaction which can
     transfer amount of token from from-account to to-account multiple times.
     """
     func = NeoInvokeFunction('transferMulti')
     for index, item in enumerate(transfer_list):
         if not isinstance(item[2], int):
             raise SDKException(
                 ErrorCode.param_err(
                     'the data type of value should be int.'))
         if item[2] < 0:
             raise SDKException(
                 ErrorCode.param_err(
                     'the value should be equal or great than 0.'))
         transfer_list[index] = [
             Address.b58decode(item[0]),
             Address.b58decode(item[1]), item[2]
         ]
     for item in transfer_list:
         func.add_params_value(item)
     params = InvokeTransaction.generate_neo_vm_invoke_code(
         self._contract_address, func)
     tx = InvokeTransaction(payer, gas_price, gas_limit, params)
     return tx
Example #6
0
 async def send_neo_vm_transaction(self,
                                   contract_address: str or bytes
                                   or bytearray,
                                   signer: Account or None,
                                   payer: Account or None,
                                   gas_price: int,
                                   gas_limit: int,
                                   func: AbiFunction or NeoInvokeFunction,
                                   is_full: bool = False):
     if isinstance(func, AbiFunction):
         params = BuildParams.serialize_abi_function(func)
     elif isinstance(func, NeoInvokeFunction):
         params = func.create_invoke_code()
     else:
         raise SDKException(
             ErrorCode.other_error('the type of func is error.'))
     contract_address = ensure_bytearray_contract_address(contract_address)
     params.append(0x67)
     for i in contract_address:
         params.append(i)
     if payer is None:
         raise SDKException(ErrorCode.param_err('payer account is None.'))
     tx = Transaction(0, 0xd1, gas_price, gas_limit,
                      payer.get_address_bytes(), params)
     tx.sign_transaction(payer)
     if isinstance(
             signer, Account
     ) and signer.get_address_base58() != payer.get_address_base58():
         tx.add_sign_transaction(signer)
     return await self.send_raw_transaction(tx, is_full)
Example #7
0
 def from_str(str_alg: str):
     if not isinstance(str_alg, str):
         raise SDKException(ErrorCode.require_str_params)
     if str_alg == 'ES224' or str_alg == 'ONT-ES224':
         return ClmAlg.ES224
     elif str_alg == 'ES256' or str_alg == 'ONT-ES256':
         return ClmAlg.ES256
     elif str_alg == 'ES384' or str_alg == 'ONT-ES384':
         return ClmAlg.ES384
     elif str_alg == 'ES512' or str_alg == 'ONT-ES512':
         return ClmAlg.ES512
     elif str_alg == 'ES3-224' or str_alg == 'ONT-ES3-224':
         return ClmAlg.ES3_224
     elif str_alg == 'ES3-256' or str_alg == 'ONT-ES3-256':
         return ClmAlg.ES3_256
     elif str_alg == 'ES3-384' or str_alg == 'ONT-ES3-384':
         return ClmAlg.ES3_384
     elif str_alg == 'ES3-512' or str_alg == 'ONT-ES3-512':
         return ClmAlg.ES3_512
     elif str_alg == 'ER160' or str_alg == 'ONT-ER160':
         return ClmAlg.ER160
     elif str_alg == 'SM' or str_alg == 'ONT-SM':
         return ClmAlg.SM
     elif str_alg == 'EDS512' or str_alg == 'ONT-EDS512':
         return ClmAlg.EDS512
     else:
         raise SDKException(ErrorCode.invalid_claim_alg)
 def add_control_by_hex_private_key(self, ont_id: str, password: str, hex_private_key: str) -> Account:
     WalletManager.__check_ont_id(ont_id)
     if not isinstance(password, str):
         raise SDKException(ErrorCode.require_str_params)
     if not isinstance(hex_private_key, str):
         raise SDKException(ErrorCode.require_str_params)
     return self.__add_control(ont_id, password, hex_private_key)
 def from_claim_alg(alg: str):
     if not isinstance(alg, str):
         raise SDKException(ErrorCode.require_str_params)
     if alg == 'ES224' or alg == 'ONT-ES224':
         return SignatureScheme.SHA224withECDSA
     elif alg == 'ES256' or alg == 'ONT-ES256':
         return SignatureScheme.SHA256withECDSA
     elif alg == 'ES384' or alg == 'ONT-ES384':
         return SignatureScheme.SHA384withECDSA
     elif alg == 'ES512' or alg == 'ONT-ES512':
         return SignatureScheme.SHA512withECDSA
     elif alg == 'ES3-224' or alg == 'ONT-ES3-224':
         return SignatureScheme.SHA3_224withECDSA
     elif alg == 'ES3-256' or alg == 'ONT-ES3-256':
         return SignatureScheme.SHA3_256withECDSA
     elif alg == 'ES3-384' or alg == 'ONT-ES3-384':
         return SignatureScheme.SHA3_384withECDSA
     elif alg == 'ER160' or alg == 'ONT-ER160':
         return SignatureScheme.RIPEMD160withECDSA
     elif alg == 'SM' or alg == 'ONT-SM':
         return SignatureScheme.SM3withSM2
     elif alg == 'EDS512' or alg == 'ONT-EDS512':
         return SignatureScheme.EDDSAwithSHA256
     else:
         raise SDKException(ErrorCode.unknown_asymmetric_key_type)
Example #10
0
 async def connect(self):
     try:
         self.__ws_client = await client.connect(self.__url)
     except ConnectionAbortedError as e:
         raise SDKException(ErrorCode.other_error(e.args[1])) from None
     except socket.gaierror as e:
         raise SDKException(ErrorCode.other_error(e.args[1])) from None
 def validate_proof(proof: List[dict], hex_target_hash: str, hex_merkle_root: str, is_big_endian: bool = False):
     if is_big_endian:
         hex_merkle_root = NeoData.to_reserve_hex_str(hex_merkle_root)
         hex_target_hash = NeoData.to_reserve_hex_str(hex_target_hash)
     if len(proof) == 0:
         return hex_target_hash == hex_merkle_root
     else:
         hex_proof_hash = hex_target_hash
         for node in proof:
             if is_big_endian:
                 sibling = NeoData.to_reserve_hex_str(node['TargetHash'])
             else:
                 sibling = node['TargetHash']
             try:
                 direction = node['Direction'].lower()
             except KeyError:
                 raise SDKException(ErrorCode.other_error('Invalid proof'))
             if direction == 'left':
                 value = bytes.fromhex('01' + sibling + hex_proof_hash)
                 hex_proof_hash = Digest.sha256(value, is_hex=True)
             elif direction == 'right':
                 value = bytes.fromhex('01' + hex_proof_hash + sibling)
                 hex_proof_hash = Digest.sha256(value, is_hex=True)
             else:
                 raise SDKException(ErrorCode.other_error('Invalid proof.'))
         return hex_proof_hash == hex_merkle_root
Example #12
0
 def kid(self, kid: str):
     if not isinstance(kid, str):
         raise SDKException(ErrorCode.invalid_claim_head_params)
     if 'did:ont:' not in kid:
         raise SDKException(ErrorCode.invalid_claim_head_params)
     if '#keys-' not in kid:
         raise SDKException(ErrorCode.invalid_claim_head_params)
     self.__kid = kid
Example #13
0
 def wrapper(*args, **kwargs):
     bound_values = sig.bind(*args, **kwargs)
     ont_id = bound_values.arguments.get('ont_id')
     if not isinstance(ont_id, str):
         raise SDKException(ErrorCode.require_str_params)
     if not ont_id.startswith(DID_ONT):
         raise SDKException(ErrorCode.invalid_ont_id_format(ont_id))
     return func(*args, **kwargs)
Example #14
0
 def __init__(self, script_hash: Union[bytes, bytearray]):
     if not isinstance(script_hash, bytes):
         try:
             script_hash = bytes(script_hash)
         except TypeError:
             raise SDKException(ErrorCode.other_error('Invalid script hash.'))
     if len(script_hash) != 20:
         raise SDKException(ErrorCode.other_error('Invalid script hash.'))
     self.ZERO = script_hash
Example #15
0
 def from_str_type(str_type: str):
     if not isinstance(str_type, str):
         raise SDKException(ErrorCode.require_str_params)
     if str_type == 'JWT':
         return ClmType.raw_claim
     elif str_type == 'JWT-X':
         return ClmType.witness_claim
     else:
         raise SDKException(ErrorCode.invalid_claim_type)
 def get_account_data_by_b58_address(self, b58_address: str) -> AccountData:
     if not isinstance(b58_address, str):
         raise SDKException(ErrorCode.require_str_params)
     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.b58_address == b58_address:
             return acct
     raise SDKException(ErrorCode.other_error(f'Get account {b58_address} failed.'))
Example #17
0
    def test_sdk_exception(self):
        try:
            raise SDKException(ErrorCode.param_error)
        except SDKException as e:
            self.assertEqual('param error', e.args[1])

        try:
            raise SDKException(ErrorCode.asset_name_error)
        except SDKException as e:
            self.assertEqual('OntAsset Error, asset name error', e.args[1])
Example #18
0
 async def get_memory_pool_tx_state(self, tx_hash: str, is_full: bool = False):
     payload = self.generate_json_rpc_payload(RpcMethod.GET_MEM_POOL_TX_STATE, [tx_hash])
     response = await self.__post(payload)
     if response.get('result', '') == '':
         raise SDKException(ErrorCode.invalid_tx_hash(tx_hash))
     if response.get('error', -1) != 0:
         raise SDKException(ErrorCode.other_error(response.get('result', '')))
     if is_full:
         return response
     return response['result']['State']
Example #19
0
 def compare_pubkey(pub_key: bytes):
     if not isinstance(pub_key, bytes):
         raise SDKException(ErrorCode.other_error('Invalid key.'))
     if KeyType.from_pubkey(pub_key) == KeyType.SM2:
         raise SDKException(ErrorCode.other_error('Unsupported key type'))
     elif KeyType.from_pubkey(pub_key) == KeyType.ECDSA:
         x = pub_key[1:]
         return util.string_to_number(x)
     else:
         return str(pub_key)
 def create_wallet_file(self, wallet_path: str = ''):
     if not isinstance(wallet_path, str):
         raise SDKException(ErrorCode.require_str_params)
     if wallet_path != '':
         self.__wallet_path = wallet_path
     if not path.isfile(self.__wallet_path):
         self.wallet_in_mem.create_time = datetime.today().strftime("%Y-%m-%d %H:%M:%S")
         self.save()
     else:
         raise SDKException(ErrorCode.other_error('Wallet file has existed.'))
Example #21
0
 def from_json(self, json_blk_proof: str, is_big_endian: bool = False):
     if not isinstance(json_blk_proof, str):
         raise SDKException(ErrorCode.require_str_params)
     try:
         dict_blk_proof = json.loads(json_blk_proof)
     except json.decoder.JSONDecodeError:
         raise SDKException(ErrorCode.invalid_b64_claim_data)
     proof = BlockchainProof(self.__sdk)
     proof.proof = dict_blk_proof, is_big_endian
     return proof
 def get_control_info_by_index(self, ont_id: str, index: int) -> Control:
     if not isinstance(ont_id, str):
         raise SDKException(ErrorCode.require_str_params)
     if not ont_id.startswith(DID_ONT):
         raise SDKException(ErrorCode.invalid_ont_id_format(ont_id))
     identity = self.get_identity_by_ont_id(ont_id)
     try:
         ctrl = identity.controls[index]
     except IndexError:
         raise SDKException(ErrorCode.other_error(f'Get {ont_id}\'s control account failed.'))
     return ctrl
Example #23
0
 def from_json(json_head: str):
     if not isinstance(json_head, str):
         raise SDKException(ErrorCode.require_str_params)
     dict_head = json.loads(json_head)
     try:
         alg = ClmAlg.from_str(dict_head['alg'])
         typ = ClmType.from_str_type(dict_head['typ'])
         head = Header(dict_head['kid'], alg, typ)
     except KeyError:
         raise SDKException(ErrorCode.invalid_b64_claim_data)
     return head
Example #24
0
 def from_str_type(str_type: str):
     if not isinstance(str_type, str):
         raise SDKException(ErrorCode.require_str_params)
     if str_type == 'ECDSA':
         return KeyType.ECDSA
     elif str_type == 'SM2':
         return KeyType.SM2
     elif str_type == 'EDDSA':
         return KeyType.ECDSA
     else:
         raise SDKException(ErrorCode.unknown_asymmetric_key_type)
Example #25
0
 def __init__(self, key, chain_code: bytes, index: int, depth: int, parent_fingerprint: bytes):
     if index < 0 or index > MAX_INDEX:
         raise SDKException(ErrorCode.hd_index_out_of_range)
     if not isinstance(chain_code, bytes):
         raise SDKException(ErrorCode.require_bytes_params)
     if depth == 0:
         parent_fingerprint = MASTER_KEY_FINGERPRINT
     self._key = key
     self._chain_code = chain_code
     self._depth = depth
     self._index = index
     self._parent_fingerprint = to_bytes(parent_fingerprint)
Example #26
0
 def get_public_key_by_hex_private_key(private_key: str):
     if not isinstance(private_key, str):
         raise SDKException(
             ErrorCode.other_error(
                 'The type of private key should be hexadecimal str.'))
     if len(private_key) != 64:
         raise SDKException(
             ErrorCode.other_error(
                 'The length of private key should be 64 bytes.'))
     private_key = bytes.fromhex(private_key)
     point_str = ECIES.get_public_key_by_bytes_private_key(private_key)
     return point_str.hex()
    def get_default_account_data(self) -> AccountData:
        """
        This interface is used to get the default account in WalletManager.

        :return: an AccountData object that contain all the information of a default account.
        """
        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.is_default:
                return acct
        raise SDKException(ErrorCode.get_default_account_err)
 def open_wallet(self, wallet_path: str = '', is_create: bool = True):
     if not isinstance(wallet_path, str):
         raise SDKException(ErrorCode.require_str_params)
     if wallet_path != '':
         self.__wallet_path = wallet_path
     if is_create and not path.isfile(self.__wallet_path):
         self.create_wallet_file()
     if not path.isfile(self.__wallet_path):
         raise SDKException(ErrorCode.invalid_wallet_path(self.__wallet_path))
     self.wallet_file = self.load_file()
     self.wallet_in_mem = copy.deepcopy(self.wallet_file)
     return self.wallet_file
Example #29
0
 def to_int(hex_str: str) -> int:
     if len(hex_str) == 0:
         return 0
     try:
         array = bytearray.fromhex(hex_str)
     except ValueError as e:
         raise SDKException(ErrorCode.other_error(e.args[0]))
     array.reverse()
     try:
         num = int(bytearray.hex(array), 16)
     except ValueError as e:
         raise SDKException(ErrorCode.other_error(e.args[0]))
     return num
Example #30
0
 def __init__(self, ont_id: str = '', label: str = '', lock: bool = False, controls: List[Control] = None,
              is_default=False):
     if controls is None:
         controls = list()
     if not isinstance(ont_id, str):
         raise SDKException(ErrorCode.require_str_params)
     if len(ont_id) != 0 and not ont_id.startswith(DID_ONT):
         raise SDKException(ErrorCode.invalid_ont_id_format(ont_id))
     self.__ont_id = ont_id
     self.label = label
     self.lock = lock
     self.__controls = controls
     self.is_default = is_default