4

I'm trying to create a very simple proxy contract that forwards my transaction/call and nothing else.

So User A > transaction to P(roxy)C > Call to Contract (msg.sender = user A)

i've tried two ways to get this too work (low level call and abstract function), but I'm not sure what could be the problem here. This works locally, but not live.

 contract ContractProxy {
    address public _owner; 
    address public _targetcontract;
    event CallContract(bool succes);

    function ContractProxy(address target) public {
        _owner = msg.sender;
        _targetcontract = target;
    }

    function callcontract(uint contractgas, address targetu, uint nonce, address user, uint8 v, bytes32 r, bytes32 s, uint amount) public {
        require(_owner == msg.sender);
        if(_targetcontract.call.gas(contractgas)(bytes4(keccak256("targetfunction(address,uint256,address,uint8,bytes32,bytes32,uint256)")), targetu, nonce, user, v, r, s, amount)){
            CallContract(true);
        } else {
            CallContract(false);
        }
    }

    function changetargetaddress(address newaddress) public {
        require(_owner == msg.sender);
        _targetcontract = newaddress;
    }}

I added the event to find out what's going on, but it appears to be false. The function name parameters and types appear to be correct, so I'm wondering what else could cause an error. So some questions..

  1. Is call executed in the original context of the account calling the proxy contract?
  2. How can I find out what the error for the underlying contract is? I suspect a gas issue, can I find out? Should I throw when the call returns false?
  3. I read you need to be carefull when working with low level calls and return values.. could that be an issue here? The function doesn't actually return a value.
  4. I am now trying to get this to work with an abstract contract. When I deploy this with mist, the code is valid, but I only deploy my proxy contract (with MIST) and feed it the real contract's address. From what I understand, that's how it's supposed to work? Feels a bit weird/like a trick, but I read that abstract contract is the way to go here. Thoughts?
  • It currently is not possible to do what you are trying to do. See Difference call vs callcode vs delegatecall. Both call and callcode modify msg.sender (difference is callcode does not switch to a new context, it uses callers storage), delegatecall does not modify msg.sender but it also uses callers storage. – Ismael Oct 8 '17 at 17:35
  • This makes sense and was actually the issue. Thanks for point me in the right direction – Syg Oct 11 '17 at 21:30
1

I had similar issues and it was caused by two issues:

  • _targetcontract is invalid: add "require(_targetcontract != 0)"
  • parameters are not padded to 32 bytes: for example, some of the parameters like "uint8 v" in targetfunction are not aligned to 32 bytes. In my case, I found such parameters "disappeared" during the call.

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.