Number of arguments error

I have a smart contract call that was returning an empty error, then I did a dry run to get a more specific error, and I got incorrect number of arguments error which is really weird, as I am passing the correct number of arguments (9)!
Sophia function that I am calling is:
public stateful entrypoint finalize(pubkey: address, sig: signature, logicVersion : int, nonce : int, functionName : string, ti : int, flancer : int, flancersScore : int, flancersText : string) =

(so as can be seen it takes 9 arguments)

And in js code I call it like this in a try block:
const resBc = await _contract.methods
.finalize.get(req.body.publicKey, req.body.sig, req.body.logicVersion, req.body.nonce, ‘finalize’, task.bcId, freelancer.bcId, req.body.rate, req.body.message);

I catch error and print exact calling arguments:
console.error(req.body.publicKey, req.body.sig, req.body.logicVersion, req.body.nonce, ‘finalize’, task.bcId, freelancer.bcId, req.body.rate, req.body.message);
console.error(err);

And I get output:
ak_M65JLCoTNWEiprJT9oTZWrhs5bJJ8mg9SyEdcm3UqW6snTmxK 3f2c42a32835f7fb6519b739c274e8304380d353f38e7b853cef297410cede60664e91ca6ea61aedef2f075749d95fadd29d17eef3154fdb2ef86781249ebc08 1 9 finalize 4 2 2 soso
Error: Invocation failed: cb_RXhwZWN0ZWQgOSBhcmd1bWVudHMsIGdvdCA4ls17fg==. Decoded: Expected 9 arguments, got 8��{~

returnType: ‘error’,
returnValue: ‘cb_RXhwZWN0ZWQgOSBhcmd1bWVudHMsIGdvdCA4ls17fg==’,
error: ‘cb_RXhwZWN0ZWQgOSBhcmd1bWVudHMsIGdvdCA4ls17fg==’,
decodedError: ‘Expected 9 arguments, got 8��{~’

So super weird…any ideas? @philipp.chain @bruteforce.chain @hanssv.chain
Is there some limit in Sophia on the number of arguments or size of all arguments combined? I am sure there are, but it would be weird if that limit was only 8 arguments :confused: (actually I tested the function through online Sophia IDE and it worked, so I don’t get what’s wrong with my JS calling procedure)

what sdk version are you using?

@philipp.chain @aeternity/[email protected]

@philipp.chain updated to 7.7.0 but still getting the same error…there is now rlpEncoded field as well so I will paste the error output in case you find it useful:

callData: ‘cb_KxFAZW4rm58AoC2ccH8rCukePo2nDQG4B6XCvEjs245SJejFCvN+lCfonwEBAPUk3P32d/H5tsiA5i+3Xy3e36z2ynP+FKOAE0nEJwJJcUVUjXT0e8bevzX+LyXUn5UIOjRl4G1ymUlQjfyKUwYCFiFmaW5hbGl6ZQoECBFsaWtl+hfG7w==’
},
rlpEncoded: <Buffer f8 de 2b 01 a1 01 9c 5a d3 f4 a0 79 4c 3c 88 fc 51 81 8a 1f f4 15 11 84 84 7f 4e 83 14 58 24 45 22 e1 dd f0 5c e6 81 ac a1 05 d2 b2 de ca be 7c bc bb … 174 more bytes>,
binary: [
<Buffer 2b>,
<Buffer 01>,
<Buffer 01 9c 5a d3 f4 a0 79 4c 3c 88 fc 51 81 8a 1f f4 15 11 84 84 7f 4e 83 14 58 24 45 22 e1 dd f0 5c e6>,
,
<Buffer 05 d2 b2 de ca be 7c bc bb 96 1a b7 8c f5 5c e8 a7 19 01 15 13 74 49 26 b5 94 b1 a3 39 c4 22 07 dd>,
<Buffer 03>,
<Buffer a7 c8 98 de 40 00>,
<Buffer 00>,
<Buffer 00>,
<Buffer 18 17 f8>,
<Buffer 3b 9a ca 00>,
<Buffer 2b 11 40 65 6e 2b 9b 9f 00 a0 2d 9c 70 7f 2b 0a e9 1e 3e 8d a7 0d 01 b8 07 a5 c2 bc 48 ec db 8e 52 25 e8 c5 0a f3 7e 94 27 e8 9f 01 01 00 f5 24 dc fd … 79 more bytes>
]
},
error: ‘cb_RXhwZWN0ZWQgOSBhcmd1bWVudHMsIGdvdCA4ls17fg==’,
rawTx: undefined,
decodedError: ‘Expected 9 arguments, got 8��{~’

1 Like

can you provide me with an sample project to reproduce the error, the following works well for me:

const {Universal, MemoryAccount, Node} = require('@aeternity/aepp-sdk');

const keypair = {
  secretKey: "",
  publicKey: ""
};

const config = {
  url: 'https://testnet.aeternity.io/',
  internalUrl: 'https://testnet.aeternity.io/',
  compilerUrl: 'https://latest.compiler.aepps.com'
};

const getClient = async () => {
  return Universal({
    nodes: [{
      name: 'testnet',
      instance: await Node(config)
    }],
    accounts: [MemoryAccount({keypair: keypair})],
    networkId: 'ae_uat',
    compilerUrl: config.compilerUrl
  });
};

const source = `
contract Test =
  entrypoint finalize(pubkey: address, sig: signature, logicVersion : int, nonce : int, functionName : string, ti : int, flancer : int, flancersScore : int, flancersText : string) =
    (pubkey, sig, logicVersion, nonce, functionName, ti, flancer, flancersScore, flancersText)
`;


const deploy = async () => {
  const client = await getClient();
  const contract = await client.getContractInstance(source);
  console.log(await contract.deploy())

  const finalize = await contract.methods.finalize(
    "ak_M65JLCoTNWEiprJT9oTZWrhs5bJJ8mg9SyEdcm3UqW6snTmxK",
    "3f2c42a32835f7fb6519b739c274e8304380d353f38e7b853cef297410cede60664e91ca6ea61aedef2f075749d95fadd29d17eef3154fdb2ef86781249ebc08",
    1, 9, "finalize", 4, 2, 2, "soso");

  console.log(finalize)
};

deploy();

Thanks. One thing that occurred to me is that i used Contracts Aepp for compiling and deploying and it might be using an outdated compiler? I will try now deploying using js sdk
In the meantime it’d be great if you can try calling the actual function, and see what we get…the contract is deployed on testnet at ct_2bo1vBzK7jSCE26wd8KGHev7iJ3hFCB8c2r3G4xRcoWbkY9wBn
This is the actual function body:
//client accepts flancer’s work
public stateful entrypoint finalize(pubkey: address, sig: signature, logicVersion : int, nonce : int, functionName : string, ti : int, flancer : int, flancersScore : int, flancersText : string) =
require(functionName == “finalize” && Crypto.verify_sig(String.blake2b(String.concat(Int.to_str(logicVersion), String.concat(Int.to_str(nonce), String.concat(functionName, String.concat(Int.to_str(ti), String.concat(Int.to_str(flancer), String.concat(Int.to_str(flancersScore), flancersText )))))) ), pubkey, sig) && logicVersion == state.logicVersion && nonce == state.nonces[pubkey=0], “Wrong function name, nonce, logicVersion or failed signature check” )

    let (profile, pi) = getMyProfile(pubkey)
    let task = state.ct_store.getTask(ti)
    require(task.client == pi, "You can only finalize applications on your own tasks")
    require(task.applicationStage[flancer=999] == 1, "This freelancer is not working on this task")

    state.ct_store.setTaskApplicationStage(ti, flancer, 2)
    state.ct_store.setTaskMstoneStage(ti, flancer*10, 2)

    let fi = state.ct_store.getLastFeedbackIndex() + 1
    require(flancersScore >= 1 && flancersScore =< 5 && flancersText != "", "Feedback score must be 1 to 5 and text non empty")
    state.ct_store.setFeedback(fi, ti, flancer, 0, "", flancersScore, flancersText, 1)
    state.ct_store.setLastFeedbackIndex(fi)
    state.ct_store.setTaskFeedback(ti, flancer, fi)
    let profileFlancer = state.ct_store.getProfile(flancer)
    state.ct_store.setProfileFlancerScore(flancer, profileFlancer.flancerScore + flancersScore)
    state.ct_store.setProfileFlancerNumJobs(flancer, profileFlancer.flancerNumJobs + 1)

    put(state{nonces[pubkey] = state.nonces[pubkey=0] + 1})

    fi

also seems to work for me, receiving “Wrong function name, nonce, logicVersion or failed signature check”

const {Universal, MemoryAccount, Node} = require('@aeternity/aepp-sdk');

const keypair = {
  secretKey: "",
  publicKey: ""
};

const config = {
  url: 'https://testnet.aeternity.io/',
  internalUrl: 'https://testnet.aeternity.io/',
  compilerUrl: 'https://latest.compiler.aepps.com'
};

const getClient = async () => {
  return Universal({
    nodes: [{
      name: 'testnet',
      instance: await Node(config)
    }],
    accounts: [MemoryAccount({keypair: keypair})],
    networkId: 'ae_uat',
    compilerUrl: config.compilerUrl
  });
};

const source = `
contract Test =
  public stateful entrypoint finalize : (address, signature, int, int, string, int, int, int, string) => int
`;


const deploy = async () => {
  const client = await getClient();
  const contract = await client.getContractInstance(source, {contractAddress: "ct_2bo1vBzK7jSCE26wd8KGHev7iJ3hFCB8c2r3G4xRcoWbkY9wBn"});
  //console.log(await contract.deploy())

  const finalize = await contract.methods.finalize.get(
    "ak_M65JLCoTNWEiprJT9oTZWrhs5bJJ8mg9SyEdcm3UqW6snTmxK",
    "3f2c42a32835f7fb6519b739c274e8304380d353f38e7b853cef297410cede60664e91ca6ea61aedef2f075749d95fadd29d17eef3154fdb2ef86781249ebc08",
    1, 9, "finalize", 4, 2, 2, "soso");

  console.log(finalize)
};

deploy();

@philipp.chain thanks Piwo!
I figured it out, the error actually happens inside the body of the function, at line:

state.ct_store.setFeedback(fi, ti, flancer, 0, "", flancersScore, flancersText, 1)

There 8 arguments are passed, and I forgot I changed that function in the store contract to take 9 arguments. It’s incredible coincidence that both functions are supposed to take 9 arguments which made this issue confusing :smiley:
Would it be possible to have instead of just decoded error some way to get the line at which it was thrown and stack trace? Or any other ideas?

2 Likes