javascriptnext.jssmartcontractsgeneral-network-erroralgorand

Algrand Smart Contract Method Calling


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.


Solution

  • 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.