1

I am running into an error with the CSL Rust Lib when submitting a minting NFT tx. I am following a minimal example in JS https://gist.github.com/lovalabs/83d08796ab9ff65cbf188fbca8d03343 as a guide for the RUST library. I receive the following error when attempting to submit the built tx via the cardano-CLI:

Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (MissingScriptWitnessesUTXOW (fromList [ScriptHash "d47c1b40ca47ac8f1b0c0f01941acbc634dbd5896239a2ade9548557"]))),UtxowFailure (WrappedShelleyEraFailure (UtxoFailure (UtxosFailure (CollectErrors [NoRedeemer (Minting (PolicyID {policyID = ScriptHash "d47c1b40ca47ac8f1b0c0f01941acbc634dbd5896239a2ade9548557"})),NoWitness (ScriptHash "d47c1b40ca47ac8f1b0c0f01941acbc634dbd5896239a2ade9548557")]))))]) 

My RUST declarations are as follows:

Policy NativeScripts

 //Initialize 'NativeScript' for NFT Policy 
    let mut native_scripts = NativeScripts::new();
    let script_public_key = NativeScript::new_script_pubkey(&ScriptPubkey::new(&policy_public_key_hash));

    //Initialize 'TimelockExpiry' and 'NativeScript' 
    let timelock_expiry_fmt = TimelockExpiry::new_timelockexpiry(&BigNum::from_str("59634480").unwrap());
    let script_timelock = NativeScript::new_timelock_expiry(&timelock_expiry_fmt);

    //Add Public Key and Timelock 'NativeScript' to Collection of 'NativeScripts'    
    native_scripts.add(&script_public_key);
    native_scripts.add(&script_timelock);

    //Initialize 'ScriptAll' type of 'NativeScript' & Add 'NativeScripts' with script public key and timelock expiry
    let policy_script = NativeScript::new_script_all(&ScriptAll::new(&native_scripts));

    //Initialize 'PolicyID', 'AssetName', and 'Amount'
    let asset_name = AssetName::new("Rust-CSL-NFT-Mint".as_bytes().to_vec()).unwrap();
    let amount = Int::new(&BigNum::from_str("1").unwrap());

Builder & Witnesses

//Add 'NativeScript', 'AssetName', 'Amount' (Int), and 'TransactionOutputAmountBuilder' to 'TransactionBuilder'
    tx_builder.add_mint_asset_and_output_min_required_coin(&policy_script, &asset_name, amount, &tx_output_amount_builder).unwrap();    

    //Set 'ttl' for 'Transaction'
    tx_builder.set_ttl_bignum(&BigNum::from_str("59634480").unwrap());

    //Add 'TransactionInputs'
    tx_builder.add_key_input(&input_public_key_hash, &tx_input_1, &tx_value);

    //Add Change Wallet
    tx_builder.add_change_if_needed(&addr_1).unwrap();

    //Build Transaction
    let transaction = tx_builder.build_tx().unwrap();

    //Set 'TransactionWitnessSet'
    let mut vkey_witnesses: Vkeywitnesses = Vkeywitnesses::new();
    let tx_hash = hash_transaction(&transaction.body());
    let vkey_witness_wallet = make_vkey_witness(&tx_hash, &input_private_key);
    let vkey_witness_policy = make_vkey_witness(&tx_hash, &policy_private_key);
    vkey_witnesses.add(&vkey_witness_wallet);
    vkey_witnesses.add(&vkey_witness_policy);
    let mut tx_witness_set = TransactionWitnessSet::new();
    tx_witness_set.set_vkeys(&vkey_witnesses);
    tx_witness_set.set_native_scripts(&native_scripts);
    
    //Sign Transaction
    let signed_transaction = Transaction::new(&transaction.body(), &tx_witness_set, None);

I hope that I am missing something simple here. I have added the input and policy keys as witnesses and I have added the policy nativescripts to the tx_witness_set but have not had any success resolving the error. There is more than enough Test Ada in the utxo and I understand that the add_mint_asset_and_output_min_required_coin() handles the min fee and defines the PolicyID associated with the tx. Any help or guidance is greatly appreciated as I have not found any rust tutorials or examples for the CSL.

1 Answer 1

0

I was able to complete the NFT Minting successfully following a different JS demo as a reference https://github.com/Emurgo/cardano-serialization-lib/blob/master/doc/getting-started/minting-nfts.md There are zero RUST examples online for using the Cardano Serialization Library so I will post the code for any future Rustaceans in search of help.

