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 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 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}`"