2

I have this struct with many properties. Due to limitations of the solidity stack and practicality of the app, I cannot pass in all the values to the properties when creating a new instance of the struct. Consider the code below:

struct PersonalInfo {
    uint256 tsc;
    bytes32 surname;
    bytes32 firstName;
    bytes32 lastName;
    bytes32 birthdate;
    bytes32 gender;
    uint256 nationalID;
    bytes32 life;
    uint phone;
    bytes32 postalAddress;
    uint currentSchool;
    bytes32 reportingDate;
    bytes32 subject1;
    bytes32 subject2;
    string path
    bytes32 email;
    uint teacherIndex;
}

I want some properties like string path to be added later. This is because in the registration form, I don't have all these properties as form fields that a user fills. However, when creating a new instance of the struct as shown below, I get an error.

      //store teacher details
function storeTeacherDetails(
    uint256 tsc,
    bytes32 surname,
    bytes32 firstName,
    bytes32 lastName,
    bytes32 birthdate,
    bytes32 gender,
    uint256 nationalID,
    bytes32 life,
    uint phone,
    bytes32 postalAddress,
    uint currentSchool,
    bytes32 reportingDate,
    bytes32 subject1,
    bytes32 subject2,
    bytes32 email
) public {
      teachers[teacherRecords.length]=PersonalInfo({tsc:tsc,
      surname:surname,
      firstName:firstName,
      lastName:lastName,
      birthdate:birthdate,
      gender:gender,
      nationalID:nationalID,
      life:life,
      phone:phone,
      postalAddress:postalAddress,
      currentSchool:currentSchool,
      reportingDate:reportingDate,
      subject1:subject1,
      subject2:subject2,
      email:email});
}

After compiling, I get the following error

TypeError: Wrong argument count for struct constructor: 14 arguments given but expected 17.

As a side note, I read somewhere that the stack only goes 7 steps deep. Passing all these parameters at once is a bad idea. I need to group these properties and have getters and setters to each group, but I can only get/set a property of a struct instance that exists. The question therefore is, how do I create an struct instance with say default values for each data type, the set/get then properties later?

1

I think you have to do it the verbose way. You should also save some gas:


function storeTeacherDetails(
    uint256 tsc,
    bytes32 surname,
    bytes32 firstName,
...
    bytes32 subject1,
    bytes32 subject2,
    bytes32 email
) public {
      // Create a storage reference so that actions are immediately done.
      PersonalInfo storage teacher = teachers[teacherRecords.length]; // Or whichever way you pick your storage location
      teacher.tsc = tsc;
      teacher.surname = surname;
      teacher.firstName = firstName;
...
      teacher.subject1 = subject1;
      teacher.subject2 = subject2;
      teacher.email = email;
}
  • Do you have any rough estimations on how much gas could be saved this way? – Paul Razvan Berg Nov 10 '18 at 15:28
0
contract Test {

    struct SomeStruct {
        uint256 a;
        uint256 b;
        uint256 c;
    }

    SomeStruct[] public structs;

    function pushStruct() {
        SomeStruct memory s;
        structs.push(s);
   }

}
  • Thats a brilliant idea. Unfortunately I get an error InternalCompilerError: Stack too deep, try removing local variables. – Sean Apr 15 '18 at 18:04
  • Your struct has too many variables in it. You'll have to remove variables from your struct until that stops happening. From my experience I've been able to get 10 or so variables in a struct before hitting a stack to deep error. – hextet Apr 15 '18 at 18:42
  • Okay..but why does this happen? I have not seen this kind of behavior in other languages i use...e.g js, kotlin,java,php...does it occur in c/c++ coz i understand structs are borrowed from c? – Sean Apr 15 '18 at 19:01
  • It is admittedly tangential to this discussion, but the attempt to overload the contract with so much data is an inappropriate use of the language.You're pushing against limits that aren't problematic when this is used appropriately. Have a look at this: medium.com/solidified/… – Rob Hitchens - B9lab Apr 15 '18 at 20:00
  • @RobHitchens I have to admit this project is an overkill. My 4th year project involves creating a system for the gvt to track students' performance through out their academic lives. I did it in node, but to eliminate fraud, I decided to store the academic documents in the blockchain. Maybe I should stick to that specific part as far as blockchain is concerned, instead of redoing the whole backend in solidity. That would be in line with your link to that article, to make the contract as minimal as possible. – Sean Apr 15 '18 at 20:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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