Ejemplo n.º 1
0
    def validate(self):
        if self.version != 0:
            Logger.error("invalid vote version")
            return False

        type_list = list()
        for content in self.contents:
            if content.vote_type in type_list:
                Logger.error("{} duplicate vote type")
                return False
            type_list.append(content.vote_type)

            if content.vote_type != VoteContent.TYPE_DELEGATE:
                Logger.error("{} invalid vote type")

            if len(content.candidates) == 0 or len(content.candidates) > 36:
                Logger.error("{} invalid vote candidates")
                return False

            candidates_list = list()
            for candidate in content.candidates:
                if candidate in candidates_list:
                    Logger.error("{} duplicate candidate")
                    return False
                candidates_list.append(candidate)

        return True
Ejemplo n.º 2
0
    def _check_password(self):
        ret = keytool.sha256_hash(str.encode(self._password),
                                  3).hex() == self._get_password_hash()
        if not ret:
            Logger.error("Invalid password!")

        return ret
Ejemplo n.º 3
0
 def add_sub_account(self, sub_account: Account):
     if not self._valid:
         Logger.error("Invalid keystore!")
         return
     self._sub_accounts_list.append(sub_account)
     sub_account_data = self._create_account_data(sub_account,
                                                  self.SUB_ACCOUNT)
     self._accounts_data_list.append(sub_account_data)
Ejemplo n.º 4
0
def arbiter_public_keys(key_stores):
    public_keys = []
    if len(key_stores) != 5:
        Logger.error(
            "[common] Invalid argument, the length of the argument must be equal 5"
        )
        exit(0)
    for key_store in key_stores:
        public_keys.append(key_store.public_key.hex())
    return public_keys
    def serialize(self, version: int):
        if self.candidates is None or len(self.candidates) == 0:
            Logger.error("candidates list is empty!")
            return None
        r = b""
        r += struct.pack("<B", self.vote_type)
        r += serialize.write_var_uint(len(self.candidates))
        for candidate in self.candidates:
            r = serialize.write_var_bytes(r, candidate)

        return r
Ejemplo n.º 6
0
    def serialize(self):
        if self.contents is None or len(self.contents) == 0:
            Logger.error("contents is invalid")
            return None

        r = b""
        r += struct.pack("<B", self.version)
        r += serialize.write_var_uint(len(self.contents))
        for content in self.contents:
            r += content.serialize(self.version)

        return r
Ejemplo n.º 7
0
    def _get_master_key(self):
        password_twice_hash = keytool.sha256_hash(str.encode(self._password),
                                                  2)
        encrypt_master_key = self._get_master_key_encrypted()
        if encrypt_master_key is None:
            Logger.error("encrypt master key is None")
            return None

        master_key = keytool.aes_decrypt(bytes.fromhex(encrypt_master_key),
                                         password_twice_hash, self._iv)

        return master_key
Ejemplo n.º 8
0
    def key_store_dict(self):
        if not self._valid:
            Logger.error("Invalid keystore!")
            return None
        store_dict = {
            "Version": "1.0.0",
            "PasswordHash": self._password_thrice_hash.hex(),
            "IV": self._iv.hex(),
            "MasterKey": self._master_key_encrypted.hex(),
            "Account": self._accounts_data_list
        }

        return store_dict
Ejemplo n.º 9
0
def create_normal_inputs(address: str, total_amount: int, rpc_port: int):
    global total_amount_global
    global response
    total_amount_global = total_amount
    total_amount_format = str(
        Decimal(str(total_amount_global)) / Decimal(util.TO_SELA))

    if rpc_port != rpc.DEFAULT_PORT:
        response = rpc.list_unspent_utxos(address, port=rpc_port)
    else:
        response = rpc.get_utxos_by_amount(address, total_amount_format,
                                           rpc_port)
    if not response or isinstance(response, dict):
        Logger.error("get utxos return error: {}".format(response))
        return None, None
    utxos = response

    # Logger.debug("utxos: {}".format(utxos))
    inputs = list()
    change_outputs = list()

    program_hash = keytool.address_to_program_hash(address)

    for utxo in utxos:
        txid = util.bytes_reverse(bytes.fromhex(utxo["txid"]))
        index = utxo["vout"]
        input = Input(txid, index)
        inputs.append(input)

        amount = int(Decimal(utxo["amount"]) * util.TO_SELA)

        if amount < total_amount_global:
            total_amount -= amount
        elif amount == total_amount:
            total_amount_global = 0
            break
        elif amount > total_amount:
            change = Output(value=amount - total_amount_global,
                            output_lock=0,
                            program_hash=program_hash,
                            output_type=Output.OT_NONE,
                            output_payload=OutputPayload())
            change_outputs.append(change)
            total_amount_global = 0
            break

    if total_amount_global > 0:
        Logger.error("Available token is not enough!")
        return None, None

    return inputs, change_outputs
