def mint_or_burn_sign( cluster_obj: clusterlib.ClusterLib, new_tokens: List[TokenRecord], temp_template: str, ) -> clusterlib.TxRawOutput: """Mint or burn tokens, depending on the `amount` value. Sign using skeys. Positive `amount` value means minting, negative means burning. """ _issuers_addrs = [n.issuers_addrs for n in new_tokens] issuers_addrs = list(itertools.chain.from_iterable(_issuers_addrs)) issuers_skey_files = [p.skey_file for p in issuers_addrs] token_mint_addr_skey_files = [ t.token_mint_addr.skey_file for t in new_tokens ] src_address = new_tokens[0].token_mint_addr.address tx_files = clusterlib.TxFiles( signing_key_files=[*issuers_skey_files, *token_mint_addr_skey_files]) # build and sign a transaction ttl = cluster_obj.calculate_tx_ttl() fee = cluster_obj.calculate_tx_fee( src_address=src_address, tx_name=temp_template, tx_files=tx_files, ttl=ttl, # TODO: workaround for https://github.com/input-output-hk/cardano-node/issues/1892 witness_count_add=len(issuers_skey_files) * 2, ) tx_raw_output = cluster_obj.build_raw_tx( src_address=src_address, tx_name=temp_template, tx_files=tx_files, fee=fee, ttl=ttl, mint=[ clusterlib.TxOut(address=n.token_mint_addr.address, amount=n.amount, coin=n.token) for n in new_tokens ], ) out_file_signed = cluster_obj.sign_tx( tx_body_file=tx_raw_output.out_file, signing_key_files=tx_files.signing_key_files, tx_name=temp_template, script_files=[n.script for n in new_tokens], ) # submit signed transaction cluster_obj.submit_tx(out_file_signed) cluster_obj.wait_for_new_block(new_blocks=2) return tx_raw_output
def test_shelley_cddl(self, cluster: clusterlib.ClusterLib, payment_addrs: List[clusterlib.AddressRecord]): """Check expected failure when Shelley Tx is used with CDDL format.""" temp_template = common.get_test_id(cluster) src_address = payment_addrs[0].address dst_address = payment_addrs[1].address # amount value -1 means all available funds destinations = [clusterlib.TxOut(address=dst_address, amount=-1)] tx_files = clusterlib.TxFiles( signing_key_files=[payment_addrs[1].skey_file]) fee = cluster.calculate_tx_fee( src_address=src_address, tx_name=temp_template, txouts=destinations, tx_files=tx_files, ) orig_cddl_value = cluster.use_cddl try: cluster.use_cddl = True tx_raw_output = cluster.build_raw_tx( src_address=src_address, tx_name=temp_template, txouts=destinations, tx_files=tx_files, fee=fee, ) finally: cluster.use_cddl = orig_cddl_value with pytest.raises(clusterlib.CLIError) as excinfo: cluster.sign_tx( tx_body_file=tx_raw_output.out_file, signing_key_files=tx_files.signing_key_files, tx_name=temp_template, ) if "TextEnvelope error" in str(excinfo.value): pytest.xfail("TextEnvelope error") else: pytest.fail(f"Unexpected error:\n{excinfo.value}")
def _mint_tx( self, cluster_obj: clusterlib.ClusterLib, new_tokens: List[clusterlib_utils.TokenRecord], temp_template: str, ) -> Path: """Return signed TX for minting new token. Sign using skeys.""" _issuers_addrs = [n.issuers_addrs for n in new_tokens] issuers_addrs = list(itertools.chain.from_iterable(_issuers_addrs)) issuers_skey_files = [p.skey_file for p in issuers_addrs] token_mint_addr_skey_files = [ t.token_mint_addr.skey_file for t in new_tokens ] src_address = new_tokens[0].token_mint_addr.address tx_files = clusterlib.TxFiles(signing_key_files=[ *issuers_skey_files, *token_mint_addr_skey_files ]) # build and sign a transaction tx_raw_output = cluster_obj.build_raw_tx( src_address=src_address, tx_name=temp_template, tx_files=tx_files, fee=100_000, mint=[ clusterlib.TxOut(address=n.token_mint_addr.address, amount=n.amount, coin=n.token) for n in new_tokens ], ) out_file_signed = cluster_obj.sign_tx( tx_body_file=tx_raw_output.out_file, signing_key_files=tx_files.signing_key_files, tx_name=temp_template, script_files=[n.script for n in new_tokens], ) return out_file_signed
def mint_or_burn_witness( cluster_obj: clusterlib.ClusterLib, new_tokens: List[TokenRecord], temp_template: str, invalid_hereafter: Optional[int] = None, invalid_before: Optional[int] = None, ) -> clusterlib.TxRawOutput: """Mint or burn tokens, depending on the `amount` value. Sign using witnesses. Positive `amount` value means minting, negative means burning. """ _issuers_addrs = [t.issuers_addrs for t in new_tokens] issuers_addrs = set(itertools.chain.from_iterable(_issuers_addrs)) issuers_skey_files = {p.skey_file for p in issuers_addrs} src_address = new_tokens[0].token_mint_addr.address # create TX body tx_files = clusterlib.TxFiles( script_files=clusterlib.ScriptFiles(minting_scripts=[t.script for t in new_tokens]), ) mint = [ clusterlib.TxOut(address=t.token_mint_addr.address, amount=t.amount, coin=t.token) for t in new_tokens ] fee = cluster_obj.calculate_tx_fee( src_address=src_address, tx_name=temp_template, tx_files=tx_files, mint=mint, # TODO: workaround for https://github.com/input-output-hk/cardano-node/issues/1892 witness_count_add=len(issuers_skey_files), ) tx_raw_output = cluster_obj.build_raw_tx( src_address=src_address, tx_name=temp_template, tx_files=tx_files, fee=fee, invalid_hereafter=invalid_hereafter, invalid_before=invalid_before, mint=mint, ) # create witness file for each required key witness_files = [ cluster_obj.witness_tx( tx_body_file=tx_raw_output.out_file, witness_name=f"{temp_template}_skey{idx}", signing_key_files=[skey], ) for idx, skey in enumerate(issuers_skey_files) ] # sign TX using witness files tx_witnessed_file = cluster_obj.assemble_tx( tx_body_file=tx_raw_output.out_file, witness_files=witness_files, tx_name=temp_template, ) # submit signed TX cluster_obj.submit_tx(tx_file=tx_witnessed_file, txins=tx_raw_output.txins) return tx_raw_output
def mint_or_burn_sign( cluster_obj: clusterlib.ClusterLib, new_tokens: List[TokenRecord], temp_template: str, sign_incrementally: bool = False, ) -> clusterlib.TxRawOutput: """Mint or burn tokens, depending on the `amount` value. Sign using skeys. Positive `amount` value means minting, negative means burning. """ _issuers_addrs = [t.issuers_addrs for t in new_tokens] issuers_addrs = set(itertools.chain.from_iterable(_issuers_addrs)) issuers_skey_files = {p.skey_file for p in issuers_addrs} token_mint_addr = new_tokens[0].token_mint_addr signing_key_files = list({*issuers_skey_files, token_mint_addr.skey_file}) # build and sign a transaction tx_files = clusterlib.TxFiles(signing_key_files=signing_key_files) mint = [ clusterlib.Mint( txouts=[ clusterlib.TxOut(address=t.token_mint_addr.address, amount=t.amount, coin=t.token) ], script_file=t.script, ) for t in new_tokens ] fee = cluster_obj.calculate_tx_fee( src_address=token_mint_addr.address, tx_name=temp_template, mint=mint, tx_files=tx_files, # TODO: workaround for https://github.com/input-output-hk/cardano-node/issues/1892 witness_count_add=len(issuers_skey_files), ) tx_raw_output = cluster_obj.build_raw_tx( src_address=token_mint_addr.address, tx_name=temp_template, mint=mint, tx_files=tx_files, fee=fee, ) # sign incrementally (just to check that it works) if sign_incrementally and len(signing_key_files) >= 1: out_file_signed = cluster_obj.sign_tx( tx_body_file=tx_raw_output.out_file, signing_key_files=signing_key_files[:1], tx_name=f"{temp_template}_sign0", ) # incrementally sign the already signed Tx with rest of required skeys for idx, skey in enumerate(signing_key_files[1:], start=1): out_file_signed = cluster_obj.sign_tx( tx_file=out_file_signed, signing_key_files=[skey], tx_name=f"{temp_template}_sign{idx}", ) else: out_file_signed = cluster_obj.sign_tx( tx_body_file=tx_raw_output.out_file, signing_key_files=tx_files.signing_key_files, tx_name=temp_template, ) # submit signed transaction cluster_obj.submit_tx(tx_file=out_file_signed, txins=tx_raw_output.txins) return tx_raw_output
def mint_or_burn_witness( cluster_obj: clusterlib.ClusterLib, new_tokens: List[TokenRecord], temp_template: str, invalid_hereafter: Optional[int] = None, invalid_before: Optional[int] = None, use_build_cmd: bool = False, sign_incrementally: bool = False, ) -> clusterlib.TxRawOutput: """Mint or burn tokens, depending on the `amount` value. Sign using witnesses. Positive `amount` value means minting, negative means burning. """ _issuers_addrs = [t.issuers_addrs for t in new_tokens] issuers_addrs = set(itertools.chain.from_iterable(_issuers_addrs)) issuers_skey_files = {p.skey_file for p in issuers_addrs} token_mint_addr = new_tokens[0].token_mint_addr signing_key_files = list({*issuers_skey_files, token_mint_addr.skey_file}) # create TX body mint = [ clusterlib.Mint( txouts=[ clusterlib.TxOut(address=t.token_mint_addr.address, amount=t.amount, coin=t.token) ], script_file=t.script, ) for t in new_tokens ] if use_build_cmd: mint_txouts = [ clusterlib.TxOut(address=t.token_mint_addr.address, amount=t.amount, coin=t.token) for t in new_tokens ] txouts = [ # meet the minimum required UTxO value clusterlib.TxOut(address=new_tokens[0].token_mint_addr.address, amount=2000_000), # leave out token burning records *[t for t in mint_txouts if t.amount > 0], ] tx_raw_output = cluster_obj.build_tx( src_address=token_mint_addr.address, tx_name=temp_template, txouts=txouts, fee_buffer=2000_000, mint=mint, invalid_hereafter=invalid_hereafter, invalid_before=invalid_before, witness_override=len(signing_key_files), ) else: fee = cluster_obj.calculate_tx_fee( src_address=token_mint_addr.address, tx_name=temp_template, mint=mint, # TODO: workaround for https://github.com/input-output-hk/cardano-node/issues/1892 witness_count_add=len(signing_key_files), ) tx_raw_output = cluster_obj.build_raw_tx( src_address=token_mint_addr.address, tx_name=temp_template, mint=mint, fee=fee, invalid_hereafter=invalid_hereafter, invalid_before=invalid_before, ) # sign incrementally (just to check that it works) if sign_incrementally and len(signing_key_files) >= 1: # create witness file for first required key witness_file = cluster_obj.witness_tx( tx_body_file=tx_raw_output.out_file, witness_name=f"{temp_template}_skey0", signing_key_files=signing_key_files[:1], ) # sign Tx using witness file tx_witnessed_file = cluster_obj.assemble_tx( tx_body_file=tx_raw_output.out_file, witness_files=[witness_file], tx_name=f"{temp_template}_sign0", ) # incrementally sign the already signed Tx with rest of required skeys for idx, skey in enumerate(signing_key_files[1:], start=1): tx_witnessed_file = cluster_obj.sign_tx( tx_file=tx_witnessed_file, signing_key_files=[skey], tx_name=f"{temp_template}_sign{idx}", ) else: # create witness file for each required key witness_files = [ cluster_obj.witness_tx( tx_body_file=tx_raw_output.out_file, witness_name=f"{temp_template}_skey{idx}", signing_key_files=[skey], ) for idx, skey in enumerate(signing_key_files) ] # sign Tx using witness files tx_witnessed_file = cluster_obj.assemble_tx( tx_body_file=tx_raw_output.out_file, witness_files=witness_files, tx_name=temp_template, ) # submit signed TX cluster_obj.submit_tx(tx_file=tx_witnessed_file, txins=tx_raw_output.txins) return tx_raw_output
def multisig_tx( cluster_obj: clusterlib.ClusterLib, temp_template: str, src_address: str, dst_address: str, amount: int, multisig_script: Path, payment_skey_files: List[Path], invalid_hereafter: Optional[int] = None, invalid_before: Optional[int] = None, script_is_src=False, ): """Build and submit multisig transaction.""" # record initial balances src_init_balance = cluster_obj.get_address_balance(src_address) dst_init_balance = cluster_obj.get_address_balance(dst_address) # create TX body destinations = [clusterlib.TxOut(address=dst_address, amount=amount)] witness_count_add = len(payment_skey_files) if script_is_src: # TODO: workaround for https://github.com/input-output-hk/cardano-node/issues/1892 witness_count_add += 5 ttl = cluster_obj.calculate_tx_ttl() fee = cluster_obj.calculate_tx_fee( src_address=src_address, tx_name=temp_template, txouts=destinations, ttl=ttl, witness_count_add=witness_count_add, ) tx_raw_output = cluster_obj.build_raw_tx( src_address=src_address, tx_name=temp_template, txouts=destinations, fee=fee, ttl=ttl, invalid_hereafter=invalid_hereafter, invalid_before=invalid_before, ) # create witness file for each key witness_files = [ cluster_obj.witness_tx( tx_body_file=tx_raw_output.out_file, witness_name=f"{temp_template}_skey{idx}", signing_key_files=[skey], ) for idx, skey in enumerate(payment_skey_files) ] if script_is_src: witness_files.append( cluster_obj.witness_tx( tx_body_file=tx_raw_output.out_file, witness_name=f"{temp_template}_script", script_file=multisig_script, )) # sign TX using witness files tx_witnessed_file = cluster_obj.assemble_tx( tx_body_file=tx_raw_output.out_file, witness_files=witness_files, tx_name=temp_template, ) # submit signed TX cluster_obj.submit_tx(tx_witnessed_file) cluster_obj.wait_for_new_block(new_blocks=2) # check final balances assert (cluster_obj.get_address_balance(src_address) == src_init_balance - tx_raw_output.fee - amount), f"Incorrect balance for source address `{src_address}`" assert (cluster_obj.get_address_balance(dst_address) == dst_init_balance + amount), f"Incorrect balance for script address `{dst_address}`"