Node.js SDK invoke contract error

on CLI works well:
alexs-iMac-2:concordium alex$ concordium-client contract invoke 2025 --entrypoint getFinishingSessions --energy 10000 \

    --schema res/motodex.bin \
    --grpc-ip 162.19.70.59 \
    --grpc-port 10001

Invocation resulted in success:

  • Energy used: 5371 NRG
  • Return value:
    [
    2
    ]

but in node.js produce error:

TypeError: Cannot read properties of undefined (reading 'length')
    at isValidHash (/Users/alex/Documents/repos/deansart_bot/node_modules/@concordium/common-sdk/lib/util.js:96:17)
    at ConcordiumNodeClient.invokeContract (/Users/alex/Documents/repos/deansart_bot/node_modules/@concordium/node-sdk/lib/client.js:466:37)
    at /Users/alex/Documents/repos/deansart_bot/controllers/ethereumController.js:1434:39
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

CODE:

const accountAddress = new AccountAddress("3sb8rSpqhNmK9aX1TnZAn6tt1dc4kBm5NLzWJjdHD583rBXzUU");
const consensusStatus = await client.getConsensusStatus();
const bestBlock = consensusStatus.bestBlock;
// const accountInfo = await client.getAccountInfo(accountAddress, bestBlock);
const nextAccountNonce = await client.getNextAccountNonce(
    accountAddress
);

const contractAddress = { index: 2025n, subindex: 0n };
const contractName = 'MOTODEX';
let receiveFunctionName = 'getFinishingSessions';
let methodName = contractName + '.' + receiveFunctionName;
const moduleFileBuffer = new Buffer(bin64, 'base64');

const parameters = {};
let inputParams = serializeUpdateContractParameters(
    contractName,
    receiveFunctionName,
    parameters,
    moduleFileBuffer,
    0
);

let result = await client.invokeContract(
    {
        invoker: accountAddress,
        contract: contractAddress,
        method: methodName,
        parameter: inputParams
    }
);

Hi @oleksiivinogradov

The entrypoint does not seem to expect a parameter, as you don’t provide one in concordium-client. So you shouldn’t provide a parameter in javascript either. I am not sure about the exact error message, for that, I would have to look deeper into the issue.

But you can try this:

let result = await client.invokeContract(
    {
        invoker: accountAddress,
        contract: contractAddress,
        method: methodName
    }
);

This example shows how to invoke a parameter-less entrypoint on a contract:

Best regards,
Kasper

send

let result = await client.invokeContract(
    {
        invoker: accountAddress,
        contract: contractAddress,
        method: methodName,
        parameter: undefined
    }
);

same error:
TypeError: Cannot read properties of undefined (reading ‘length’)
at isValidHash (/Users/alex/Documents/repos/deansart_bot/node_modules/@concordium/common-sdk/lib/util.js:96:17)
at ConcordiumNodeClient.invokeContract (/Users/alex/Documents/repos/deansart_bot/node_modules/@concordium/node-sdk/lib/client.js:466:37)
at /Users/alex/Documents/repos/deansart_bot/controllers/ethereumController.js:1443:39
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

same for @Kasper solution:

TypeError: Cannot read properties of undefined (reading ‘length’)
at isValidHash (/Users/alex/Documents/repos/deansart_bot/node_modules/@concordium/common-sdk/lib/util.js:96:17)
at ConcordiumNodeClient.invokeContract (/Users/alex/Documents/repos/deansart_bot/node_modules/@concordium/node-sdk/lib/client.js:466:37)
at /Users/alex/Documents/repos/deansart_bot/controllers/ethereumController.js:1443:39
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

sorry i used “;” in undefined inside json object
try without “;”

doesn’t matter, I delete it of course

Hi there.

The error happens due to a missing second function parameter of the client.invokeContract, which takes both ContractParameters and a string (block hash).

concordium-client implicitly uses the best block when no block hash is specified, whereas the nodeJS SDK requires you to specify it with no fallback.

The following code should work:

let result = await client.invokeContract(
    {
        invoker: accountAddress,
        contract: contractAddress,
        method: methodName,
        parameter: inputParams
    },
    bestBlock
);

You can find the documentation for the specific client function here:

Best regards,
Søren

works well, thanks, thanks, thanks