FuelError: Invalid transaction data: PredicateVerificationFailed(OutOfGas)

fuelup show:-

fuelup home: /home/chappie/.fuelup

Installed toolchains
--------------------
latest-x86_64-unknown-linux-gnu (default)
nightly-2024-05-28-x86_64-unknown-linux-gnu
testnet-x86_64-unknown-linux-gnu

active toolchain
----------------
latest-x86_64-unknown-linux-gnu (default)
  forc : 0.61.2
    - forc-client
      - forc-deploy : 0.61.2
      - forc-run : 0.61.2
    - forc-crypto : 0.61.2
    - forc-debug : 0.61.2
    - forc-doc : 0.61.2
    - forc-fmt : 0.61.2
    - forc-lsp : 0.61.2
    - forc-tx : 0.61.2
    - forc-wallet : 0.8.1
  fuel-core : 0.31.0
  fuel-core-keygen : 0.31.0

fuels versions
--------------
forc : 0.64.0
forc-wallet : 0.64.0

predicate code:-

```predicate;

use std::{
     tx::{
        tx_witness_data,
        tx_witnesses_count,
        tx_id
    },
    ecr::ec_recover_address,
    b512::B512
};

use std::array_conversions::{b256::*};


configurable {
    ORACLE: Address = Address::from(0x6b63804cfbf9856e68e5b6e7aef238dc8311ec55bec04df774003a2c96e0418e),
}

fn main() -> bool {
    // return true;
    let res = verify_signature(1);
    if res == ORACLE {
        return true;
    }
 false
}

fn verify_signature(witness_index: u64) -> Address {
    let tx_hash = tx_id();
    let current_signature = tx_witness_data::<B512>(witness_index);
    let current_address = ec_recover_address(current_signature, tx_hash).unwrap();
    current_address
}


TS code:- 

    const createRedmption = async () => {
    const transactionRequest = new ScriptTransactionRequest();

    const red_predicate = await createRedmptionPredicate(ttd, asset1);

    const predicate = await createPredicate();
    const user = await getWallet();
    const UtxoToPayFee: Resource[] = await predicate.getResourcesToSpend([
      [100, ttd],
    ]);

    transactionRequest
      .addResources(UtxoToPayFee)
      .addCoinOutput(red_predicate.address, 100, ttd);
    const txCost = await user.provider.getTransactionCost(transactionRequest, {
      signatureCallback: (tx) => tx.addAccountWitnesses(user),
      resourcesOwner: predicate,
    });
    transactionRequest.updatePredicateGasUsed(txCost.estimatedPredicates);
    transactionRequest.gasLimit = txCost.gasUsed;
    transactionRequest.maxFee = txCost.maxFee;
    transactionRequest.addWitness("0x");
    // Fund the transaction from the wallet
    await user.fund(transactionRequest, txCost);

    await transactionRequest.addAccountWitnesses(user);

    // Sending the transaction to the chain
    const tx = await user.sendTransaction(transactionRequest);
    const res = await tx.waitForResult();
    console.log(res);
  };

Error:- 

```index.mjs:4229 Uncaught (in promise) 
FuelError: Invalid transaction data: PredicateVerificationFailed(OutOfGas)
    at responseMiddleware (index.mjs:4229:19)
    at eval (index.js:284:17)
    at async _Provider.sendTransaction (index.mjs:4364:9)
    at async createRedmption (page.tsx:892:16)
Show 16 more frames```

Hello @chappie1998.

We are sorry for this issue.

Our team is actively investigating the issue and we will keep you updated on our progress.

Thank you for your patience.

2 Likes

@chappie1998, I noticed that you’re using forc version 0.61.2. Is there a specific reason for using this version instead of the latest version, 0.62.0?

Additionally, which version of fuels are you using? Is it 0.93.0?

I have tested your code, and everything worked fine on my side using fuels version 0.93.0. Updating to this version might resolve your issue.

The code needs some updates to be compatible with 0.93.0, particularly when calling getTransactionCost( you can read more about this change here).

You need to call it directly from the predicate and update its parameters as follows:

const txCost = await predicate.getTransactionCost(transactionRequest, {
  signatureCallback: (tx) => tx.addAccountWitnesses(user),
});

Please let us know if this resolves the problem.

Same issue but doesn’t work for locked wallets

Is this an issue with all the latest versions ie fuel-core 0.36.0, forc 0.63.6 and ts SDK 0.94.6?

@1griffy This is expected behavior because a WalletLocked instance can only be used to access an account’s public information. It cannot be used to generate signatures since a WalletLocked is instantiated with only the wallet’s address.

Only WalletUnlocked can be used to generate signatures, as they are either newly generated wallets or instantiated with a private key.

// Cannot be used to generate signatures
const lockedWallet: WalletLocked = Wallet.fromAddress(walletAddress); 

// Can be used to generate signatures
const unlockedWallet: WalletUnlocked = Wallet.fromPrivateKey(privateKey);

If I’m missing any specifics of your use case, I apologize for any confusion. Please feel free to share more details so I can better understand and assist you.

1 Like

How do you do this from the frontend ?
const txCost = await predicate.getTransactionCost(transactionRequest, {
signatureCallback: (tx) => tx.addAccountWitnesses(user),
});
tx.addAccountWitness can’t be added right ?

@1griffy

I don’t have the full context of your use case, but it seems like a wallet connector might solve your problem. Have you tried using the Fuel Wallet Connector?

Is your use case related to a predicate that requires a signature from a locked wallet?

By using a wallet connector, the user will be prompted to sign the transaction just before submission.

I’d be happy to provide more details, but I’ll need more context about the Predicate code to assist you further.