0

I have a public function that accepts some data from users and i basically want to store this data into a struct that is mapped to an address.

This is the definition of the Struct :

struct APINodeJobResponse {
        uint256 jobId;
        uint256[] responseValue;
    }

This is the definition of the mapping :

mapping(address => APINodeJobResponse) public jobResponses;

This is the function that fails to execute :

function receiveRevealedAPIJobResult(
        uint256[] memory dataValues,
        uint256 rand,
        uint256 jobId
    ) public {
        //fetch committment string to ensure no tampering
            APINodeJobResponse memory newJobResponse;
            newJobResponse.jobId = jobId;
            for (uint i = 0; i < dataValues.length; i++) {
               newJobResponse.responseValue[i]= dataValues[i];
           }
            jobResponses[msg.sender] = newJobResponse;
    }

I've been at this for more than 6 hours. Scoured the web trying to figure out what is happening and ran into numerous (Out of gas) exceptions. When I got out of gas exceptions my thought went to that i cant save dynamic data onto a storage variable since EVM cannot know before hand the size of the data.

Now I have no idea what the problem is but it seems to have a problem with the saving part (to the storage variable)

This is the error :

Error: Returned error: VM Exception while processing transaction: invalid opcode
    at Object.ErrorResponse (/Users/moustafa/Documents/veritas/veritas/oracleNodeNetwork/node_modules/web3-core-requestmanager/node_modules/web3-core-helpers/lib/errors.js:28:19)
    at Object.callback (/Users/moustafa/Documents/veritas/veritas/oracleNodeNetwork/node_modules/web3-core-requestmanager/lib/index.js:302:36)
    at /Users/moustafa/Documents/veritas/veritas/oracleNodeNetwork/node_modules/web3-providers-ws/lib/index.js:114:45
    at Array.forEach (<anonymous>)
    at WebsocketProvider._onMessage (/Users/moustafa/Documents/veritas/veritas/oracleNodeNetwork/node_modules/web3-providers-ws/lib/index.js:102:69)
    at W3CWebSocket._dispatchEvent [as dispatchEvent] (/Users/moustafa/Documents/veritas/veritas/oracleNodeNetwork/node_modules/yaeti/lib/EventTarget.js:115:12)
    at W3CWebSocket.onMessage (/Users/moustafa/Documents/veritas/veritas/oracleNodeNetwork/node_modules/websocket/lib/W3CWebSocket.js:234:14)
    at WebSocketConnection.<anonymous> (/Users/moustafa/Documents/veritas/veritas/oracleNodeNetwork/node_modules/websocket/lib/W3CWebSocket.js:205:19)
    at WebSocketConnection.emit (node:events:390:28)
    at WebSocketConnection.processFrame (/Users/moustafa/Documents/veritas/veritas/oracleNodeNetwork/node_modules/websocket/lib/WebSocketConnection.js:554:26)
    at /Users/moustafa/Documents/veritas/veritas/oracleNodeNetwork/node_modules/websocket/lib/WebSocketConnection.js:323:40
    at processTicksAndRejections (node:internal/process/task_queues:78:11) {
  data: {
    '0x5a54387c1a44c929ceaf2060539e2c54b5e9435b29f7138a794a22c6a705bf86': { error: 'invalid opcode', program_counter: 2460, return: '0x' },
    stack: 'RuntimeError: VM Exception while processing transaction: invalid opcode\n' +
      '    at Function.RuntimeError.fromResults (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n' +
      '    at BlockchainDouble.processBlock (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/blockchain_double.js:627:24)\n' +
      '    at runMicrotasks (<anonymous>)\n' +
      '    at processTicksAndRejections (internal/process/task_queues.js:93:5)',
    name: 'RuntimeError'
  }
}

I get this error from the js client (user) script that is trying to call this function.

Any help is greatly appreciated.

Thank you

1 Answer 1

1

The array within your struct is in memory, you first need to initialise it (with a given length, to allocate the appropriate space) - see https://docs.soliditylang.org/en/latest/types.html#allocating-memory-arrays

This code doesn't revert (notice the newJobResponse.responseValue = new uint[](dataValues.length);)

function receiveRevealedAPIJobResult(
        uint256[] memory dataValues,
        uint256 rand,
        uint256 jobId
    ) public {
        //fetch committment string to ensure no tampering
            APINodeJobResponse memory newJobResponse;
            newJobResponse.jobId = jobId;
            newJobResponse.responseValue = new uint256[](dataValues.length);
            for (uint i = 0; i < dataValues.length; i++) {
               newJobResponse.responseValue[i]= dataValues[i];
           }
            jobResponses[msg.sender] = newJobResponse;
    }
2
  • I tried this before, and I get an OUT OF GAS error :( ` Error: Returned error: VM Exception while processing transaction: out of gas ` Jan 7, 2023 at 13:56
  • How long was the array and how much did you use? I tried my solution in Remix without revert Jan 7, 2023 at 18:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.