So I am working with an Algorand smart contract in nextjs. I am using Pera wallet to sign transactions. And currently, I am running into a problem where I want to call methods from the contract from the front end using the ABI, and AtomicTransactionComposer, however I get this error
URLTokenBaseHTTPError: Network request error. Received status 400 (): TransactionPool.Remember: transaction BCJJTOCFMIZOJZNRKDFCIOPMXWRFUUQ24DDJWGJWRD46UXUYSZ7A: logic eval error: invalid Box reference 0x3239303135313533. Details: pc=587, opcodes=frame_dig -1; extract 2 0; box_get
Here is my code, assume that anything before this code is unrelated to calling the method
const algodToken = '';
const algodServer = 'https://testnet-api.algonode.cloud';
const algodPort = undefined;
const algodClient = new algosdk.Algodv2(algodToken, algodServer, algodPort);
const suggestedParams = await algodClient.getTransactionParams().do();
console.log('suggestedParams:', suggestedParams);
const contract = new algosdk.ABIContract(myabi);
const atc = new algosdk.AtomicTransactionComposer();
atc.addMethodCall({
suggestedParams,
sender: account,
// Signer is a function that takes in unsigned txns and returns signed txns
signer: async (unsignedTxns) => {
// Create an array of transaction groups with the unsigned transactions and the signers
const txnGroups = unsignedTxns.map((t) => ({txn: t, signers: [t.from]}));
// Call the signTransaction method of the peraWallet instance and return the signed transactions
return await peraWallet.signTransaction([txnGroups]);
},
appID: 468709015,
method: algosdk.getMethodByName(contract.methods, 'readFundsWithdrawnStatus'),
// Note how we don't have to manually encode the string
methodArgs: [APN],
});
const results = await atc.execute(algodClient, 3);
console.log(`Contract read success ` + results.methodResults);
return results.methodResults
This is the method i want to call in the smart contract
@app.external
def readFundsWithdrawnStatus(item_name: abi.String, *, output: abi.Bool) -> Expr:
existing_sender_funds_item = SenderFundsContract()
return Seq(
existing_sender_funds_item.decode(app.state.sender_funds_item[item_name.get()].get()),
output.set(existing_sender_funds_item.fundsWithdrawn)
)
Does anyone know why I cam getting that network error. I have a feeling its becasue of the methodArg I am passing in or is it the AppID is not deploying.
invalid box reference
means your transaction doesn't include the references to boxes being read or written to. The AVM needs to know all of the resources it will touch before being executed, and we do that when forming the transaction.
In your case, it looks like the box reference it item_name
, which is APN
in your client-side code. So, to add the box reference add the following parameter to your addMethodCall
:
boxes: { appIndex: 468709015, name: algosdk.ABIStringType.encode(APN) }
atc.addMethodCall({
suggestedParams,
sender: account,
// Signer is a function that takes in unsigned txns and returns signed txns
signer: async (unsignedTxns) => {
// Create an array of transaction groups with the unsigned transactions and the signers
const txnGroups = unsignedTxns.map((t) => ({txn: t, signers: [t.from]}));
// Call the signTransaction method of the peraWallet instance and return the signed transactions
return await peraWallet.signTransaction([txnGroups]);
},
appID: 468709015,
method: algosdk.getMethodByName(contract.methods, 'readFundsWithdrawnStatus'),
// Note how we don't have to manually encode the string
methodArgs: [APN],
// Box reference
boxes: { appIndex: 468709015, name: algosdk.ABIStringType.encode(APN) }
});
See https://algorand.github.io/js-algorand-sdk/classes/AtomicTransactionComposer.html#addMethodCall for documentation on addMethodCall
And see https://developer.algorand.org/docs/get-details/dapps/smart-contracts/apps/ for more information on resources.