EVM Struct – Manipulating Storage Struct Array with External Library Function Using Delegatecall

delegatecallevmlibrariesstruct

Basic pseudocode mockup of my problem

import libraryB;

contract A{

struct Person{
string Name;
uint age;

}

Person[] public Party;

Party[0] = (Alice, 30); 

libraryB.addAgeToPerson(Party[0], 1)



}

library libraryB{

struct Person{
string Name;
uint age;

}

function addAgeToPerson(Person storage PersonToAddAgeTo, uint ageToAdd) external {
 PersonToAddAgeTo.age += ageToAdd;
}

}

Contract A is using a delegatecall unto the libraryB to use the function, passing the storage pointer to Person[] public Party; The struct is defined in both instances, but I get the error:

TypeError: Invalid type for argument in function call. Invalid implicit conversion from struct Contract A.Person storage ref to struct libraryB.Person storage pointer requested.

Any idea on how to pass a storage struct from a contract into a delegatecall to a Library to work with? I thought delegatecalls preserve the callers context..

Thanks for any input!

Best Answer

Inside Contract A , Person is actually A.Person while in libraryB Person is libraryB.Person when you do the delegate call you are giving a pointer to A.Person to the library that expects a storage pointer to libraryB.Person, hence the error.

Any idea on how to pass a storage struct from a contract into a delegatecall to a Library to work with?

Just define your struct inside your library as described in this answer and change all references to Person in contract A to libraryB.Person like this:

library libraryB {

    struct Person{
        string Name;
        uint age;
    }

    function addAgeToPerson(Person storage PersonToAddAgeTo, uint ageToAdd) external {
        PersonToAddAgeTo.age += ageToAdd;
    }

}

contract A {

    libraryB.Person[] public Party;

    constructor() {
        Party.push(libraryB.Person("Alice", 30));
        libraryB.addAgeToPerson(Party[0], 1);
    }
}
Related Topic