Ejemplo n.º 10
0
    def serialize(self, r: bytes, version: int):
        if len(self.cross_chain_addresses) != len(self.output_indexes) or \
                len(self.cross_chain_addresses) != len(self.cross_chain_addresses):
            Logger.error("Invalid cross chain asset")
            return None

        r += serialize.write_var_uint(len(self.cross_chain_addresses))

        for i in range(len(self.cross_chain_addresses)):
            r = serialize.write_var_bytes(
                r, bytes(self.cross_chain_addresses[i].encode()))
            r += serialize.write_var_uint(self.output_indexes[i])
            r += struct.pack("<q", self.cross_chain_amounts[i])

        return r
Ejemplo n.º 11
0
    def save_to_file(self, dest_dir_path: str):
        if not self._valid:
            Logger.error("Invalid keystore!")
            return False
        if dest_dir_path is "":
            Logger.debug("Invalid parameter!")
            return False

        if not os.path.exists(dest_dir_path):
            os.makedirs(dest_dir_path)

        file_path = os.path.join(dest_dir_path, "keystore.dat")
        util.write_config_file(self.key_store_dict(), file_path)

        return True
Ejemplo n.º 12
0
    def _get_account(self, index):
        encrypt_private_key = self._accounts_data_list[index][
            "PrivateKeyEncrypted"]
        if encrypt_private_key is None:
            Logger.error("encrypt private key is None")
            return None

        encrypt_private_key_bytes = bytes.fromhex(encrypt_private_key)
        if len(encrypt_private_key_bytes) != 96:
            Logger.error("encrypt private key length is not 96")
            return None

        private_key = keytool.aes_decrypt(encrypt_private_key_bytes,
                                          self._master_key, self._iv)[64:96]
        account = Account(private_key.hex())
        return account
