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
def __init__(self, owner_private_key: str, node_private_key: str, nickname: str, url: str, location: int, net_address: str): Payload.__init__(self, self.DEFAULT_VERSION) self.owner_account = Account(owner_private_key) self.node_account = Account(node_private_key) self.nickname = nickname self.url = url self.location = location self.net_address = net_address self.signature = self.gen_signature()
def __init__(self, input_private_key: str, owner_private_key: str, node_private_key: str, nick_name: str, url: str, location: int, net_address: str): self.input_private_key = input_private_key self.input_account = Account(input_private_key) self.utxo_value = 0 self.fee = 10000 self.state = "" self.deposit_amount = 5000 * util.TO_SELA self.info = self._producer_info(owner_private_key, node_private_key, nick_name, url, location, net_address)
def _create_account_data(self, account: Account, account_type: str): private_key_encrypted = keytool.encrypt_private_key( self._master_key, bytes.fromhex(account.private_key()), account.ecc_public_key(), self._iv) account_data = dict() account_data["Address"] = account.address() account_data["ProgramHash"] = account.program_hash() account_data["RedeemScript"] = account.redeem_script() account_data["PrivateKeyEncrypted"] = private_key_encrypted.hex() account_data["Type"] = account_type return account_data
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
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
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
class ProducerInfo(Payload): def __init__(self, owner_private_key: str, node_private_key: str, nickname: str, url: str, location: int, net_address: str): Payload.__init__(self, self.DEFAULT_VERSION) self.owner_account = Account(owner_private_key) self.node_account = Account(node_private_key) self.nickname = nickname self.url = url self.location = location self.net_address = net_address self.signature = self.gen_signature() def gen_signature(self): r = b"" r = self.serialize_unsigned(r, self.version) signature = keytool.ecdsa_sign(bytes.fromhex(self.owner_account.private_key()), r) self.signature = signature return signature def data(self, version): r = b"" r = self.serialize(r, version) return r def serialize(self, r: bytes, version: int): r = self.serialize_unsigned(r, version) if self.signature is not None: r = serialize.write_var_bytes(r, self.signature) return r def serialize_unsigned(self, r: bytes, version=0): r = serialize.write_var_bytes(r, bytes.fromhex(self.owner_account.public_key())) r = serialize.write_var_bytes(r, bytes.fromhex(self.node_account.public_key())) r = serialize.write_var_bytes(r, bytes(self.nickname.encode())) r = serialize.write_var_bytes(r, bytes(self.url.encode())) r += struct.pack("<Q", self.location) r = serialize.write_var_bytes(r, bytes(self.net_address.encode())) return r def deserialize(self, r: bytes, version: int): pass def deserialize_unsigned(self, r: bytes, version: int): pass def get_deposit_address(self): return self.owner_account.deposit_address() def __repr__(self): return "ProducerInfo {" + "\n\t" \ + "owner_public_key: {}".format(self.owner_account.public_key()) + "\n\t" \ + "node_public_key : {}".format(self.node_account.public_key()) + "\n\t" \ + "nickname: {}".format(self.nickname) + "\n\t" \ + "url: {}".format(self.url) + "\n\t" \ + "location: {}".format(self.location) + "\n\t" \ + "net_address: {}".format(self.net_address) + "\n" \ + "}"
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
def _read_key_stores(self, category: str, num: int): dest_path = os.path.join(self.stables_path, category + ".json") if not os.path.exists(dest_path): Logger.error( "{} read key stores failed, dest path {} is not found, exit..." .format(self.tag, dest_path)) time.sleep(1) exit(-1) content_dict = util.read_config_file(dest_path) for i in range(num): private_key_str = content_dict[category + "_" + str(i)]["private_key"] a = Account(private_key_str) self.category_dict[category].append(a) Logger.debug("{} load {} keystore on success !".format( self.tag, category))
class Producer(object): def __init__(self, input_private_key: str, owner_private_key: str, node_private_key: str, nick_name: str, url: str, location: int, net_address: str): self.input_private_key = input_private_key self.input_account = Account(input_private_key) self.utxo_value = 0 self.fee = 10000 self.state = "" self.deposit_amount = 5000 * util.TO_SELA self.info = self._producer_info(owner_private_key, node_private_key, nick_name, url, location, net_address) def _producer_info(self, owner_private_key: str, node_private_key: str, nick_name: str, url: str, location: int, net_address: str): info = ProducerInfo(owner_private_key=owner_private_key, node_private_key=node_private_key, nickname=nick_name, url=url, location=location, net_address=net_address) Logger.debug("generate register producer{} payload".format(nick_name)) return info def get_payload(self): return self.info def input_private_key(self): return self.input_private_key def input_public_key(self): return self.input_account.public_key() def owner_private_key(self): return self.get_payload().owner_account.private_key() def owner_public_key(self): return self.get_payload().owner_account.public_key() def node_private_key(self): return self.get_payload().node_account.private_key() def node_public_key(self): return self.get_payload().node_account.public_key() def register(self, rpc_port: int): tx = txbuild.create_register_transaction( input_private_key=self.input_private_key, amount=self.deposit_amount, payload=self.info, rpc_port=rpc_port) if tx is None: return None tx = txbuild.single_sign_transaction(self.input_private_key, tx) return tx def update(self, producer_info: ProducerInfo, rpc_port): tx = txbuild.create_update_transaction( input_private_key=self.input_private_key, payload=producer_info, rpc_port=rpc_port) if tx is None: return None producer_info.gen_signature() tx = txbuild.single_sign_transaction(self.input_private_key, tx) return tx def cancel(self, rpc_port: int): tx = txbuild.create_cancel_transaction( input_private_key=self.input_private_key, payload=self.get_payload(), rpc_port=rpc_port) if tx is None: return None tx = txbuild.single_sign_transaction(self.input_private_key, tx) return tx def redeem(self, amount: int, rpc_port: int): tx = txbuild.create_redeem_transaction( payload=self.get_payload(), output_address=self.input_account.address(), amount=amount, rpc_port=rpc_port) if tx is None: return None tx = txbuild.single_sign_transaction( self.get_payload().owner_account.private_key(), tx) return tx def activate(self): # note activate producer transaction needn't to sign the whole transaction tx = txbuild.create_active_transaction(self.node_private_key(), self.node_public_key()) if tx is None: return None return tx
def _create_keystore(self, category: str, num: int): keystore_saved_dir = os.path.join(self.key_message_saved_dir, category) if not os.path.exists(keystore_saved_dir): os.makedirs(keystore_saved_dir) for i in range(num): if i == 0: first_time = True else: first_time = False if category == "arbiter": a = Account(self.node_accounts[i].private_key()) else: a = Account() Logger.debug("{} {}_{} private key: {}".format( self.tag, category, i, a.private_key())) k = Keystore(a, self.password) self.category_dict[category].append(a) if category == "arbiter": sub1 = Account() k.add_sub_account(sub1) self.sub1_accounts.append(sub1) util.save_to_json( sub1, "sub1_" + str(i), os.path.join(self.key_message_saved_dir, "sub1.json"), first_time) sub2 = Account() k.add_sub_account(sub2) self.sub2_accounts.append(sub2) util.save_to_json( sub2, "sub2_" + str(i), os.path.join(self.key_message_saved_dir, "sub2.json"), first_time) sub3 = Account() k.add_sub_account(sub3) self.sub3_accounts.append(sub3) util.save_to_json( sub3, "sub3_" + str(i), os.path.join(self.key_message_saved_dir, "sub3.json"), first_time) sub4 = Account() k.add_sub_account(sub4) self.sub3_accounts.append(sub4) util.save_to_json( sub4, "sub4_" + str(i), os.path.join(self.key_message_saved_dir, "sub4.json"), first_time) util.save_to_json( a, category + "_" + str(i), os.path.join(self.key_message_saved_dir, category + ".json"), first_time) util.save_to_dat( k.key_store_dict(), os.path.join(keystore_saved_dir, category + str(i) + ".dat")) Logger.debug("{} create {} keystores on success!".format( self.tag, category))
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 def __repr__(self): if not self._valid: Logger.error("Invalid keystore!") return "" return json.dumps(self.key_store_dict(), indent=4) if __name__ == '__main__': a = Account() k = Keystore(a, "123") print(k) print(a) print("main private key: ", k.export_private_key())