When I try to exceute a solidity smart conract function to store 32 input parameters, I am getting a stack too deep error.

To resolve that, at the middleware we have consolidated and created an array of bytes32 for 24 input parameters and the rest of the 8 parameters are of string datatype. But again we get the same stack too deep error.

How can I possibly exceute a function to store the 32 input parameters?

We are making use of solidity compiler version 0.4.25.

This is the basic skeletal of code

struct Sample {
    bytes32 key;
    string str1;
    .
    .
    .
    .
    .
    string str8;
    byts32[] someArray; //23 elements
}

mapping(bytes32 => Sample) sampleMap;

function set(bytes32 key,string str1,string str2,......,string str8,bytes32[] array) public returns(bool) {
    //set the values using sampleMap mapping;
    return true;
}

function get(bytes32 key) returns(bytes32 key,string str1,string str2,......,string str8,bytes32[] array) {
    //retrieve values from struct using sampleMap mapping
}
  • Link to your code? – Edmund Edgar Oct 11 at 6:54
  • Have edited the question to include basic skeletal of code – user44305 Oct 11 at 7:14

There is no way of having a stack push so heavy in EVM/solidity.

Pass the address of a storage array to be filled just before the call or, better, write your input parameters in a suitable public struct or data repository and call the function without any parameter, accessing the data directly in storage area.

The concept is:

p1 = argument n.1
p2 = argument n.2
.
.
.
pn= argument n. N

foo();

Where in foo() some elaboration using p1...pN is realized

instead of

foo(p1, p2, ..., pN)

If you don't mind using the ABIV2Encoder, then you can do this:

pragma solidity 0.4.25;
pragma experimental ABIEncoderV2;

contract Example {
    struct Sample {
        bytes32 key;
        string str1;
        .
        .
        .
        .
        .
        string str8;
        byts32[] someArray; //23 elements
    }

    mapping(bytes32 => Sample) sampleMap;

    function set(Sample data) public returns(bool) {
        sampleMap[data.key] = data;
        return true;
    }

    function get(bytes32 key) returns(Sample) {
        return sampleMap[key];
    }
}

To avoid a Stack too deep exception I would break it down in small transactions doing one transaction to store one string.

struct StringStorage {
    bytes32 key; // Key
    mapping(uint => string) strings; // Each strings is associated to an index
}

mapping(bytes32 => StringStorage) db; // Global storage

/*
 * Create a StringStorage
 */
function createStringStorage(bytes32 _key) public returns(bool) {
    require(db[_key].key[0] == 0, "StringStorage already exists");

    db[key].key = _key;

    return true;
}

/*
 * Add a string to a StringStorage for a given index
 */
function set(bytes32 _key, uint _index, string _str) public returns(bool) {
    require(db[_key].key[0] != 0, "StringStorage doesn't exist");

    db[key].strings[_index] = _str;

    return true;
}

/*
 * Returns a given string in a StringStorage
 */
function get(bytes32 _key, uint _index) returns(string) {
    return db[_key].strings[_index];
}

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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