Ejemplo n.º 13
0
def create_transaction(input_private_key: str, output_addresses: list,
                       amount: int, rpc_port: int):
    account = Account(input_private_key)
    # check output
    if output_addresses is None or len(output_addresses) == 0:
        Logger.error("Invalid output addresses")
        return None

    # create outputs
    outputs, total_amount = create_normal_outputs(
        output_addresses=output_addresses,
        amount=amount,
        fee=util.TX_FEE,
        output_lock=0)

    # create inputs
    inputs, change_outputs = create_normal_inputs(account.address(),
                                                  total_amount, rpc_port)

    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(usage=Attribute.NONCE,
                          data=bytes("attributes".encode()))
    attributes.append(attribute)

    tx = Transaction()
    tx.version = Transaction.TX_VERSION_09
    tx.tx_type = Transaction.TRANSFER_ASSET
    tx.payload = Payload(Payload.DEFAULT_VERSION)
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
Ejemplo n.º 14
0
def create_redeem_transaction(payload: ProducerInfo, output_address: str,
                              amount: int, rpc_port: int):

    # create outputs
    outputs, total_amount = create_normal_outputs(
        output_addresses=[output_address],
        amount=amount,
        fee=util.TX_FEE,
        output_lock=0)

    # create inputs

    deposit_address = payload.get_deposit_address()
    inputs, change_outputs = create_normal_inputs(deposit_address,
                                                  total_amount, rpc_port)
    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(payload.owner_account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(usage=Attribute.NONCE,
                          data=bytes("attributes".encode()))
    attributes.append(attribute)

    tx = Transaction()
    tx.version = Transaction.TX_VERSION_09
    tx.tx_type = Transaction.RETURN_DEPOSIT_CHAIN
    tx.payload_version = 0
    tx.payload = Payload(Payload.DEFAULT_VERSION)
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
Ejemplo n.º 15
0
def create_register_transaction(input_private_key: str, amount: int,
                                payload: ProducerInfo, rpc_port: int):

    # create outputs
    outputs, total_amount = create_normal_outputs(
        output_addresses=[payload.get_deposit_address()],
        amount=amount,
        fee=util.TX_FEE,
        output_lock=0)

    # create inputs
    account = Account(input_private_key)
    inputs, change_outputs = create_normal_inputs(account.address(),
                                                  total_amount, rpc_port)
    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(usage=Attribute.NONCE,
                          data=bytes("attributes".encode()))
    attributes.append(attribute)

    tx = Transaction()
    tx.version = Transaction.TX_VERSION_09
    tx.tx_type = Transaction.REGISTER_PRODUCER
    tx.payload_version = 0
    tx.payload = payload
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
Ejemplo n.º 16
0
def create_cancel_transaction(input_private_key: str, payload: ProducerInfo,
                              rpc_port: int):

    # create inputs
    account = Account(input_private_key)
    inputs, change_outputs = create_normal_inputs(account.address(),
                                                  util.TX_FEE, rpc_port)
    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None

    # create outputs
    outputs = list()
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(usage=Attribute.NONCE,
                          data=bytes("attributes".encode()))
    attributes.append(attribute)

    payload = ProcessProducer(
        bytes.fromhex(payload.owner_account.public_key()),
        bytes.fromhex(payload.owner_account.private_key()))
    tx = Transaction()
    tx.version = Transaction.TX_VERSION_09
    tx.tx_type = Transaction.CANCEL_PRODUCER
    tx.payload_version = 0
    tx.payload = payload
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
Ejemplo n.º 17
0
    def serialize_unsigned(self):
        # version
        r = b""
        if self.version >= self.TX_VERSION_09:
            r += struct.pack(">B", self.version)

        # tx type
        r += struct.pack(">B", self.tx_type)

        # payload version
        r += struct.pack(">B", self.payload_version)

        # payload
        if self.payload is None:
            Logger.error("Transaction payload is None")
            return None

        if self.payload.data(self.payload_version) is not None:
            r += self.payload.data(self.payload_version)

        # attributes
        if self.attributes is not None:
            r += serialize.write_var_uint(len(self.attributes))
            for attribute in self.attributes:
                r += attribute.serialize()

        # inputs
        if self.inputs is not None:
            r += serialize.write_var_uint(len(self.inputs))
            for input in self.inputs:
                r += input.serialize()

        # outputs
        if self.outputs is not None:
            r += serialize.write_var_uint(len(self.outputs))
            for output in self.outputs:
                r += output.serialize(self.version)

        # lock_time
        r += struct.pack("<I", self.lock_time)

        return r
Ejemplo n.º 18
0
def create_cross_chain_asset(input_private_key: str, lock_address: str,
                             cross_chain_address: str, amount: int,
                             recharge: bool, rpc_port: int):
    if lock_address is None or lock_address is "":
        Logger.error("Invalid lock address")
        return None

    if cross_chain_address is None or cross_chain_address is "":
        Logger.error("Invalid cross chain address")
        return None

    account = Account(input_private_key)
    # create outputs:
    outputs, total_amount = create_normal_outputs(
        output_addresses=[lock_address],
        amount=amount,
        fee=util.TX_FEE,
        output_lock=0)

    # create inputs:
    inputs, change_outputs = create_normal_inputs(account.address(),
                                                  total_amount, rpc_port)
    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(usage=Attribute.NONCE,
                          data=bytes("attributes".encode()))
    attributes.append(attribute)

    cross_chain_asset = TransferCrossChainAsset()
    cross_chain_asset.cross_chain_addresses = [cross_chain_address]
    cross_chain_asset.output_indexes = [0]
    cross_chain_asset.cross_chain_amounts = [amount - util.TX_FEE]

    tx = Transaction()
    if recharge:
        tx.version = Transaction.TX_VERSION_09
    else:
        tx.version = Transaction.TX_VERSION_DEFAULT

    Logger.debug("transaction version {}".format(tx.version))
    tx.tx_type = Transaction.TRANSFER_CROSS_CHAIN_ASSET
    tx.payload = cross_chain_asset
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
Ejemplo n.º 19
0
    def _get_password_hash(self):
        if "PasswordHash" not in self._store_dict.keys():
            Logger.error("keystore_dat dose not contain key PasswordHash")
            return None

        return self._store_dict["PasswordHash"]
Ejemplo n.º 20
0
    def _get_accounts_data(self, ):
        if "Account" not in self._store_dict.keys():
            Logger.error("keystore_dat dose not contain key Account")
            return None

        return self._store_dict["Account"]
Ejemplo n.º 21
0
 def password(self):
     if not self._valid:
         Logger.error("Invalid keystore!")
         return ""
     return self._password
Ejemplo n.º 22
0
 def sub_accounts(self):
     if not self._valid:
         Logger.error("Invalid keystore!")
         return None
     return self._sub_accounts_list
Ejemplo n.º 23
0
    def _get_iv(self):
        if "IV" not in self._store_dict.keys():
            Logger.error("keystore_dat dose not contain key IV")
            return None

        return self._store_dict["IV"]
Ejemplo n.º 24
0
 def __repr__(self):
     if not self._valid:
         Logger.error("Invalid keystore!")
         return ""
     return json.dumps(self.key_store_dict(), indent=4)
Ejemplo n.º 25
0
 def export_private_key(self):
     if not self._valid:
         Logger.error("Invalid keystore!")
         return None
     return self.main_account().private_key()
Ejemplo n.º 26
0
    def _get_master_key_encrypted(self):
        if "MasterKey" not in self._store_dict.keys():
            Logger.error("keystore_dat dose not contain key MasterKey")
            return None

        return self._store_dict["MasterKey"]
Ejemplo n.º 27
0
 def main_account(self):
     if not self._valid:
         Logger.error("Invalid keystore!")
         return None
     return self._main_account