[Ethereum] How to pass the external account address to the contract function when calling another contract

contract-developmentsolidity

If we deploy the contract B, and pass the contract B address to the contract A. When call the contract B function from the contract A, inside the contract B function, the msg.sender is the "address of contract A", not external account original calls from the contract A.

Here is the example:

pragma solidity ^0.4.18;

contract metaCoin {
    mapping (address => uint) public balances;
    address[] public addresses;

    function metaCoin() {
        balances[msg.sender] = 10000;
        addresses.push( msg.sender );
    }
    function getBalance(address _addr) public view returns (uint) {
        return balances[_addr];
    }
    function sendToken(address receiver, uint amount) returns(bool successful, address _caller){
        if (balances[msg.sender] < amount) return (false, msg.sender);
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        addresses.push( receiver );
        return (false, msg.sender);
    }
}

contract coinCaller{

    function sendCoin(address coinContractAddress, address receiver, uint amount) public returns (address) {
        metaCoin m = metaCoin(coinContractAddress);
        var (status, addr) = m.sendToken(receiver, amount);
        return addr;
    }
}

Step 1. Using the account, 0x1328500533b017449698300A868fA24eaC1D7486 to deploy metaCoin contract at the address, 0x9628a8814b1b83c67a974f23af8dfd16fea49ae9

Step 2. Use the same account to deploy coinCaller contract at the address 0xd8d5b5f968f119531a941a05682bbbb154d367c0, then call,

coinCaller.sendCoin("0x9628a8814b1b83c67a974f23af8dfd16fea49ae9", "_any_account_addr_", 88)

This function should have transferred the balance from 0x1328500533b017449698300A868fA24eaC1D7486 to _any_account_addr_ with 88. But, it doesn't perform like that. The issue is that in metaCoin.sendToken() the msg.sender is coinCaller contract address, 0xd8d5b5f968f119531a941a05682bbbb154d367c0.

This is documented in the Solidity documentation as the "sender of the message (current call)", which is the coinCaller contract in this call.

Is there a way to work around this to have the external account address of coinCaller.sendCoin()?

Best Answer

It's not possible or even desirable.

You're trying to achieve an arrangement where contract coinCaller can spend ETH that belongs to other accounts.

You should be treating coinCaller more like an escrow account or an ATM. It has it's own balance.

Not possible: coinCaller instructs Alice's wallet to send ETH to Bob.

Is Possible: Alice sends Alice's ETH to coinCaller with instructions to forward or hold for Bob.

It might help to think of the contract as a sort of programmable vending machine.

Hope it helps.

Related Topic