As we have three ways to make a transaction solidity, and all have the same syntax almost.

_to.call or send or transfer // and then we assign the amount.

But who is the sender here? Contract or msg.sender? If it is contract, how to make the sender as the msg.sender and if opposite, vice versas.

3 Answers 3


you should read this Stop Using Solidity's transfer() Now

"Smart Contracts Can’t Depend on Gas Costs If gas costs are subject to change, then smart contracts can’t depend on any particular gas costs.

Any smart contract that uses transfer() or send() is taking a hard dependency on gas costs by forwarding a fixed amount of gas: 2300.

Our recommendation is to stop using transfer() and send() in your code and switch to using call() instead:"

  • This doesn't answer the question.
    – vampireAb
    Commented Feb 1, 2023 at 18:34
  • for all is msg.sender the caller. The smart contract takes the caller's context (value and address). It can be different only by using delegate call gasless transactions
    – Catalin
    Commented Feb 2, 2023 at 5:28

The sender from msg.sender is the initiator of the message or caller of the function that sent the message.

Msg.sender will contain the address of the calling smart contract, or EOA. The transaction origin (tx.origin) will refer to the EOA that signed and sent the transaction to the network,

So msg.sender can be either : -EOA aka Externally owned account or -Contract account.

it's the EOA when the message, call, or transaction is initiated by an externally owned account.

it's the Contract account when a smart contract who receive a transaction or call originated from an Externally owned account (tx.origin) call a method that belongs to another smart contract.

The originator of the transaction will be the EOA (tx.origin), but the sender will be the Contract account.


You can try to deploy the following contract in Remix

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.17;

contract Test {
    function sendETH(address to) external payable {
        (bool sent, ) = payable(to).call{value: 1 ether}("");
  1. When Alice(EOA) call sendETH() to Bob, and set value: 2 ETH, then you will get

    Test: 0 -> 1 ETH

    Bob: +1 ETH

  2. Alice(EOA) call sendETH() to Bob again, and set value: 0 ETH, then you will get

    Test: 1 -> 0 ETH

    Bob: +1 ETH again

From this, it can be found that the token flow is "EOA -> Contract -> EOA".

The _from of the call() method is the contract Test (address(this))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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