I have locked ADA and assets into a script. I want to use the last transaction output and the ADA of a wallet as inputs and I want to have an output with some extra ADA locked and the datum changed
const settings = {
protocolParams: {
linearFee: {
minFeeA: "44",
minFeeB: "155381",
},
minUtxo: "4310",
poolDeposit: "500000000",
keyDeposit: "2000000",
maxValSize: 5000,
maxTxSize: 16384,
priceMem: 0.0577,
priceStep: 0.0000721,
coinsPerUtxoByte: "4310",
}
};
const initTransactionBuilder = () => {
const { protocolParams } = settings;
const txBuilder = TransactionBuilder.new(
TransactionBuilderConfigBuilder.new()
.fee_algo(LinearFee.new(BigNum.from_str(protocolParams.linearFee.minFeeA), BigNum.from_str(protocolParams.linearFee.minFeeB)))
.pool_deposit(BigNum.from_str(protocolParams.poolDeposit))
.key_deposit(BigNum.from_str(protocolParams.keyDeposit))
.coins_per_utxo_byte(BigNum.from_str(protocolParams.coinsPerUtxoByte))
.max_value_size(protocolParams.maxValSize)
.max_tx_size(protocolParams.maxTxSize)
.prefer_pure_change(true)
.build()
);
return txBuilder
};
const buildRedeemAdaFromPlutusScript = async (walletApi,
{ transactionIdLocked, transactionIndxLocked, lovelaceLocked, manualFee, CollatUtxos, newDatumStr, datumStr }) => {
const txBuilder = initTransactionBuilder();
const ScriptAddress = Address.from_bech32(settings.smartContract.addressScriptBech32);
const shelleyChangeAddress = Address.from_bech32(await walletApi.getChangeAddress());
let multiAsset = MultiAsset.new();
let assets = Assets.new()
assets.insert(
AssetName.new(Buffer.from(assetNameHex, "hex")),
BigNum.from_str(assetAmountToSend.toString())
);
multiAsset.insert(
ScriptHash.from_bytes(Buffer.from(assetPolicyIdHex, "hex")),
assets
);
const outputVal = 2 * lovelaceLocked - Number(manualFee);
const outputValStr = outputVal.toString();
let txOutputScriptBuilder = TransactionOutputBuilder.new();
txOutputScriptBuilder = txOutputScriptBuilder.with_address(ScriptAddress);
const dataHash = hash_plutus_data(PlutusData.new_integer(BigInt.from_str(newDatumStr)));
txOutputScriptBuilder = txOutputScriptBuilder.with_data_hash(dataHash)
txOutputScriptBuilder = txOutputScriptBuilder.next();
txOutputScriptBuilder = txOutputScriptBuilder.with_coin_and_asset(BigNum.from_str(outputValStr), multiAsset)
const txOutputScript = txOutputScriptBuilder.build();
txBuilder.add_output(txOutputScript)
txBuilder.add_input(
ScriptAddress,
TransactionInput.new(
TransactionHash.from_bytes(Buffer.from(transactionIdLocked, "hex")),
transactionIndxLocked.toString()),
Value.new_with_assets(BigNum.from_str(lovelaceLocked.toString()), multiAsset)
);
const { txOutputs: txUnspentOutputs } = await walletApi.getUtxos();
txBuilder.add_inputs_from(txUnspentOutputs, 2)
txBuilder.add_change_if_needed(shelleyChangeAddress)
txBuilder.set_fee(BigNum.from_str(Number(manualFee).toString()));
const txBody = txBuilder.build();
const scripts = PlutusScripts.new();
scripts.add(PlutusScript.from_bytes(Buffer.from(settings.smartContract.plutusScriptCborHex, "hex")));
const collateral = CollatUtxos;
const inputs = TransactionInputs.new();
collateral.forEach((utxo) => {
inputs.add(utxo.input());
});
const datum = PlutusData.new_integer(BigInt.from_str(datumStr));
const redeemers = Redeemers.new();
const redeemer = Redeemer.new(
RedeemerTag.new_spend(),
BigNum.from_str("0"),
datum,
ExUnits.new(
BigNum.from_str("7000000"),
BigNum.from_str("3000000000")
)
);
redeemers.add(redeemer);
const datums = PlutusList.new();
datums.add(datum);
const transactionWitnessSet = TransactionWitnessSet.new();
transactionWitnessSet.set_plutus_scripts(scripts);
transactionWitnessSet.set_plutus_data(datums);
transactionWitnessSet.set_redeemers(redeemers);
const cost_model_vals = [
205665, 812, 1, 1, 1000, 571, 0, 1, 1000, 24177, 4, 1, 1000, 32, 117366,
10475, 4, 23000, 100, 23000, 100, 23000, 100, 23000, 100, 23000, 100, 23000,
100, 100, 100, 23000, 100, 19537, 32, 175354, 32, 46417, 4, 221973, 511, 0, 1,
89141, 32, 497525, 14068, 4, 2, 196500, 453240, 220, 0, 1, 1, 1000, 28662, 4,
2, 245000, 216773, 62, 1, 1060367, 12586, 1, 208512, 421, 1, 187000, 1000,
52998, 1, 80436, 32, 43249, 32, 1000, 32, 80556, 1, 57667, 4, 1000, 10,
197145, 156, 1, 197145, 156, 1, 204924, 473, 1, 208896, 511, 1, 52467, 32,
64832, 32, 65493, 32, 22558, 32, 16563, 32, 76511, 32, 196500, 453240, 220, 0,
1, 1, 69522, 11687, 0, 1, 60091, 32, 196500, 453240, 220, 0, 1, 1, 196500,
453240, 220, 0, 1, 1, 806990, 30482, 4, 1927926, 82523, 4, 265318, 0, 4, 0,
85931, 32, 205665, 812, 1, 1, 41182, 32, 212342, 32, 31220, 32, 32696, 32,
43357, 32, 32247, 32, 38314, 32, 9462713, 1021, 10,
];
const costModel = CostModel.new();
cost_model_vals.forEach((x, i) => costModel.set(i, Int.new_i32(x)));
const costModels = Costmdls.new();
costModels.insert(Language.new_plutus_v1(), costModel);
const scriptDataHash = hash_script_data(redeemers, costModels, datums);
txBody.set_script_data_hash(scriptDataHash);
txBody.set_collateral(inputs);
const baseAddress = BaseAddress.from_address(shelleyChangeAddress);
const requiredSigners = Ed25519KeyHashes.new();
requiredSigners.add(baseAddress.payment_cred().to_keyhash());
txBody.set_required_signers(requiredSigners);
const tx = Transaction.new(
txBody,
TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes())
);
let txVkeyWitnesses = await walletApi.api.signTx(Buffer.from(tx.to_bytes(), "utf8").toString("hex"), true);
txVkeyWitnesses = TransactionWitnessSet.from_bytes(Buffer.from(txVkeyWitnesses, "hex"));
transactionWitnessSet.set_vkeys(txVkeyWitnesses.vkeys());
const signedTx = Transaction.new(
tx.body(),
transactionWitnessSet
);
const submittedTxHash = await walletApi.api.submitTx(Buffer.from(signedTx.to_bytes(), "utf8").toString("hex"));
return { submittedTxHash };
};
Error:
""transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (UtxoFailure (FromAlonzoUtxoFail (ValueNotConservedUTxO (Value 2258970370 (fromList [(PolicyID {policyID = ScriptHash \"9560a89a549f66bb02c4a04525e8e367283f566ec0e34e1a31cf3aa2\"},fromList [(4a616c61436f696e,999962)])])) (Value 2259870370 (fromList [(PolicyID {policyID = ScriptHash \"9560a89a549f66bb02c4a04525e8e367283f566ec0e34e1a31cf3aa2\"},fromList [(4a616c61436f696e,999962)])])))))])""