Пример #1
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
Пример #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)
Пример #3
0
 async def get_contract(self, hex_contract_address: str, is_full: bool = False) -> dict:
     """
     This interface is used to get the information of smart contract based on the specified hexadecimal hash value.
     """
     if not isinstance(hex_contract_address, str):
         raise SDKException(ErrorCode.param_err('a hexadecimal contract address is required.'))
     if len(hex_contract_address) != 40:
         raise SDKException(ErrorCode.param_err('the length of the contract address should be 40 bytes.'))
     payload = self.generate_json_rpc_payload(RpcMethod.GET_SMART_CONTRACT, [hex_contract_address, 1])
     response = await self.__post(payload)
     if is_full:
         return response
     result = response['result']
     return dict() if result is None else result
Пример #4
0
    def read_serializable_array(self, class_name, max_size=sys.maxsize):
        """
        Deserialize a stream into the object specific by `class_name`.

        Args:
            class_name (str): a full path to the class to be deserialized into. e.g. 'neo.Core.Block.Block'
            max_size (int): (Optional) maximum number of bytes to read.

        Returns:
            list: list of `class_name` objects deserialized from the stream.
        """
        module = '.'.join(class_name.split('.')[:-1])
        class_name = class_name.split('.')[-1]
        class_attr = getattr(importlib.import_module(module), class_name)
        length = self.read_var_int(max_size=max_size)
        items = []
        try:
            for _ in range(0, length):
                item = class_attr()
                item.Deserialize(self)
                items.append(item)
        except Exception as e:
            raise SDKException(
                ErrorCode.param_err("Couldn't deserialize %s" % e))
        return items
Пример #5
0
    def read_var_int(self, max_size=sys.maxsize):
        """
        Read a variable length integer from the stream.
        The NEO network protocol supports encoded storage for space saving. See: http://docs.neo.org/en-us/node/network-protocol.html#convention

        Args:
            max_size (int): (Optional) maximum number of bytes to read.

        Returns:
            int:
        """
        fb = self.read_byte()
        if fb is 0:
            return fb
        if hex(fb) == '0xfd':
            value = self.read_uint16()
        elif hex(fb) == '0xfe':
            value = self.read_uint32()
        elif hex(fb) == '0xff':
            value = self.read_uint64()
        else:
            value = fb
        if value > max_size:
            raise SDKException(ErrorCode.param_err('Invalid format'))
        return int(value)
Пример #6
0
 def new_verify_signature_tx(self, did: str,
                             key_index: int) -> InvokeTransaction:
     if key_index < 1:
         raise SDKException(ErrorCode.param_err('Invalid key index.'))
     args = dict(did=did.encode('utf-8'), index=key_index)
     tx = self._generate_transaction('verifySignature', args, b'', 0, 0)
     return tx
Пример #7
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)
Пример #8
0
 def write_bytes(self, value: bytearray or bytes or str or int):
     if isinstance(value, bytearray) or isinstance(value, bytes):
         self.ms.write(value)
     elif isinstance(value, str):
         self.ms.write(value.encode('utf-8'))
     elif isinstance(value, int):
         self.ms.write(bytes([value]))
     else:
         raise SDKException(
             ErrorCode.param_err('type error, write byte failed.'))
Пример #9
0
    def get_parameter(self, param_name: str) -> Parameter:
        """
        This interface is used to get a Parameter object from an AbiFunction object
        which contain given function parameter's name, type and value.

        :param param_name: a string used to indicate which parameter we want to get from AbiFunction.
        :return: a Parameter object which contain given function parameter's name, type and value.
        """
        for p in self.parameters:
            if p.name == param_name:
                return p
        raise SDKException(ErrorCode.param_err('get parameter failed.'))
Пример #10
0
 def verify_signature(self, did: str, key_index: int,
                      sign_acct: Account) -> bool:
     if key_index < 1:
         raise SDKException(ErrorCode.param_err('Invalid key index.'))
     tx = self.new_verify_signature_tx(did, key_index)
     tx.sign_transaction(sign_acct)
     try:
         self._sdk.default_network.send_raw_transaction_pre_exec(tx)
     except SDKException as e:
         if 'verify signature failed' in e.args[1]:
             return False
         else:
             raise e
     return True
Пример #11
0
 def add_sign_transaction(self, signer: Account):
     """
     This interface is used to add signature into the transaction.
     """
     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'
             ))
     tx_hash = self.hash256()
     sig_data = signer.generate_signature(tx_hash)
     sig = Sig([signer.get_public_key_bytes()], 1, [sig_data])
     self.sig_list.append(sig)
Пример #12
0
 def new_approve_tx(self, owner: Union[str, bytes,
                                       Address], spender: Union[str, bytes,
                                                                Address],
                    amount: int, payer: Union[str, bytes, Address],
                    gas_price: int, gas_limit: int) -> InvokeTransaction:
     """
     This interface is used to generate a transaction which allows spender to
     withdraw from owner account multiple times, up to the _value amount.
     If this function is called again it overwrites the current allowance with amount value.
     """
     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.'))
     func = NeoInvokeFunction('approve')
     func.set_params_value(Address.b58decode(owner),
                           Address.b58decode(spender), amount)
     params = InvokeTransaction.generate_neo_vm_invoke_code(
         self._contract_address, func)
     tx = InvokeTransaction(payer, gas_price, gas_limit, params)
     return tx
