cardano-serialization-lib
cardano-serialization-lib copied to clipboard
Claiming token from smart contract that was locked using CSL 11.0.0-rc.6
Recently on 21st of July I was able to lock NFT asset in smart contract.
cardano-cli query utxo --address addr_test1wz4tdxj4rlynr3t975nzh7djen4gge23m9fwnpf4xz0r7wgulazkc --testnet-magic 1097911063 | findstr 43727970746f44696e6f3036333039
1af28a9c20dd3b76372d148f670a8ca80421bb51a07df087d40a2c406c429fd6 0 2000000 lovelace + 1 ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3.43727970746f44696e6f3036333039 + TxOutDatumHash ScriptDataInBabbageEra "8dc802b6f6c94ed951dbca33820f2f17dd9912ed764364d201a0cfaf464d1d70"
I created createTransactionBuilder method that returns TransacionBuilder object:
export const createTransactionBuilder = async (protocolParams: CardanoProtocolParameters, exUnitPrices: CardanoSerialization.ExUnitPrices | undefined = undefined) => {
let configBuilder = TransactionBuilderConfigBuilder.new()
.fee_algo(LinearFee.new(BigNum.from_str(protocolParams.min_fee_a.toString()), BigNum.from_str(protocolParams.min_fee_b.toString())))
.pool_deposit(BigNum.from_str(protocolParams.pool_deposit.toString()))
.key_deposit(BigNum.from_str(protocolParams.key_deposit.toString()))
.coins_per_utxo_byte(BigNum.from_str(protocolParams.coins_per_utxo_word))
.max_value_size(protocolParams.max_val_size)
.max_tx_size(protocolParams.max_tx_size)
.prefer_pure_change(true)
if (exUnitPrices) {
configBuilder = configBuilder.ex_unit_prices(exUnitPrices)
}
const txBuilder = TransactionBuilder.new(
configBuilder.build()
);
return txBuilder
}
using following offer method I was able to lock NFT token mentioned on the begining
const nftMoveFixedPrice = "2000000";
export const offer = async (api: CardanoApi, policyId: string, assetName: string, askingPrice: string): Promise<string> => {
const cardano = cardanoApiAdapter(api)
const protocolParameters = await getProtocolProtocolParams()
const txBuilder = await createTransactionBuilder(protocolParameters)
const scriptAddress = getContractAddress();
const selfAddress = await cardano.getWalletAddress()
const baseAddress = BaseAddress.from_address(selfAddress)!
const pkh = toHex(baseAddress.payment_cred().to_keyhash()?.to_bytes() as Uint8Array);
const offerDatum = createSalesOfferDatum(pkh, askingPrice, policyId, assetName);
const plutusData = toPlutusData(offerDatum);
const offerDatumHash = hash_plutus_data(plutusData);
let txOutputBuilder = TransactionOutputBuilder.new();
txOutputBuilder = txOutputBuilder.with_address(scriptAddress);
txOutputBuilder = txOutputBuilder.with_data_hash(offerDatumHash)
const txOutputAmountBuilder = txOutputBuilder.next();
const lovelaceWithAsset = getContractOutput(nftMoveFixedPrice, policyId, assetName)
const txOutputAmountBuilderWithCoins = txOutputAmountBuilder.with_value(lovelaceWithAsset)
const txOutput = txOutputAmountBuilderWithCoins.build();
const aux_data: AuxiliaryData = await addOfferMetadata(txBuilder, selfAddress, askingPrice, assetName, policyId, "offer")
txBuilder.add_output(txOutput)
const txUnspentOutputs = TransactionUnspentOutputs.new();
const walletOutputs = await cardano.getUtxos();
walletOutputs.forEach(utxo => txUnspentOutputs.add(utxo))
txBuilder.add_inputs_from(txUnspentOutputs, 3)
txBuilder.add_change_if_needed(selfAddress)
const txBody = txBuilder.build();
const transactionWitnessSet = TransactionWitnessSet.new();
const tx = Transaction.new(
txBody,
TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes()),
aux_data
)
let signedtxVkeyWitnesses: TransactionWitnessSet
try {
signedtxVkeyWitnesses = await cardano.signTx(tx, true);
}
catch (err) {
throw handleSignError(err)
}
transactionWitnessSet.set_vkeys(signedtxVkeyWitnesses.vkeys()!);
const signedTx = Transaction.new(
tx.body(),
transactionWitnessSet,
tx.auxiliary_data()
);
try {
const txHash = await cardano.submitTx(signedTx);
console.log(`txHash for sales offer: ${txHash}`);
return txHash
} catch (err) {
appInsights.trackException({ exception: err as Error }, {
sellerAddress: selfAddress.to_bech32(),
sellerPkh: pkh,
policyId: policyId,
assetName: assetName,
price: askingPrice,
method: "offer"
});
console.log(err)
throw err;
}
}
Today I wanted to test cancel operation (retrieve NFT from SC):
export const cancel = async (api: CardanoApi, policyId: string, assetName: string): Promise<string> => {
const cardano = cardanoApiAdapter(api)
const protocolParameters = await getProtocolProtocolParams()
//Temporary pass explicitely values for exUnitPrices
const exUnitPrices = ExUnitPrices.new(UnitInterval.new(BigNum.from_str("577"), BigNum.from_str("10000")), UnitInterval.new(BigNum.from_str("721"), BigNum.from_str("10000000")))
const txBuilder = await createTransactionBuilder(protocolParameters, exUnitPrices)
const scriptAddress = getContractAddress();
const unspentOutput = await getUnspentTransactionUtxoForNft(getContractAddress(), policyId, assetName);
const selfAddress = Address.from_bech32(unspentOutput.metadata?.addr.join("") as string)
const baseAddress = BaseAddress.from_address(selfAddress)!
const pkh = toHex(baseAddress.payment_cred().to_keyhash()?.to_bytes() as Uint8Array);
const scripts = getContractScript()
const contractAssetOutput = await getContractOutput(nftMoveFixedPrice, policyId, assetName)
let txOutputBuilder = TransactionOutputBuilder.new();
txOutputBuilder = txOutputBuilder.with_address(selfAddress);
let txOutputBuilderWithAmount = txOutputBuilder.next();
txOutputBuilderWithAmount = txOutputBuilderWithAmount.with_value(contractAssetOutput)
const txOutput = txOutputBuilderWithAmount.build();
const aux_data: AuxiliaryData = await addOfferMetadata(txBuilder, selfAddress, unspentOutput.metadata?.price as string, assetName, policyId, "cancel")
txBuilder.add_output(txOutput)
const scriptInputIndex = unspentOutput.scriptUtxo.input().index()
console.log(`scriptInputIndex ${scriptInputIndex}`)
const salesOfferDatum = createSalesOfferDatum(pkh, unspentOutput.metadata?.price as string, policyId, assetName);
const datum = toPlutusData(salesOfferDatum);
const datumHash = hash_plutus_data(datum);
console.log(`datumHash: ${toHex(datumHash.to_bytes())}`)
const datumList = PlutusList.new();
datumList.add(datum);
const redeemers = Redeemers.new();
const redeemer = createRedeemer(scriptInputIndex, RedeemerType.Close)
redeemers.add(redeemer);
const plutusWitness = PlutusWitness.new(scripts.get(0), datum, redeemer)
txBuilder.add_plutus_script_input(
plutusWitness,
unspentOutput.scriptUtxo.input(),
contractAssetOutput
)
const txUnspentOutputs = TransactionUnspentOutputs.new();
const walletOutputs = await cardano.getUtxos();
walletOutputs.forEach(utxo => txUnspentOutputs.add(utxo))
txBuilder.add_inputs_from(txUnspentOutputs, 2)
txBuilder.add_change_if_needed(selfAddress)
const txBody = txBuilder.build();
// Tx witness
const transactionWitnessSet = TransactionWitnessSet.new();
transactionWitnessSet.set_plutus_scripts(scripts)
transactionWitnessSet.set_plutus_data(datumList)
transactionWitnessSet.set_redeemers(redeemers)
const costModels = TxBuilderConstants.plutus_vasil_cost_models();
const scriptDataHash = hash_script_data(redeemers, costModels, datumList);
console.log(`scriptDataHash: ${toHex(scriptDataHash.to_bytes())}`)
txBody.set_script_data_hash(scriptDataHash);
const collateral = await getCollateralUnspentTransactionOutput(api)
const collateralInputs = TransactionInputs.new();
collateral.forEach((utxo) => {
collateralInputs.add(utxo.input());
});
txBody.set_collateral(collateralInputs)
const requiredSigners = Ed25519KeyHashes.new();
requiredSigners.add(baseAddress.payment_cred().to_keyhash() as Ed25519KeyHash);
txBody.set_required_signers(requiredSigners);
const transaction = Transaction.new(
txBody,
TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes()),
aux_data
)
let signedtxVkeyWitnesses: TransactionWitnessSet
try {
signedtxVkeyWitnesses = await cardano.signTx(transaction, true);
}
catch (err) {
throw handleSignError(err)
}
transactionWitnessSet.set_vkeys(signedtxVkeyWitnesses.vkeys()!);
const signedTx = Transaction.new(
transaction.body(),
transactionWitnessSet,
transaction.auxiliary_data()
);
//logTx(signedTx)
try
{
let txHash = await cardano.submitTx(signedTx);
console.log(`cancel txhash: ${txHash}`)
return txHash
} catch (err) {
appInsights.trackException({ exception: err as Error }, {
sellerAddress: selfAddress.to_bech32(),
sellerPkh: pkh,
policyId: policyId,
assetName: assetName,
price: unspentOutput.metadata?.price as string,
method: "cancel"
});
console.log(err)
throw err;
}
}
However I see exception:
""transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (PPViewHashesDontMatch (SJust (SafeHash "776295c74d196814e33ea5a3d5b148243b6e7318cf3f1dd8e67bbf7597fbe7cb")) (SJust (SafeHash "cf442fa6f31027353659522764941c71b732702296b6f400c977a4dc5628f872")))),UtxowFailure (UtxoFailure (FromAlonzoUtxoFail (FeeTooSmallUTxO (Coin 418688) (Coin 414288))))])""
It seems that there are two problems:
- Fee is not correctly calculated despite I passed to createTransactionBuilder(protocolParameters, exUnitPrices) exUnitPrices. For values mem and CPU required for redeemer I checked what haskel outputed while compiling SC ExBudget {exBudgetCPU = ExCPU 18221176, exBudgetMemory = ExMemory 61300}
I passed the values for ExCPU and ExMemory into ExUnits.new(BigNum.from_str("61300"), BigNum.from_str("18221176")) for cancel redeemer
const createRedeemer = (index: number, redeemerType: RedeemerType) => {
//buy.json - {"constructor":0,"fields":[]}
//update.json - {"constructor":1,"fields":[]}
//close.json - {"constructor":2,"fields":[]} it is redeemer for cancelling
const redeemerData = PlutusData.new_constr_plutus_data(
ConstrPlutusData.new(
BigNum.from_str(redeemerType.toString()),
PlutusList.new()
)
);
const exUnits = redeemerType == RedeemerType.Close ?
ExUnits.new(BigNum.from_str("61300"), BigNum.from_str("18221176"))
:
ExUnits.new(BigNum.from_str("7000000"), BigNum.from_str("3000000000"))
//temp check if it is going to help to cancel in ccvault
// const exUnits = ExUnits.new(BigNum.from_str("7000000"), BigNum.from_str("3000000000"))
const r = Redeemer.new(
RedeemerTag.new_spend(),
toBigNum(index),
redeemerData,
exUnits
);
return r;
}
- I'm not sure why I'm getting PPViewHashesDontMatch.
Full code for the marketplace.ts (and depending typescript files) where offer method (locking asset in SC) and cancel method (retrieving from SC) exists can be found here marketplace_app.zip
With help from @abdelkrimdev I was able to change cancel method and retrieve NFT from smart contract only once here is transaction id: https://testnet.cardanoscan.io/transaction/e06d6a351ab3291629d60b5cf24608209307216118a612a280df26f6793c5198?tab=utxo
and the code changes we made:
export const cancel = async (api: CardanoApi, policyId: string, assetName: string): Promise<string> => {
const cardano = cardanoApiAdapter(api)
const protocolParameters = await getProtocolProtocolParams()
//Temporary pass explicitely values for exUnitPrices
const exUnitPrices = ExUnitPrices.new(UnitInterval.new(BigNum.from_str("577"), BigNum.from_str("10000")), UnitInterval.new(BigNum.from_str("721"), BigNum.from_str("10000000")))
const txBuilder = await createTransactionBuilder(protocolParameters, exUnitPrices)
const scriptAddress = getContractAddress();
const unspentOutput = await getUnspentTransactionUtxoForNft(getContractAddress(), policyId, assetName);
const selfAddress = Address.from_bech32(unspentOutput.metadata?.addr.join("") as string)
const baseAddress = BaseAddress.from_address(selfAddress)!
const pkh = toHex(baseAddress.payment_cred().to_keyhash()?.to_bytes() as Uint8Array);
const scripts = getContractScript()
const contractAssetOutput = await getContractOutput(nftMoveFixedPrice, policyId, assetName)
let txOutputBuilder = TransactionOutputBuilder.new();
txOutputBuilder = txOutputBuilder.with_address(selfAddress);
let txOutputBuilderWithAmount = txOutputBuilder.next();
txOutputBuilderWithAmount = txOutputBuilderWithAmount.with_value(contractAssetOutput)
const txOutput = txOutputBuilderWithAmount.build();
const aux_data: AuxiliaryData = await addOfferMetadata(txBuilder, selfAddress, unspentOutput.metadata?.price as string, assetName, policyId, "cancel")
txBuilder.add_output(txOutput)
const scriptInputIndex = unspentOutput.scriptUtxo.input().index()
console.log(`scriptInputIndex ${scriptInputIndex}`)
const salesOfferDatum = createSalesOfferDatum(pkh, unspentOutput.metadata?.price as string, policyId, assetName);
const datum = toPlutusData(salesOfferDatum);
const datumHash = hash_plutus_data(datum);
console.log(`datumHash: ${toHex(datumHash.to_bytes())}`)
const datumList = PlutusList.new();
datumList.add(datum);
const redeemers = Redeemers.new();
const redeemer = createRedeemer(scriptInputIndex, RedeemerType.Close)
redeemers.add(redeemer);
const plutusWitness = PlutusWitness.new(scripts.get(0), datum, redeemer)
txBuilder.add_plutus_script_input(
plutusWitness,
unspentOutput.scriptUtxo.input(),
contractAssetOutput
)
const collateral = await getCollateralUnspentTransactionOutput(api)
var txInputBuilder = TxInputsBuilder.new()
collateral.forEach((utxo) => {
txInputBuilder.add_input(utxo.output().address(), utxo.input(), utxo.output().amount())
});
txBuilder.add_required_signer(baseAddress.payment_cred().to_keyhash() as Ed25519KeyHash)
const costModels = TxBuilderConstants.plutus_vasil_cost_models();
txBuilder.calc_script_data_hash(costModels)
const txUnspentOutputs = TransactionUnspentOutputs.new();
const walletOutputs = await cardano.getUtxos();
walletOutputs.forEach(utxo => txUnspentOutputs.add(utxo))
txBuilder.add_inputs_from(txUnspentOutputs, 2)
txBuilder.set_collateral(txInputBuilder)
txBuilder.add_change_if_needed(selfAddress)
const tx = txBuilder.build_tx();
const transactionWitnessSet = TransactionWitnessSet.from_bytes(tx.witness_set().to_bytes());
let signedtxVkeyWitnesses: TransactionWitnessSet
try {
signedtxVkeyWitnesses = await cardano.signTx(tx, true);
}
catch (err) {
throw handleSignError(err)
}
transactionWitnessSet.set_vkeys(signedtxVkeyWitnesses.vkeys()!);
const signedTx = Transaction.new(
tx.body(),
transactionWitnessSet,
tx.auxiliary_data()
);
//logTx(signedTx)
try
{
let txHash = await cardano.submitTx(signedTx);
console.log(`cancel txhash: ${txHash}`)
return txHash
} catch (err) {
appInsights.trackException({ exception: err as Error }, {
sellerAddress: selfAddress.to_bech32(),
sellerPkh: pkh,
policyId: policyId,
assetName: assetName,
price: unspentOutput.metadata?.price as string,
method: "cancel"
});
console.log(err)
throw err;
}
}
The problem I see now is that once I locked same token again in SC and when I tried to retrieve it I'm getting now:
transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (PPViewHashesDontMatch (SJust (SafeHash "cf442fa6f31027353659522764941c71b732702296b6f400c977a4dc5628f872")) (SJust (SafeHash "e6129f50a866d19d95bc9c95ee87b57a9e695c05d92ba2746141b03c15cf5f70"))))])
Is it related to revert from cardano-node 1.35 to version 1.34.1?
This is transaction body that I'm trying to submit:
84a70082825820e53be52539d82c67f01922ec01e0bb81670e519d09d76b6b5f05edacef36899202825820f074add7bf053d735b42d2d2f31ea6f38fda3717d73c29b257474686e04fb5620001828258390045f6a506a49a38263c4a8bbb2e1e369dd8732fb1f9a281f3e88383878727ae504f79d260b6024ac8590c934899b65734d835378badd32300821a001e8480a1581cee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3a14f43727970746f44696e6f3036333039018258390045f6a506a49a38263c4a8bbb2e1e369dd8732fb1f9a281f3e88383878727ae504f79d260b6024ac8590c934899b65734d835378badd323001a72cbd99b021a0006645c0758206b0c01fa274ac5011e649770211b9cd595d006b94a9258ee2e919289e0d98cba0b5820cf442fa6f31027353659522764941c71b732702296b6f400c977a4dc5628f8720d81825820ff02bee5a73b1f7b5d8994ad4ea6c90cc0612d641344acece5b4bf459ce582ab000e81581c45f6a506a49a38263c4a8bbb2e1e369dd8732fb1f9a281f3e8838387a40081825820729b9d4d9df2d95ef199ec817242534f9e649fef8fccfce5880b909ae10efcdd584073d671febacb14746c262fe827fbf0dde25a97f28baf47e1df9ae6273b2dac9763020f2416c787da049dcc2750a957df7623d98d2f1dd2c073fb13cec037f60e038159139d59139a010000332332233322233223322323233322232333222323333333322222222323332223233332222323233223233322232333222323233223322323233333222223322332233223322332233222232323232232232325335303633300b3333573466e1cd55cea804a400046666444466660b20080060040026eb8d5d0a8049bad35742a0106eb8d5d0a8039bae357426ae89401c8d4130d4c134cd5ce2481035054310004e499263333573466e1d40112002205223333573466e1d40152000205423504d35304e335738921035054310004f49926498cccd5cd19b8735573aa004900011980719191919191919191919191999ab9a3370e6aae75402920002333333333301c33502a232323333573466e1cd55cea80124000466044607a6ae854008c0bcd5d09aba2500223505c35305d3357389201035054310005e49926135573ca00226ea8004d5d0a80519a8150159aba150093335503175ca0606ae854020ccd540c5d728181aba1500733502a04635742a00c66a05466aa0ae09eeb4d5d0a8029919191999ab9a3370e6aae754009200023350243232323333573466e1cd55cea80124000466a05866a08aeb4d5d0a80118251aba135744a00446a0c06a60c266ae712401035054310006249926135573ca00226ea8004d5d0a8011919191999ab9a3370e6aae7540092000233502a33504575a6ae854008c128d5d09aba250022350603530613357389201035054310006249926135573ca00226ea8004d5d09aba2500223505c35305d3357389201035054310005e49926135573ca00226ea8004d5d0a80219a8153ae35742a00666a05466aa0aeeb88004d5d0a801181e1aba135744a00446a0b06a60b266ae71241035054310005a49926135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135573ca00226ea8004d5d0a8011919191999ab9a3370ea002900311810981f1aba135573ca00646666ae68cdc3a801240084604060906ae84d55cf280211999ab9a3370ea00690011181018199aba135573ca00a46666ae68cdc3a80224000460466eb8d5d09aab9e50062350533530543357389201035054310005549926499264984d55cea80089baa001357426ae8940088d4130d4c134cd5ce249035054310004e49926104d13504b35304c3357389201035054350004d4984d55cf280089baa001135573a6ea80044d5d1280089aba25001135573ca00226ea80048848cc00400c0088004888888888848cccccccccc00402c02802402001c01801401000c00880048848cc00400c008800448848cc00400c0084800448848cc00400c0084800448848cc00400c00848004848888c010014848888c00c014848888c008014848888c004014800448c88c008dd6000990009aa81c911999aab9f0012500e233500d30043574200460066ae880080cc8c8c8c8cccd5cd19b8735573aa006900011998039919191999ab9a3370e6aae754009200023300d303135742a00466a02605a6ae84d5d1280111a81b1a981b99ab9c491035054310003849926135573ca00226ea8004d5d0a801999aa805bae500a35742a00466a01eeb8d5d09aba25002235032353033335738921035054310003449926135744a00226aae7940044dd50009110919980080200180110009109198008018011000899aa800bae75a224464460046eac004c8004d540cc88c8cccd55cf80112804919a80419aa81898031aab9d5002300535573ca00460086ae8800c0b84d5d08008891001091091198008020018900089119191999ab9a3370ea002900011a80418029aba135573ca00646666ae68cdc3a801240044a01046a0526a605466ae712401035054310002b499264984d55cea80089baa001121223002003112200112001232323333573466e1cd55cea8012400046600c600e6ae854008dd69aba135744a00446a0466a604866ae71241035054310002549926135573ca00226ea80048848cc00400c00880048c8cccd5cd19b8735573aa002900011bae357426aae7940088d407cd4c080cd5ce24810350543100021499261375400224464646666ae68cdc3a800a40084a00e46666ae68cdc3a8012400446a014600c6ae84d55cf280211999ab9a3370ea00690001280511a8111a981199ab9c490103505431000244992649926135573aa00226ea8004484888c00c0104488800844888004480048c8cccd5cd19b8750014800880188cccd5cd19b8750024800080188d4068d4c06ccd5ce249035054310001c499264984d55ce9baa0011220021220012001232323232323333573466e1d4005200c200b23333573466e1d4009200a200d23333573466e1d400d200823300b375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c46601a6eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc048c050d5d0a8049bae357426ae8940248cccd5cd19b875006480088c050c054d5d09aab9e500b23333573466e1d401d2000230133016357426aae7940308d407cd4c080cd5ce2481035054310002149926499264992649926135573aa00826aae79400c4d55cf280109aab9e500113754002424444444600e01044244444446600c012010424444444600a010244444440082444444400644244444446600401201044244444446600201201040024646464646666ae68cdc3a800a400446660106eb4d5d0a8021bad35742a0066eb4d5d09aba2500323333573466e1d400920002300a300b357426aae7940188d4040d4c044cd5ce2490350543100012499264984d55cea80189aba25001135573ca00226ea80048488c00800c888488ccc00401401000c80048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e500423500a35300b3357389201035054310000c499264984d55cea80089baa001212230020032122300100320011122232323333573466e1cd55cea80124000466aa016600c6ae854008c014d5d09aba25002235007353008335738921035054310000949926135573ca00226ea8004498480048004448848cc00400c0084480044880084880048004888848cccc00401401000c0088004448c8c00400488cc00cc008008004cc8c8cc88cc88c8cc88c8c8c8c8c8ccc888c8c8cc88c8c8ccc888c8c8cccc8888c8cc88c8c8c8c8c8c8c8c8cc88ccc888c8ccc888ccc888cccccccc88888888cc88ccccc88888cccc8888cc88cc88cc88ccc888cc88cc88cc88cc88cc88c8c8c888c8c8c888c94cd4c0e400c54cd4c1614cd4c160cc0fcc17cccc024ccd54c1204800541114144cc02c021400522010048810053353058330405004505c1505c15004105a133573892010c466565206e6f7420706169640005915335305853353058333573466e1cccc024ccd54c1204800541114144cc02d4cd4d413cd4c0394004888888888800c4c174588854cd4d41440044008884c184594004d4c0f001c8888008d4c0f001c8888005200205a059105a13357389210c57726f6e6720696e7075747300059153353058533530583303f305f33300933355304812001504450513300b35303c007222200450014881004881003322353506200222353506400322330493370066e08010004cdc100100199b820030013322353506200222353506400322330493370266e08010004cdc100100199b82003001305f500653353058330405005505e1505e15005305f482024bd00441684cd5ce24810f53656c6c6572206e6f74207061696400059153353058333573466e1cc8cc8004c8004ccd54c13c48004c8cd415c88ccd415c00c004008d4150004cd4158888c00cc008004800488cdc0000a40040029000199119180099aa981d8900091a980a000910009a9808a8021111111111005190009aa83511299a9a829800880191099299a982f99911a980e801111a980f801911919a9821802919a98220021299a9834199ab9a3371e0040020d40d22a00620d240d2466a608800840d24a66a60d0666ae68cdc78010008350348a80188348a99a9a81180190a99a9a8120011099a9820801119a9821001119a9823001119a98238011198348010009036119a9823801103611983480100091103611119a98220021036111299a9836999ab9a3370e00c0060de0dc2a66a60da666ae68cdc38028010378370999ab9a3370e0080020de0dc20dc20dc20ce2a66a6a046002420ce20ce6a603200644400666038607a6a6aa0d86a6026012446a602e0044444444444a66a6a052a6666a606c01642a05642a05642a05642666aa60c424002a03c46a604a00244a66a60dea66a60de666ae68cdc79a981f801110011a981f802110010388380999ab9a3370e6a607e004440026a607e008440020e20e020e026a05e0062a05c016426a6048002446a60500024446a605a0064466a60a0004460fc2c4a66a6a0640084266aa10602004002260fc2c260ea2c44004a03c26600e00600220026008002a0a0a0a2900102d02c882d099ab9c49120547279696e6720746f2067726162206d6f7265207468616e206f6e65204e4654000591059105910591533530583322353010002222222222253353502233355305a120015016253353065333573466e3c03000419c1984d40940045409000c8419c4194d4c03000888008d4c0f001c888801041684cd5ce249204e6f2072696768747320746f20706572666f726d207468697320616374696f6e00059135300b0012200213303e3303a4801120c801305b353038003222200313303d330394801120c801305a5001135303600122220032223232300100532001355063223353504c0014800088d4d54190008894cd4c164ccd5cd19b8f00200905b05a130070011300600332001355062223353504b0014800088d4d5418c008894cd4c160ccd5cd19b8f00200705a059100113006003133504b2253353500e002210031001500d223530050012222222222333553049120012235301500222235301a00322335303d002253353061333573466e3c05000418c1884cd416401401c401c801d41480248848cc00400c0088004888888888848cccccccccc00402c02802402001c01801401000c00880048848cc00400c008800488848ccc00401000c00880048848cc00400c008800448488c00800c44880044800448848cc00400c0084800448848cc00400c0084800448848cc00400c00848004484888c00c010448880084488800448004848888c010014848888c00c014848888c008014848888c00401480048848cc00400c0088004848888888c01c0208848888888cc018024020848888888c014020488888880104888888800c8848888888cc0080240208848888888cc00402402080048488c00800c888488ccc00401401000c80048488c00800c8488c00400c8004c8004d540c08844894cd4d406c00454074884cd4078c010008cd54c018480040100044880084880048004888848cccc00401401000c008800488cc01ccdc1001299a980e199ab9a3370e002900000f00e8a40002a66a6038666ae68cdc4800a400003a03c29001099b814800120025335301c333573466e20005200001e01d13370290000008800911a9a811801111a9a8128019119299a9810199ab9a3370e00a0060440422a66a6040666ae68cdc380200101101088110a8008a8008a99a980f999980400200180100088100810911a9a811001111a9a8120019119998038020018010009111199ab9a3371266e08010004cdc100100180e80e111a9a810001111a9a811001911980399b82004002337040060024464a66a6030666ae68cdc38012400003403226a04e6a604666ae71240103505433000244984cd4084cdc2001a80099b84002500113301653353017333573466e20009200001901813370290000010801299a980b999ab9a33710002900000c80c099b81480000044004488cd54c02c480048d4d5409000488cd5409c008cd54c038480048d4d5409c00488cd540a8008ccd4d540340048cc0812000001223302100200123302000148000004cd54c02c480048d4d5409000488cd5409c008ccd4d540280048cd54c03c480048d4d540a000488cd540ac008d5404400400488ccd5540200640080048cd54c03c480048d4d540a000488cd540ac008d5403c004004ccd55400c050008004444888ccd54c018480054038cd54c02c480048d4d5409000488cd5409c008d54034004ccd54c0184800488d4d54094008894cd4c068ccd54c04048004c8cd406088ccd4d402c00c88008008004d4d402400488004cd4024894cd4c0700084078400406c8d4d540a000488cc028008014018400c4cd404801000d403c004cd54c02c480048d4d5409000488c8cd540a000cc004014c8004d540a4894cd4d40480044d5403400c884d4d540a8008894cd4c07ccc0300080204cd5404801c0044c01800c00848848cc00400c00848004c8004d5408088448894cd4d40300044008884cc014008ccd54c01c480040140100044484888c00c01044884888cc0080140104484888c004010448004c8004d5406c8844894cd4d401800454020884cd4024c010008cd54c01848004010004c8004d5406888448894cd4d40180044d402400c884ccd4030014c010008ccd54c01c480040140100044488008488488cc00401000c4800448d4d400c0048800448d4d40080048800848848cc00400c0084800488ccd5cd19b8f0020010060053200135501122253353004333573466e1c005200000600510021330030013370a00400224400424400240024466e000080044c00d2080897a26130014820225e88cd400c00520021221233001003002120012350063530023357389201024c6700003498480048004448848cc00400c008448004498448c8c00400488cc00cc00800800522011ce2a206cf1f33c8bb90722b6fd92f747911485954f0562faae0b16bc00001049fd8799f581c45f6a506a49a38263c4a8bbb2e1e369dd8732fb1f9a281f3e88383871a03938700581cee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb34f43727970746f44696e6f3036333039ffff0581840001d87a808219ef741a01160878f5a1190195a56461646472827840616464725f746573743171707a6c64666778356a6472736633756632396d6b74733778367761737565306b3875363971306e617a70633870753879376839716e782c6d653666737476716a3265707673657936676e786d397764786378356d636874776e79767171733736376a326561737365746f43727970746f44696e6f3036333039626f706663616e63656c66706f6c69637978386565386533373637366636656262386530333164666634393366383866663731316432346161363836363661303964363166316433666233657072696365683630303030303030
More update: I tried using:
const costModels = TxBuilderConstants.plutus_default_cost_models();
txBuilder.calc_script_data_hash(costModels)
I'm getting exception:
message: ""transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (PPViewHashesDontMatch (SJust (SafeHash \"8fef0878373b82fd419669a22c716a717d62c783f41a0021e922096eebc14ec5\")) (SJust (SafeHash \"e6129f50a866d19d95bc9c95ee87b57a9e695c05d92ba2746141b03c15cf5f70\"))))])""
tried using
const costModels = TxBuilderConstants.plutus_vasil_cost_models();
txBuilder.calc_script_data_hash(costModels)
I'm getting this exception:
message: ""transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (PPViewHashesDontMatch (SJust (SafeHash \"cf442fa6f31027353659522764941c71b732702296b6f400c977a4dc5628f872\")) (SJust (SafeHash \"e6129f50a866d19d95bc9c95ee87b57a9e695c05d92ba2746141b03c15cf5f70\"))))])""
More update: I tried using:
const costModels = TxBuilderConstants.plutus_default_cost_models(); txBuilder.calc_script_data_hash(costModels)I'm getting exception:
message: ""transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (PPViewHashesDontMatch (SJust (SafeHash "8fef0878373b82fd419669a22c716a717d62c783f41a0021e922096eebc14ec5")) (SJust (SafeHash "e6129f50a866d19d95bc9c95ee87b57a9e695c05d92ba2746141b03c15cf5f70"))))])""
tried using
const costModels = TxBuilderConstants.plutus_vasil_cost_models(); txBuilder.calc_script_data_hash(costModels)I'm getting this exception:
message: ""transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (PPViewHashesDontMatch (SJust (SafeHash "cf442fa6f31027353659522764941c71b732702296b6f400c977a4dc5628f872")) (SJust (SafeHash "e6129f50a866d19d95bc9c95ee87b57a9e695c05d92ba2746141b03c15cf5f70"))))])""
Yes I'm getting the same error since yesterday... it was working just fine before that on testnet 🤔
Seconded, similar/same issue. Might also be a mismatch between CSL versions used in lucid and nami (both the latest vasil testnet versions)
Update - it's blockfrost.
Do you know when it is going to be fixed? Or if there’s any workaround?
On Wed, 10 Aug 2022 at 09:04, Chris M. Hiatt @.***> wrote:
Update - it's blockfrost.
— Reply to this email directly, view it on GitHub https://github.com/Emurgo/cardano-serialization-lib/issues/485#issuecomment-1210249649, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACE6MHN3D67EBXLADLZKGU3VYNH6PANCNFSM54R4SRWQ . You are receiving this because you authored the thread.Message ID: @.***>
transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (PPViewHashesDontMatch (SJust (SafeHash "cf442fa6f31027353659522764941c71b732702296b6f400c977a4dc5628f872")) (SJust (SafeHash "e6129f50a866d19d95bc9c95ee87b57a9e695c05d92ba2746141b03c15cf5f70"))))])
@AdamMachera , try using the latest available version of the library please, I have just added a testcase which checks the hashing of the same exact datum and redeemer you have in your transaction and it gives me the expected hash e6129f50a866d19d95bc9c95ee87b57a9e695c05d92ba2746141b03c15cf5f70, you can check the test here: https://github.com/Emurgo/cardano-serialization-lib/blob/df96bf45b04cb8731726dae8361118bcf29a7d13/rust/src/plutus.rs#L2333-L2368
If you still will have a similar issue after switching to the latest version, please provide a snippet of the entire code that builds your transaction, including how the redeemer, the datum, and the script objects are created.
const scriptInputIndex = unspentOutput.scriptUtxo.input().index()
Irrelevant to the specific error you are getting, but am I understanding correctly that this input index you are getting is the index of the utxo in the transaction, like if the input reference is { txHash: ...., txOutputIndex: 1 }, then scriptInputIndex will be 1?
If so then it's not correct to use it in the redeemer, redeemer input index is a different thing, unrelated to the utxo index. The redeemer index is expected to point to the index of the script input in the transaction inputs list.
It will not cause errors for you while you are using the . add_plutus_script_input function, because in that case builder actually recalculates and changes the redeemer index, while building the transaction, so it comes out always correct. But just for you to be aware that I think the value you are trying to put there is not correct.
You can just replace it with always putting zero there, cuz builder will calculate it automatically anyways.
const costModels = TxBuilderConstants.plutus_vasil_cost_models(); txBuilder.calc_script_data_hash(costModels) const txUnspentOutputs = TransactionUnspentOutputs.new(); const walletOutputs = await cardano.getUtxos(); walletOutputs.forEach(utxo => txUnspentOutputs.add(utxo)) txBuilder.add_inputs_from(txUnspentOutputs, 2)
Actually, @AdamMachera , I think the issue that causing the hash mismatch is that you are calling .calc_script_data_hash before calling more .add_inputs_from which adds more inputs.
As described in the previous comment (https://github.com/Emurgo/cardano-serialization-lib/issues/485#issuecomment-1220666881) the index in the redeemer will change automatically when building the transaction, and that index value depends on the total amount of inputs that you have, because inputs also have to be canonically sorted (which also happens automatically), so you need to make sure that the .calc_script_data_hash function is called strictly after all inputs have been already added to the builder. Ideally you can just always call it right before calling .build_tx so it's always the last change in the builder.
Discussed with @lisicky , we gonna try to add an additional validation to fail with an error in case any more inputs are added after the hash already been auto-calculated
I placed the calculate script hash at the end.
txBuilder.set_collateral(txInputBuilder)
txBuilder.add_change_if_needed(selfAddress)
const costModels = TxBuilderConstants.plutus_vasil_cost_models();
txBuilder.calc_script_data_hash(costModels)
const tx = txBuilder.build_tx();
Now I'm getting: message: ""transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (UtxoFailure (FromAlonzoUtxoFail (FeeTooSmallUTxO (Coin 418688) (Coin 417368))))])""
I have zipped the code here:
you run it:
- yarn install
- yarn start
let me what is your testnet wallet address so I can send you one NFT so you can lock it in the SC.
Hi, @AdamMachera. You need to call add_change_if_needed after all changes in a tx builder and before calling txBuilder.build_tx. Because fee calculation happens inside add_change_if_needed and it's important to have all your data in the tx builder before calling add_change_if_needed. In your case, it would be smth like that.
txBuilder.set_collateral(txInputBuilder)
const costModels = TxBuilderConstants.plutus_vasil_cost_models();
txBuilder.calc_script_data_hash(costModels)
txBuilder.add_change_if_needed(selfAddress)
const tx = txBuilder.build_tx();
I placed the calculate script hash at the end.
Ah, shit, @AdamMachera, this is my bad, @lisicky is right. My mistake, you need to call the .calc_script_data_hash before adding the change, not before building the transaction, because calculating and setting the hash will change the transaction size and therefore the fee. Sorry about that.
So the correct order of operations is:
- Everything else
- Calc script hash
- Add change if needed
- Build_tx
Thanks @vsubhuman and @lisicky you support helped to solve this issue. Final version of cancelation method (maybe it will help someone):
export const cancel = async (api: CardanoApi, policyId: string, assetName: string): Promise<string> => {
const cardano = cardanoApiAdapter(api)
const protocolParameters = await getProtocolProtocolParams()
const exUnitPrices = ExUnitPrices.new(UnitInterval.new(BigNum.from_str("577"), BigNum.from_str("10000")), UnitInterval.new(BigNum.from_str("721"), BigNum.from_str("10000000")))
const txBuilder = await createTransactionBuilder(protocolParameters, exUnitPrices)
const scriptAddress = getContractAddress();
const unspentOutput = await getUnspentTransactionUtxoForNft(getContractAddress(), policyId, assetName);
const selfAddress = Address.from_bech32(unspentOutput.metadata?.addr.join("") as string)
const baseAddress = BaseAddress.from_address(selfAddress)!
const pkh = toHex(baseAddress.payment_cred().to_keyhash()?.to_bytes() as Uint8Array);
const scripts = getContractScript()
const contractAssetOutput = await getContractOutput(nftMoveFixedPrice, policyId, assetName)
let txOutputBuilder = TransactionOutputBuilder.new();
txOutputBuilder = txOutputBuilder.with_address(selfAddress);
let txOutputBuilderWithAmount = txOutputBuilder.next();
txOutputBuilderWithAmount = txOutputBuilderWithAmount.with_value(contractAssetOutput)
const txOutput = txOutputBuilderWithAmount.build();
const aux_data: AuxiliaryData = await addOfferMetadata(txBuilder, selfAddress, unspentOutput.metadata?.price as string, assetName, policyId, "cancel")
txBuilder.add_output(txOutput)
const salesOfferDatum = createSalesOfferDatum(pkh, unspentOutput.metadata?.price as string, policyId, assetName);
const datum = toPlutusData(salesOfferDatum);
const datumHash = hash_plutus_data(datum);
console.log(`datumHash: ${toHex(datumHash.to_bytes())}`)
const datumList = PlutusList.new();
datumList.add(datum);
const redeemers = Redeemers.new();
const redeemer = createRedeemer(0, RedeemerType.Close)
redeemers.add(redeemer);
const plutusWitness = PlutusWitness.new(scripts.get(0), datum, redeemer)
txBuilder.add_plutus_script_input(
plutusWitness,
unspentOutput.scriptUtxo.input(),
contractAssetOutput
)
txBuilder.add_required_signer(baseAddress.payment_cred().to_keyhash() as Ed25519KeyHash)
const txUnspentOutputs = TransactionUnspentOutputs.new();
const walletOutputs = await cardano.getUtxos();
walletOutputs.forEach(utxo => txUnspentOutputs.add(utxo))
txBuilder.add_inputs_from(txUnspentOutputs, 2)
const collateral = await getCollateralUnspentTransactionOutput(api)
var txInputBuilder = TxInputsBuilder.new()
collateral.forEach((utxo) => {
txInputBuilder.add_input(utxo.output().address(), utxo.input(), utxo.output().amount())
});
txBuilder.set_collateral(txInputBuilder)
const costModels = TxBuilderConstants.plutus_vasil_cost_models();
txBuilder.calc_script_data_hash(costModels)
txBuilder.add_change_if_needed(selfAddress)
const tx = txBuilder.build_tx();
const transactionWitnessSet = TransactionWitnessSet.from_bytes(tx.witness_set().to_bytes());
let signedtxVkeyWitnesses: TransactionWitnessSet
try {
signedtxVkeyWitnesses = await cardano.signTx(tx, true);
}
catch (err) {
throw handleSignError(err)
}
transactionWitnessSet.set_vkeys(signedtxVkeyWitnesses.vkeys()!);
const signedTx = Transaction.new(
tx.body(),
transactionWitnessSet,
aux_data
);
try
{
let txHash = await cardano.submitTx(signedTx);
console.log(`cancel txhash: ${txHash}`)
return txHash
} catch (err) {
appInsights.trackException({ exception: err as Error }, {
sellerAddress: selfAddress.to_bech32(),
sellerPkh: pkh,
policyId: policyId,
assetName: assetName,
price: unspentOutput.metadata?.price as string,
method: "cancel"
});
console.log(err)
throw err;
}
}
However in create redeemer I had to use:
const createRedeemer = (index: number, redeemerType: RedeemerType) => {
const redeemerData = PlutusData.new_constr_plutus_data(
ConstrPlutusData.new(
BigNum.from_str(redeemerType.toString()),
PlutusList.new()
)
);
//const exUnits = ExUnits.new(BigNum.from_str("61300"), BigNum.from_str("18221176"))
const exUnits = ExUnits.new(BigNum.from_str("7000000"), BigNum.from_str("3000000000"))
const r = Redeemer.new(
RedeemerTag.new_spend(),
toBigNum(index),
redeemerData,
exUnits
);
return r;
}
**const exUnits = ExUnits.new(BigNum.from_str("7000000"), BigNum.from_str("3000000000"))**
instead of the one that was produced as output from haskel SC compiler const exUnits = ExUnits.new(BigNum.from_str("61300"), BigNum.from_str("18221176"))
If I used the one provided by compiler, I was getting this message:
message: "\"transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (UtxoFailure (FromAlonzoUtxoFail (UtxosFailure (ValidationTagMismatch (IsValid True) (FailedUnexpectedly (PlutusFailure \\\"\\\\nThe 3 arg plutus script (PlutusScript PlutusV1 ScriptHash \\\\\\\"aab69a551fc931c565f5262bf9b2ccea846551d952e98535309e3f39\\\\\\\") fails.\\\\nCekError An error has occurred: User error:\\\\nThe machine terminated part way through evaluation due to overspending the budget.\\\\nThe budget when the machine terminated was:\\\\n({ cpu: 2735710\\\\n| mem: -234\\\\n})\\\\nNegative numbers indicate the overspent budget; note that this only indicatessthe budget that was needed for the next step, not to run the program to completion.\\\\nThe protocol version is: ProtVer {pvMajor = 7, pvMinor = 0}\\\\nThe data is: Constr 0 [B \\\\\\\"E\\\\\\\\246\\\\\\\\165\\\\\\\\ACK\\\\\\\\164\\\\\\\\154\\\\\\\\&8&<J\\\\\\\\139\\\\\\\\187.\\\\\\\\RS6\\\\\\\\157\\\\\\\\216s/\\\\\\\\177\\\\\\\\249\\\\\\\\162\\\\\\\\129\\\\\\\\243\\\\\\\\232\\\\\\\\131\\\\\\\\131\\\\\\\\135\\\\\\\",I 60000000,B \\\\\\\"\\\\\\\\238\\\\\\\\142\\\\\\\\&7gon\\\\\\\\187\\\\\\\\142\\\\\\\\ETX\\\\\\\\GS\\\\\\\\255I?\\\\\\\\136\\\\\\\\255q\\\\\\\\GS$\\\\\\\\170hfj\\\\\\\\t\\\\\\\\214\\\\\\\\US\\\\\\\\GS?\\\\\\\\179\\\\\\\",B \\\\\\\"CryptoDino09000\\\\\\\"]\\\\nThe redeemer is: Constr 1 []\\\\nThe context is:\\\\nPurpose: Spending (TxOutRef {txOutRefId = 2d85c9d6af9f9422c69c2612d478b64cda0de95c4f362736194e2fcc333f9f0e, txOutRefIdx = 0})\\\\nTxInfo:\\\\n TxId: 3927136ff0929c67bb743e5aac678cde56a754ae6a6ed89ad5f25804b1a56e67\\\\n Inputs: [ 298c439298be7566373850790a8b4d36f55bd43c6268d68af16e00216548404a!1 -> - Value (Map [(,Map [(\\\\\\\"\\\\\\\",1920801249)])]) addressed to\\\\n PubKeyCredential: 45f6a506a49a38263c4a8bbb2e1e369dd8732fb1f9a281f3e8838387 (StakingHash PubKeyCredential: 8727ae504f79d260b6024ac8590c934899b65734d835378badd32300)\\\\n , 2d85c9d6af9f9422c69c2612d478b64cda0de95c4f362736194e2fcc333f9f0e!0 -> - Value (Map [(,Map [(\\\\\\\"\\\\\\\",2000000)]),(ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3,Map [(\\\\\\\"CryptoDino09000\\\\\\\",1)])]) addressed to\\\\n ScriptCredential: aab69a551fc931c565f5262bf9b2ccea846551d952e98535309e3f39 (no staking credential) ]\\\\n Outputs: [ - Value (Map [(,Map [(\\\\\\\"\\\\\\\",2000000)]),(ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3,Map [(\\\\\\\"CryptoDino09000\\\\\\\",1)])]) addressed to\\\\n PubKeyCredential: 45f6a506a49a38263c4a8bbb2e1e369dd8732fb1f9a281f3e8838387 (StakingHash PubKeyCredential: 8727ae504f79d260b6024ac8590c934899b65734d835378badd32300)\\\\n , - Value (Map [(,Map [(\\\\\\\"\\\\\\\",1920382341)])]) addressed to\\\\n PubKeyCredential: 45f6a506a49a38263c4a8bbb2e1e369dd8732fb1f9a281f3e8838387 (StakingHash PubKeyCredential: 8727ae504f79d260b6024ac8590c934899b65734d835378badd32300) ]\\\\n Fee: Value (Map [(,Map [(\\\\\\\"\\\\\\\",418908)])])\\\\n Value minted: Value (Map [])\\\\n DCerts: []\\\\n Wdrl: []\\\\n Valid range: (-\\\\8734 , +\\\\8734)\\\\n Signatories: [45f6a506a49a38263c4a8bbb2e1e369dd8732fb1f9a281f3e8838387]\\\\n Datums: [ ( 5c2812e11711bdbbc5789200b67ba924a3ed74c23234c0ab4d29cf2bb6070579\\\\n , <\\\\\\\"E\\\\\\\\246\\\\\\\\165\\\\\\\\ACK\\\\\\\\164\\\\\\\\154\\\\\\\\&8&<J\\\\\\\\139\\\\\\\\187.\\\\\\\\RS6\\\\\\\\157\\\\\\\\216s/\\\\\\\\177\\\\\\\\249\\\\\\\\162\\\\\\\\129\\\\\\\\243\\\\\\\\232\\\\\\\\131\\\\\\\\131\\\\\\\\135\\\\\\\",\\\\n 60000000,\\\\n \\\\\\\"\\\\\\\\238\\\\\\\\142\\\\\\\\&7gon\\\\\\\\187\\\\\\\\142\\\\\\\\ETX\\\\\\\\GS\\\\\\\\255I?\\\\\\\\136\\\\\\\\255q\\\\\\\\GS$\\\\\\\\170hfj\\\\\\\\t\\\\\\\\214\\\\\\\\US\\\\\\\\GS?\\\\\\\\179\\\\\\\",\\\\n \\\\\\\"CryptoDino09000\\\\\\\"> ) ]\\\\n\\\" \\\"hgCYphoAAyNhGQMsAQEZA+gZAjsAARkD6BlecQQBGQPoGCAaAAHKdhko6wQZWdgYZBlZ2BhkGVnYGGQZWdgYZBlZ2BhkGVnYGGQYZBhkGVnYGGQZTFEYIBoAAqz6GCAZtVEEGgADYxUZAf8AARoAAVw1GCAaAAeXdRk29AQCGgAC/5QaAAbqeBjcAAEBGQPoGW/2BAIaAAO9CBoAA07FGD4BGgAQLg8ZMSoBGgADLoAZAaUBGgAC2ngZA+gZzwYBGgABOjQYIBmo8RggGQPoGCAaAAE6rAEZ4UMEGQPoChoAAwIZGJwBGgADAhkYnAEaAAMgfBkB2QEaAAMwABkB/wEZzPMYIBn9QBggGf/VGCAZWB4YIBlAsxggGgABKt8YIBoAAv+UGgAG6ngY3AABARoAAQ+SGS2nAAEZ6rsYIBoAAv+UGgAG6ngY3AABARoAAv+UGgAG6ngY3AABARoADFBOGXcSBBoAHWr2GgABQlsEGgAEDGYABAAaAAFPqxggGgADI2EZAywBARmg3hggGgADPXYYIBl59BggGX+4GCAZqV0YIBl99xggGZWqGCAaAJBjuRkD/QqCGe90GgEWCHhZE51ZE5oBAAAzIzIjMyIjMiMyIyMjMyIjIzMiIyMzMzMyIiIiIyMzIiMjMzIiIyMjMiMjMyIjIzMiIyMjMiMyIyMjMzMiIiMyIzIjMiMyIzIjMiIjIyMjIjIjIyUzUwNjMwCzMzVzRm4c1VzqgEpAAEZmZERGZmCyAIAGAEACbrjV0KgEm601dCoBBuuNXQqAObrjV0Jq6JQByNQTDUwTTNXOJIEDUFQxAATkmSYzM1c0ZuHUARIAIgUiMzNXNGbh1AFSAAIFQjUE01ME4zVziSEDUFQxAAT0mSZJjMzVzRm4c1VzqgBJAAEZgHGRkZGRkZGRkZGRkZmauaM3DmqudUApIAAjMzMzMzAcM1AqIyMjMzVzRm4c1VzqgBJAAEZgRGB6auhUAIwLzV0Jq6JQAiNQXDUwXTNXOJIBA1BUMQAF5JkmE1VzygAibqgATV0KgFGagVAVmroVAJMzVQMXXKBgauhUAgzNVAxdcoGBq6FQBzNQKgRjV0KgDGagVGaqCuCe601dCoApkZGRmZq5ozcOaq51QAkgACM1AkMjIyMzNXNGbhzVXOqAEkAARmoFhmoIrrTV0KgBGCUauhNXRKAERqDAamDCZq5xJAEDUFQxAAYkmSYTVXPKACJuqABNXQqAEZGRkZmauaM3DmqudUAJIAAjNQKjNQRXWmroVACMEo1dCauiUAIjUGA1MGEzVziSAQNQVDEABiSZJhNVc8oAIm6oAE1dCauiUAIjUFw1MF0zVziSAQNQVDEABeSZJhNVc8oAIm6oAE1dCoAhmoFTrjV0KgBmagVGaqCu64gATV0KgBGB4auhNXRKAERqCwamCyZq5xJBA1BUMQAFpJkmE1dEoAImrolABE1dEoAImrolABE1dEoAImrolABE1dEoAImrolABE1VzygAibqgATV0KgBGRkZGZmrmjNw6gApADEYEJgfGroTVXPKAGRmZq5ozcOoASQAhGBAYJBq6E1VzygCEZmauaM3DqAGkAERgQGBmauhNVc8oApGZmrmjNw6gCJAAEYEZuuNXQmqueUAYjUFM1MFQzVziSAQNQVDEABVSZJkmSZJhNVc6oAIm6oAE1dCauiUAIjUEw1ME0zVziSQNQVDEABOSZJhBNE1BLNTBMM1c4kgEDUFQ1AATUmE1VzygAibqgARNVc6bqgARNXRKACJq6JQARNVc8oAIm6oAEiEjMAEAMAIgASIiIiIiEjMzMzMzABALAKAJAIAHAGAFAEADACIAEiEjMAEAMAIgARIhIzABADACEgARIhIzABADACEgARIhIzABADACEgASEiIjAEAFISIiMAMAUhIiIwAgBSEiIjABAFIAESMiMAI3WAAmQAJqoHJEZmaq58AElAOIzUA0wBDV0IARgBmrogAgMyMjIyMzNXNGbhzVXOqAGkAARmYA5kZGRmZq5ozcOaq51QAkgACMwDTAxNXQqAEZqAmBaauhNXRKAERqBsamBuZq5xJEDUFQxAAOEmSYTVXPKACJuqABNXQqAGZmqgFuuUAo1dCoARmoB7rjV0Jq6JQAiNQMjUwMzNXOJIQNQVDEAA0SZJhNXRKACJqrnlABE3VAAkRCRmYAIAgAYARAAkQkZgAgBgBEACJmqgAuudaIkRkRgBG6sAEyABNVAzIjIzM1Vz4ARKASRmoBBmqgYmAMaq51QAjAFNVc8oARgCGrogAwLhNXQgAiJEAEJEJEZgAgCABiQAIkRkZGZmrmjNw6gApAAEagEGAKauhNVc8oAZGZmrmjNw6gBJABEoBBGoFJqYFRmrnEkAQNQVDEAArSZJkmE1VzqgAibqgARISIwAgAxEiABEgASMjIzM1c0ZuHNVc6oASQABGYAxgDmroVACN1pq6E1dEoARGoEZqYEhmrnEkEDUFQxAAJUmSYTVXPKACJuqABIhIzABADACIAEjIzM1c0ZuHNVc6oAKQABG641dCaq55QAiNQHzUwIDNXOJIEDUFQxAAIUmSYTdUACJEZGRmZq5ozcOoAKQAhKAORmZq5ozcOoASQARGoBRgDGroTVXPKAIRmZq5ozcOoAaQABKAURqBEamBGZq5xJAQNQVDEAAkSZJkmSYTVXOqACJuqABEhIiMAMAQRIiACESIgARIAEjIzM1c0ZuHUAFIAIgBiMzNXNGbh1ACSAAIAYjUBo1MBszVziSQNQVDEAAcSZJkmE1VzpuqABEiACEiABIAEjIyMjIyMzNXNGbh1ABSAMIAsjMzVzRm4dQAkgCiANIzM1c0ZuHUANIAgjMAs3XGroVAFN1pq6E1dEoApGZmrmjNw6gCJADEZgGm641dCoA5uuNXQmrolAHIzM1c0ZuHUAVIAQjMBIwFDV0KgEm641dCauiUAkjMzVzRm4dQBkgAiMBQwFTV0JqrnlALIzM1c0ZuHUAdIAAjATMBY1dCaq55QDCNQHzUwIDNXOJIEDUFQxAAIUmSZJkmSZJkmSYTVXOqAIJqrnlADE1VzygBCaq55QARN1QAJCRERERgDgEEQkREREZgDAEgEEJERERGAKAQJERERACCREREQAZEJERERGYAQBIBBEJERERGYAIBIBBAAkZGRkZGZmrmjNw6gApABEZmAQbrTV0KgCG601dCoAZutNXQmrolADIzM1c0ZuHUAJIAAjAKMAs1dCaq55QBiNQEDUwETNXOJJA1BUMQABJJkmSYTVXOqAGJq6JQARNVc8oAIm6oAEhIjACADIiEiMzABAFAEADIAEjIyMzNXNGbh1ABSACIwBjdcauhNVc8oAZGZmrmjNw6gBJAAEYBBuuNXQmqueUAQjUAo1MAszVziSAQNQVDEAAMSZJkmE1VzqgAibqgASEiMAIAMhIjABADIAERIiMjIzM1c0ZuHNVc6oASQABGaqAWYAxq6FQAjAFNXQmrolACI1AHNTAIM1c4khA1BUMQAAlJkmE1VzygAibqgARJhIAEgAREiEjMAEAMAIRIAESIAISIAEgASIiEjMzABAFAEADACIAERIyMAEAEiMwAzACACABMyMjMiMyIyMyIyMjIyMjMyIjIyMyIyMjMyIjIyMzMiIjIzIjIyMjIyMjIyMyIzMiIyMzIiMzIiMzMzMyIiIiIzIjMzMiIiMzMiIjMiMyIzIjMyIjMiMyIzIjMiMyIyMjIiMjIyIjJTNTA5ADFTNTBYUzUwWDMD8wXzMwCTM1UwSBIAFQRFBRMwCwCFABSIBAEiBAFM1MFgzBAUARQXBUFwVAEEFoTNXOJIBDEZlZSBub3QgcGFpZAAFkVM1MFhTNTBYMzVzRm4czMAkzNVMEgSABUERQUTMAtTNTUE81MA5QASIiIiIiADEwXRYiFTNTUFEAEQAiITBhFlABNTA8AHIiIAI1MDwAciIgAUgAgWgWRBaEzVziSEMV3JvbmcgaW5wdXRzAAWRUzUwWFM1MFgzA/MF8zMAkzNVMEgSABUERQUTMAs1MDwAciIgBFABSIEASIEAMyI1NQYgAiI1NQZAAyIzBJM3AGbggBAATNwQAQAZm4IAMAEzIjU1BiACIjU1BkADIjMEkzcCZuCAEABM3BABABmbggAwATBfUAZTNTBYMwQFAFUF4VBeFQBTBfSCAkvQBEFoTNXOJIEPU2VsbGVyIG5vdCBwYWlkAAWRUzUwWDM1c0ZuHMjMgATIAEzNVME8SABMjNQVyIzNQVwAwAQAjUFQAEzUFYiIwAzACABIAEiM3AAApABAApAAGZEZGACZqpgdiQAJGpgKAAkQAJqYCKgCEREREREAUZAAmqg1ESmamoKYAIgBkQmSmamC+ZkRqYDoAREamA+AGRGRmpghgCkZqYIgAhKZqYNBmauaM3HgBAAg1A0ioAYg0kDSRmpgiACEDSSmamDQZmrmjNx4AQAINQNIqAGINIqZqagRgBkKmamoEgARCZqYIIARGamCEAERmpgjABEZ"
The issue that I'm worried is that transaction fees for these values const exUnits = ExUnits.new(BigNum.from_str("7000000"), BigNum.from_str("3000000000")) are almost twice as big as the one provided by compiler (~ 1ADA instead of 0.5ADA) - for cancel operation.