def sign(priv_key, data): acc = Account.from_secret_key_string(priv_key) tx_signer = TxSigner(acc, 'ae_uat') tx_builder = TxBuilder() tx = TxObject(tx=data) signature = tx_signer.sign_transaction(tx, None) signed = tx_builder.tx_signed([signature], tx, metadata=None) return signed.tx
def test_signing_create_transaction(): # generate a new account new_account = Account.generate() receiver_address = new_account.get_address() # create a spend transaction txb = TxBuilder(EPOCH_CLI, ACCOUNT) tx, sg, tx_hash = txb.tx_spend(receiver_address, 321, "test test ", TEST_FEE, TEST_TTL) # this call will fail if the hashes of the transaction do not match txb.post_transaction(tx, tx_hash) # make sure this works for very short block times spend_tx = EPOCH_CLI.get_transaction_by_hash(hash=tx_hash) assert spend_tx.signatures[0] == sg
def tx_spend(sender_id, recipient_id, amount, ttl, fee, nonce, payload, json_): try: set_global_options(json_) tx = TxBuilder().tx_spend(sender_id, recipient_id, amount, payload, fee, ttl, nonce) # print the results _print_object(tx, title='spend tx') except Exception as e: _print_error(e, exit_code=1)
def tx_call(self, keypair, function, arg, amount=10, gas=CONTRACT_DEFAULT_GAS, gas_price=CONTRACT_DEFAULT_GAS_PRICE, fee=DEFAULT_FEE, vm_version=CONTRACT_DEFAULT_VM_VERSION, tx_ttl=DEFAULT_TX_TTL): """Call a sophia contract""" if not utils.is_valid_hash(self.address, prefix="ct"): raise ValueError("Missing contract id") try: call_data = self.encode_calldata(function, arg) txb = TxBuilder(self.client, keypair) tx, sg, tx_hash = txb.tx_contract_call(self.address, call_data, function, arg, amount, gas, gas_price, vm_version, fee, tx_ttl) # post the transaction to the chain txb.post_transaction(tx, tx_hash) # wait for transaction to be mined txb.wait_tx(tx_hash) # unsigned transaction of the call call_obj = self.client.cli.get_transaction_info_by_hash( hash=tx_hash) return call_obj except OpenAPIClientException as e: raise ContractError(e)
def tx_create(self, keypair, amount=1, deposit=CONTRACT_DEFAULT_DEPOSIT, init_state="()", gas=CONTRACT_DEFAULT_GAS, gas_price=CONTRACT_DEFAULT_GAS_PRICE, fee=DEFAULT_FEE, vm_version=CONTRACT_DEFAULT_VM_VERSION, tx_ttl=DEFAULT_TX_TTL): """ Create a contract and deploy it to the chain :return: address """ try: call_data = self.encode_calldata("init", init_state) # get the transaction builder txb = TxBuilder(self.client, keypair) # create spend_tx tx, sg, tx_hash, contract_id = txb.tx_contract_create( self.bytecode, call_data, amount, deposit, gas, gas_price, vm_version, fee, tx_ttl) # post the transaction to the chain txb.post_transaction(tx, tx_hash) if self.client.blocking_mode: txb.wait_tx(tx_hash) # store the contract address in the instance variabl self.address = contract_id return tx except OpenAPIClientException as e: raise ContractError(e)
def update(self, account, target, name_ttl=DEFAULT_NAME_TTL, client_ttl=NAME_CLIENT_TTL, fee=DEFAULT_FEE, tx_ttl=DEFAULT_TX_TTL): if self.status != NameStatus.CLAIMED: raise NameUpdateError('Must be claimed to update pointer') if isinstance(target, oracle.Oracle): if target.oracle_id is None: raise ValueError( 'You must register the oracle before using it as target') target = target.oracle_id # TODO: check the value for name ttl? # get the name_id and pointers name_id = hashing.namehash_encode("nm", self.domain) pointers = self._get_pointers(target) # get the transaction builder txb = TxBuilder(self.client, account) # create claim transaction tx, sg, tx_hash = txb.tx_name_update(name_id, pointers, name_ttl, client_ttl, fee, tx_ttl) # post the transaction to the chain txb.post_transaction(tx, tx_hash) # ensure tx if self.client.blocking_mode: txb.wait_tx(tx_hash) return tx_hash
def account_sign(keystore_name, password, network_id, unsigned_transaction, json_): try: set_global_options(json_) account, _ = _account(keystore_name, password=password) if not utils.is_valid_hash(unsigned_transaction, prefix="tx"): raise ValueError("Invalid transaction format") # force offline mode for the node_client txb = TxBuilder() txu = txb.parse_tx_string(unsigned_transaction) signature = TxSigner(account, network_id).sign_transaction(txu) # TODO: better handling of metadata txs = txb.tx_signed([signature], txu, metadata={"network_id": network_id}) # _print_object(txu, title='unsigned transaction') _print_object(txs, title='signed transaction') except Exception as e: _print_error(e, exit_code=1)
def tx_broadcast(signed_transaction, force, wait, json_): try: set_global_options(json_, force, wait) if not utils.is_valid_hash(signed_transaction, prefix="tx"): raise ValueError("Invalid transaction format") cli = _node_cli() signed_transaction = TxBuilder().parse_tx_string(signed_transaction) tx_hash = cli.broadcast_transaction(signed_transaction) _print_object({ "Transaction hash": tx_hash, }, title='transaction broadcast') except Exception as e: _print_error(e, exit_code=1)
def revoke(self, account, fee=DEFAULT_FEE, tx_ttl=DEFAULT_TX_TTL): """ revoke a name :return: the transaction """ # get the name_id and pointers name_id = hashing.namehash_encode("nm", self.domain) # get the transaction builder txb = TxBuilder(self.client, account) # create claim transaction tx, sg, tx_hash = txb.tx_name_revoke(name_id, fee, tx_ttl) # post the transaction to the chain txb.post_transaction(tx, tx_hash) # ensure tx if self.client.blocking_mode: txb.wait_tx(tx_hash) self.status = NameStatus.REVOKED return tx_hash
def claim(self, account, fee=DEFAULT_FEE, tx_ttl=DEFAULT_TX_TTL): if self.preclaimed_block_height is None: raise MissingPreclaim( 'You must call preclaim before claiming a name') # name encoded TODO: shall this goes into transactions? name = AEName._encode_name(self.domain) # get the transaction builder txb = TxBuilder(self.client, account) # create claim transaction tx, sg, tx_hash = txb.tx_name_claim(name, self.preclaim_salt, fee, tx_ttl) # post the transaction to the chain txb.post_transaction(tx, tx_hash) # ensure tx if self.client.blocking_mode: txb.wait_tx(tx_hash) # update status self.status = AEName.Status.CLAIMED return tx_hash
def preclaim(self, account, fee=DEFAULT_FEE, tx_ttl=DEFAULT_TX_TTL): """ Execute a name preclaim """ # check which block we used to create the preclaim self.preclaimed_block_height = self.client.get_current_key_block_height( ) # calculate the commitment hash commitment_hash = self._get_commitment_hash() # get the transaction builder txb = TxBuilder(self.client, account) # create spend_tx tx, sg, tx_hash = txb.tx_name_preclaim(commitment_hash, fee, tx_ttl) # post the transaction to the chain txb.post_transaction(tx, tx_hash) if self.client.blocking_mode: txb.wait_tx(tx_hash) # update local status self.status = AEName.Status.PRECLAIMED self.preclaim_tx_hash = tx_hash return tx_hash
def transfer_ownership(self, account, recipient_pubkey, fee=DEFAULT_FEE, tx_ttl=DEFAULT_TX_TTL): """ transfer ownership of a name :return: the transaction """ # get the name_id and pointers name_id = hashing.namehash_encode("nm", self.domain) # get the transaction builder txb = TxBuilder(self.client, account) # create claim transaction tx, sg, tx_hash = txb.tx_name_transfer(name_id, recipient_pubkey, fee, tx_ttl) # post the transaction to the chain txb.post_transaction(tx, tx_hash) # update local status self.status = NameStatus.TRANSFERRED # ensure tx if self.client.blocking_mode: txb.wait_tx(tx_hash) return tx_hash
def test_tutorial_offline_tx(chain_fixture): # Accounts addresses account = Account.generate() # --- hide --- override the account for tests account = chain_fixture.ALICE # /--- hide --- # instantiate the transactions builder build = TxBuilder() # we will be creating 5 transactions for later broadcast TODO: warn about the nonce limit txs = [] # each transaction is going to be a spend amount = utils.amount_to_aettos("0.05AE") payload = b'' for i in range(5): # increase the account nonce account.nonce = account.nonce + 1 # build the transaction tx = build.tx_spend( account.get_address(), # sender Account.generate().get_address(), # random generated recipient amount, payload, defaults.FEE, defaults.TX_TTL, account.nonce) # save the transaction txs.append(tx) # Sign the transactions # define the network_id network_id = identifiers.NETWORK_ID_TESTNET # --- hide --- override the network_id for tests network_id = chain_fixture.NODE_CLI.config.network_id # /--- hide --- # instantiate a transaction signer signer = TxSigner(account, network_id) # collect the signed tx for broadcast signed_txs = [] # sign all transactions for tx in txs: signature = signer.sign_transaction(tx) signed_tx = build.tx_signed([signature], tx) signed_txs.append(signed_tx) # Broadcast the transactions NODE_URL = os.environ.get('TEST_URL', 'https://testnet.aeternity.io') node_cli = NodeClient(Config( external_url=NODE_URL, blocking_mode=False, )) # broadcast all transactions for stx in signed_txs: node_cli.broadcast_transaction(stx) # verify that all transactions have been posted for stx in signed_txs: height = node_cli.wait_for_transaction(stx) assert (height > 0)