Hi Andrew @abcoathup,
I trust that you are well.
I’m playing around with a proxy contract system in Remix connected to Ganache via Metamask. I want the function in the implementation library contract to modify the state of the calling contract. So, I need to pass in the storage variable as a parameter (otherwise, how will the library know).
I’ve started with a simple setup where there is a single uint variable to modify. I started by trying to pass in the uint directly, but the compiler threw up an error as it didn’t accept that the uint could be a storage varible (only structs, mappings can be storage variables?). Then I came across an example in a Medium article (https://medium.com/@kidinamoto/library-driven-development-of-solidity-ec7b0b41f38) where they enclosed the uint in a struct. I assume that this is a workaround to be able to give a uint a storage modifier. Does that sound right? (The immediate below is the example from the article)
library TestLib {
struct Data {
uint n;
}
Relatedly, assuming that the above is corrrect, I need to encode a function call so that I can pass it from the proxy state contract to the implementation contract. My testing contracts are below.
The examples from the Solidity documentation (https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding) don’t refer to how to deal with structs. If I was able to call a function with a uint, then it would be no problem. Unfortunately, I don’t know what to hash to produce the function selector. Would I hash ‘setNumber(Data)’? (The first four bytes of this hash are 278de5b8, by the way)
And what about the parameter? Would that just be a uint? So, 0000000000000000000000000000000000000000000000000000000000000045 would be 69.
Actually, I just realized that the parameter is only a reference to a storage variable in the calling contract. So, I shouldn’t have to pass in an encoded parameter. How does that work?
I tried throwing 278de5b80000000000000000000000000000000000000000000000000000000000000045 at the state contract using Remix to send it in the transaction payload. As the state contract inherits, proxy.sol it should forward it on to the implementation contract, but it didn’t work.
Transaction failed! Error:[ethjs-query] while formatting outputs from RPC
library ImplementationTesting {
struct Data {
uint x;
}
function setNumber (Data storage x)
public
{
x.x = 1;
}
}
pragma solidity ^0.7.0;
import './AdminUpgradeabilityProxy.sol';
contract StateTesting is AdminUpgradeabilityProxy {
uint public x;
constructor(address _logic, address _admin, bytes memory _data) AdminUpgradeabilityProxy(_logic, _admin, _data)
{
x = 32;
}
}
I realize that this is a bit convulted. If you can make sense of any of my issues and provide some direction, it would be appreciated. Cheers.
Sincerely,
Craig