0

There is currently a published contract on the main chain (contract A for short), I must use another contract .somefunction (contract B for short) to call A.somefunction(), but A.somefunction() already uses msg.sender to bring in to use. The following are examples

Contract Acoin is ERC20{
    struct Staking {
    uint256 Coin;
    uint256 ArriveCoin;
    uint256 ArriveTime;
    uint256 Time;
    uint256 State; 
    }
    mapping(address => Staking[]) public All_Staking;
    constructor(string memory name, string memory symbol) ERC20(name,symbol){}
    function SearchStaking() public view returns (Staking[] memory) {
        require(All_Staking[msg.sender].length > 0,"Sorry, This account does not have any Token staking");
        return All_Staking[msg.sender];
    }
}

So I need to write B contract to use msg.sender(caller not B contract) to call SearchStaking of A contract and get the array of AContract.Staking[], if I use All_Staking to call, I can get a single result but no array length.

import "./ACoin.sol";

Contract B is ERC20{
    Acoin public ACoin;
    Acoin.Staking[] private Staking;
    constructor(string memory name, string memory symbol,address _A) ERC20(name,symbol){
    ACoin = Acoin(_A);
    }
    function GetUserAllStaking() public view returns(Acoin.Staking[] memory){
        return ACoin.SearchStaking();    ---->Here should using msg.sender not Contract B address
    }
}
0

1 Answer 1

0

Use delegatecall.

(bool success, bytes memory data) = ACoin.delegatecall(
        abi.encodeWithSignature("SearchStaking()")
);

Note: for this to work you need that bought contract A and B will have the same storage layout.

8
  • I recommend reading the below link for a better understanding: solidity-by-example.org/delegatecall Oct 18, 2022 at 8:11
  • Yes,i tried,and the code tell me to fix like this (bool success, bytes memory data) = address(_A).delegatecall(abi.encodeWithSignature("SearchStaking()"));
    – iop04329
    Oct 18, 2022 at 8:22
  • But there is a problem the Contract A SearchStaking() returns(Staking[] memory) And i call the B contract GetUserAllStaking to return abi.decode(data, (uint256,uint256,uint256,uint256,uint256)); There is a tuple like(uint,uint,uint,uint,uint) But the contract A SearchStaking() return a tuple(uint,uint,uint,uint,uint)[] Example: tuple(uint256,uint256,uint256,uint256,uint256)[]: 1000,1020,1668660432,1666068432,0,1000,1020,1671252456,1666068456,0
    – iop04329
    Oct 18, 2022 at 8:30
  • You need to parse and fix the return values. Because you use low level call
    – matank001
    Oct 18, 2022 at 11:32
  • 1
    The answer is not correct. DelegateCall doesn't "call" another contract, it executes the other contract's bytecode within the actual contract. The call won't be able to update the target contract storage. It is mostly used for proxy contracts. It shouldn't be used for unrelated contracts.
    – Ismael
    Oct 19, 2022 at 20:28

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