Пример #13
0
    def write_var_int(self, value: int, little_endian=True):
        """
        Write an integer value in a space saving way to the stream.
        """
        if not isinstance(value, int):
            raise SDKException(ErrorCode.param_err('%s not int type.' % value))

        if value < 0:
            raise SDKException(ErrorCode.param_err('%d too small.' % value))

        elif value < 0xfd:
            return self.write_byte(value)

        elif value <= 0xffff:
            self.write_byte(0xfd)
            return self.write_uint16(value, little_endian)

        elif value <= 0xFFFFFFFF:
            self.write_byte(0xfe)
            return self.write_uint32(value, little_endian)

        else:
            self.write_byte(0xff)
            return self.write_uint64(value, little_endian)
Пример #14
0
 def new_transfer_from_tx(self, spender: Union[str, bytes, Address],
                          owner: Union[str, bytes, Address],
                          to_address: Union[str, bytes, Address],
                          value: int, payer: Union[str, bytes,
                                                   Address], gas_price: int,
                          gas_limit: int) -> InvokeTransaction:
     func = NeoInvokeFunction('transferFrom')
     if not isinstance(value, int):
         raise SDKException(
             ErrorCode.param_err('the data type of value should be int.'))
     func.set_params_value(Address.b58decode(spender),
                           Address.b58decode(owner),
                           Address.b58decode(to_address), value)
     tx = InvokeTransaction(payer, gas_price, gas_limit)
     tx.add_invoke_code(self._contract_address, func)
     return tx
Пример #15
0
    def write_fixed_str(self, value, length):
        """
        Write a string value to the stream.
        """
        towrite = value.encode('utf-8')
        slen = len(towrite)
        if slen > length:
            raise SDKException(
                ErrorCode.param_err('string longer than fixed length: %s' %
                                    length))
        self.write_bytes(towrite)
        diff = length - slen

        while diff > 0:
            self.write_byte(0)
            diff -= 1
Пример #16
0
 def __init__(self, rpc_address: str = '', restful_address: str = '', ws_address: str = '',
              default_signature_scheme: SignatureScheme = SignatureScheme.SHA256withECDSA):
     if not isinstance(default_signature_scheme, SignatureScheme):
         raise SDKException(ErrorCode.param_err('SignatureScheme object is required.'))
     self.__rpc = Rpc(rpc_address)
     self.__aio_rpc = AioRpc(rpc_address)
     self.__restful = Restful(restful_address)
     self.__aio_restful = AioRestful(restful_address)
     self.__websocket = Websocket(ws_address)
     self.__default_network = self.__rpc
     self.__default_aio_network = self.__aio_rpc
     self.__native_vm = NativeVm(self)
     self.__neo_vm = NeoVm(self)
     self.__wasm_vm = WasmVm(self)
     self.__service = Service(self)
     self.__wallet_manager = WalletManager()
     self.__default_signature_scheme = default_signature_scheme
Пример #17
0
 def new_registry_did_tx(self, did: str, pub_key: str or bytes,
                         payer: Union[str, bytes, Address], gas_price: int,
                         gas_limit: int) -> InvokeTransaction:
     """
     This interface is used to generate a Transaction object which is used to register ONT ID.
     """
     if isinstance(pub_key, str):
         bytes_ctrl_pub_key = bytes.fromhex(pub_key)
     elif isinstance(pub_key, bytes):
         bytes_ctrl_pub_key = pub_key
     else:
         raise SDKException(
             ErrorCode.param_err(
                 'a bytes or str type of public key is required.'))
     args = dict(did=did.encode('utf-8'), ctrl_pk=bytes_ctrl_pub_key)
     tx = self._generate_transaction('regIDWithPublicKey', args, payer,
                                     gas_price, gas_limit)
     return tx
Пример #18
0
 def load_file(self):
     with open(self.__wallet_path, 'rb') as f:
         content = f.read()
         if content.startswith(codecs.BOM_UTF8):
             content = content[len(codecs.BOM_UTF8):]
         content = content.decode('utf-8')
         wallet_dict = json.loads(content)
         create_time = wallet_dict.get('createTime', '')
         default_id = wallet_dict.get('defaultDID', '')
         default_address = wallet_dict.get('defaultAccountAddress', '')
         identities = wallet_dict.get('identities', list())
         try:
             scrypt_dict = wallet_dict['scrypt']
             scrypt_obj = Scrypt(scrypt_dict.get('n', 16384), scrypt_dict.get('r', 8), scrypt_dict.get('p', 8),
                                 scrypt_dict.get('dk_len', 64))
             wallet = WalletData(wallet_dict['name'], wallet_dict['version'], create_time, default_id,
                                 default_address, scrypt_obj, identities, wallet_dict['accounts'])
         except KeyError as e:
             raise SDKException(ErrorCode.param_err(f'wallet file format error: {e}.'))
     return wallet
Пример #19
0
 def verify_signature(self, msg: bytes, signature: bytes):
     if msg is None or signature is None:
         raise Exception(ErrorCode.param_err("param should not be None"))
     handler = SignatureHandler(self.__signature_scheme)
     return handler.verify_signature(self.get_public_key_bytes(), msg, signature)
Пример #20
0
 def test_param_err(self):
     msg = 'TEST'
     value = ErrorCode.param_err(msg)
     self.assertEqual(value["desc"], msg)