Exemplo n.º 1
0
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
Exemplo n.º 3
0
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}`"