//------------------------------------------NFT Policy------------------------------------------
    //Initialize 'NativeScript' for NFT Policy 
    let mut native_scripts = NativeScripts::new();

    //let script_public_key = NativeScript::new_script_pubkey(&ScriptPubkey::new(&policy_public_key_hash));
    let policy_addr = BaseAddress::new(NetworkInfo::testnet().network_id(), &StakeCredential::from_keyhash(&policy_public_key_hash), &StakeCredential::from_keyhash(&policy_public_key_hash)).to_address();
    let policy_keyhash = BaseAddress::from_address(&policy_addr).unwrap().payment_cred().to_keyhash().unwrap();
    let key_hash_script = NativeScript::new_script_pubkey(&ScriptPubkey::new(&policy_keyhash));
    native_scripts.add(&key_hash_script);

    //Initialize 'TimelockExpiry' and 'NativeScript' 
    let timelock_expiry_fmt = TimelockExpiry::new_timelockexpiry(&BigNum::from_str("59634480").unwrap());
    let script_timelock = NativeScript::new_timelock_expiry(&timelock_expiry_fmt);
    native_scripts.add(&script_timelock);

    let mint_script = NativeScript::new_script_all(&ScriptAll::new(&native_scripts));

    let addr = BaseAddress::new(NetworkInfo::testnet().network_id(), &StakeCredential::from_keyhash(&input_public_key_hash), &StakeCredential::from_keyhash(&input_public_key_hash)).to_address();
    let private_key_hash = BaseAddress::from_address(&addr).unwrap().payment_cred().to_keyhash().unwrap();
 //--------------------------------------Transaction Builder--------------------------------------
    //Initialize 'TransactionBuilder' from 'TransactionBuilderConfig'
    let mut tx_builder = TransactionBuilder::new(&tx_builder_config);

    //Add 'TransactionInputs'
    tx_builder.add_key_input(&private_key_hash, &tx_input_1, &tx_value);

    //Initialize 'PolicyID', 'AssetName', and 'Amount'
    let asset_name = AssetName::new("Rust-CSL-NFT-Mint".as_bytes().to_vec()).unwrap();
    let amount = Int::new(&BigNum::from_str("1").unwrap());
//------------------------------------Outputs (Wallet Addresses)---------------------------------
     //Initialize 'TransactionOutputAmountBuilder' from 'TransactionOutputBuilder'
     let tx_output_builder = TransactionOutputBuilder::new();     
     let tx_output_amount_builder = tx_output_builder.with_address(&addr).next().unwrap();

    //Add 'NativeScript', 'AssetName', 'Amount' (Int), and 'TransactionOutputAmountBuilder' to 'TransactionBuilder'
    tx_builder.add_mint_asset_and_output_min_required_coin(&mint_script, &asset_name, amount, &tx_output_amount_builder).unwrap();  

    //------------------------------------------NFT METADATA------------------------------------------
    //Generate Policy ID and Metadata
    let _policy_id = hex::encode(mint_script.hash().to_bytes());
    let metadata_input_string = String::from("{\"[d47c1b40ca47ac8f1b0c0f01941acbc634dbd5896239a2ade9548557]\": {\"[Rust-CSL-NFT-Mint]\": {\"name\": \"Rust-CSL-NFT-Mint-Example\",\"description\": \"Rust CSL NFT\",\"image\": \"bafkreibsko7qh472qkkwmk6fcfhbrhiuvzna5fkqzvak7gvgqosasaubi4\",\"type\": \"image\"}}}");
    let metadata = encode_json_str_to_metadatum(metadata_input_string.clone(), csl::metadata::MetadataJsonSchema::BasicConversions).expect("encode failed");
    let metadata_output_string = decode_metadatum_to_json_str(&metadata, csl::metadata::MetadataJsonSchema::BasicConversions).expect("decode failed");
    //println!("{}", metadata_output_string);

    //Set 'ttl' for 'Transaction'
    tx_builder.set_ttl_bignum(&BigNum::from_str("59634480").unwrap());

    //Set NFT 'MeatadatumLabel' (721)
    tx_builder.add_json_metadatum(&BigNum::from_str("721").unwrap(),metadata_output_string).unwrap();

        //Add Change Wallet
    tx_builder.add_change_if_needed(&addr).unwrap();

    let tx_body = tx_builder.build().unwrap();
    let tx_hash = hash_transaction(&tx_body);
    //println!("{:?}", hex::encode(&tx_hash.to_bytes()));

    let mut tx_witness_set = TransactionWitnessSet::new();
    let mut vkey_witnesses: Vkeywitnesses = Vkeywitnesses::new();
    vkey_witnesses.add(&make_vkey_witness(&tx_hash, &policy_private_key));
    vkey_witnesses.add(&make_vkey_witness(&tx_hash, &input_private_key));
    tx_witness_set.set_vkeys(&vkey_witnesses);
    tx_witness_set.set_native_scripts(&native_scripts);

    let mut witness_scripts = NativeScripts::new();
    witness_scripts.add(&mint_script);
    tx_witness_set.set_native_scripts(&witness_scripts);

    let unsigned_transaction = tx_builder.build_tx().unwrap();

    let signed_transaction = Transaction::new(&unsigned_transaction.body(), &tx_witness_set, unsigned_transaction.auxiliary_data()); 

https://explorer.cardano-testnet.iohkdev.io/en/address.html?address=addr_test1qpus2z0svc6n6dv64cryzdc695430lpkqvk5dsp6lltn8zteq5ylqe34856e4tsxgym35tftzl7rvqedgmqr4l7hxwys99g6gw

Hope this is useful for someone, I spent awhile searching for RUST examples and came up empty-handed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.