A beneficiary tries to withdraw the maximum amount from 2 utxo's of a smart contract in one transaction but that fails. If the beneficiary does it in two steps it succeeds. Why does the first one fail?
Detail :
-------------------------------------------------------------------------
ben | addr_test1v⋯qarpt4 | = 1101556208 |
| - 714d2e⋯dea7cb#0 | + 1021470 | [ "ben"×1 ] Token
| - 714d2e⋯dea7cb#1 | + 1100534738 |
-------------------------------------------------------------------------
tokencheck | addr_test1w⋯hyha8n | = 34000000 |
| - 347def⋯58e2c7#0 | + 21000000 | {14e594⋯4816fa} Datum
| - dca3bc⋯b80ae8#0 | + 13000000 | {14e594⋯4816fa} Datum
The beneficiary 'ben' tries to withdraw the maximum amount from smart contract 'tokencheck', and in that transaction also includes his token 'ben' (62656e), to fulfill a condition in the contract.
Ben tries to withdraw from both the utxo's of the contract (both have the same, correct datum) :
# total amount = 21000000 (contract) + 13000000 (contract) + 1021470 (ben token) - 966660 (fee) = 34054810
cardano-cli transaction build-raw
--babbage-era
--protocol-params-file protocol-parameters.json
--tx-in "714d2e⋯dea7cb#0" # utxo with ben's token
--tx-in "347def⋯58e2c7#0" # first utxo of contract
--tx-in "dca3bc⋯b80ae8#0" # second utxo of contract
--tx-in-datum-file datum.json
--tx-in-redeemer-file redeemer.json
--tx-in-script-file tokencheck.json
--tx-in-collateral "714d2e⋯dea7cb#1"
--required-signer ben.skey
--tx-out "addr_test1v⋯qarpt4 + 34054810 + 1 2d99fb⋯63d3a1.62656e"
--fee 966660
--tx-in-execution-units '(3000000000,7000000)'
--out-file tx_raw.json
This fails when submitting, with error message:
Command failed: transaction submit Error: Error while submitting tx: ShelleyTxValidationError
ShelleyBasedEraBabbage (ApplyTxError
[UtxowFailure(
FromAlonzoUtxowFail
(MissingRedeemers [(Spending (TxIn (TxId {_unTxId = SafeHash "347def⋯58e2c7"}) (
TxIx 0)),ScriptHash "5c2d3c⋯7d947b")])),
UtxowFailure (
UtxoFailure (FromAlonzoUtxoFail (UtxosFailure (CollectErrors
[NoRedeemer (Spending (TxIn (TxId {_unTxId = SafeHash "347def⋯58e2c7"}) (TxIx 0)))])))
)
])
If Ben just withdraws using only ONE of the contract's utxo's, the transaction succeeds:
# total amount = 21000000 + 1021470 - 953284 = 21068186
cardano-cli transaction build-raw
--babbage-era
--protocol-params-file protocol-parameters.json
--tx-in "714d2e⋯dea7cb#0" # utxo with ben's token
--tx-in "347def⋯58e2c7#0" # one utxo of contract
--tx-in-datum-file datum.json
--tx-in-redeemer-file redeemer.json
--tx-in-script-file tokencheck.json
--tx-in-collateral "714d2e⋯dea7cb#1"
--required-signer ben.skey
--tx-out "addr_test1v⋯qarpt4 + 21068186 + 1 2d99fb⋯63d3a1.62656e"
--fee 953284
--tx-in-execution-units '(3000000000,7000000)'
--out-file tx_raw.json
Transaction successfully submitted.
Question: why does the first transaction fail while the second succeeds?
Update
Here's the contract, it's written in Helios:
struct Datum {
donor: PubKeyHash
beneficiary: PubKeyHash
policy: MintingPolicyHash
}
func main(datum: Datum, ctx: ScriptContext) -> Bool {
tx: Tx = ctx.tx;
if (tx.is_signed_by(datum.donor)) {
true
} else {
if ( tx.value_sent_to(datum.beneficiary).get(AssetClass::new(datum.policy, #62656e)) == 1) {
true
} else {
print("computer says no"); false
}
}
}