New to Rust? Grab our free Rust for Beginners eBook Get it free →
How to Send Ethereum to Message Sender in Solidity?

To send Ether back to the address that called your contract, convert msg.sender to a payable address and use call with a value. The withdrawal function must update its accounting before the external payment, then reject a failed transfer.
Send Ether to msg.sender with call
A payable function can receive Ether, and msg.value tells you how much arrived with that call. In a withdrawal, payable(msg.sender).call{value: amount}(“”) sends an amount from the contract balance to the caller.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SenderPayout {
mapping(address => uint256) public credit;
function deposit() external payable {
credit[msg.sender] += msg.value;
}
function withdraw(uint256 amount) external {
require(amount <= credit[msg.sender], "insufficient credit");
credit[msg.sender] -= amount;
(bool sent, ) = payable(msg.sender).call{value: amount}("");
require(sent, "Ether transfer failed");
}
}
Why payable(msg.sender) is required
Because msg.sender identifies the immediate caller as an address, payable(msg.sender) gives it the payable type used by the value transfer expression while the call result reports whether the recipient accepted the payment attempt.
What the success flag means
The low-level call returns a boolean and returned data, so require the boolean because a receiving contract can revert, reject the transfer, or fail while running its receive or fallback function.
Compile the contract
I compiled this contract with solc 0.8.36 and ran a local withdrawal check. The check deposited 1 ETH, withdrew 0.4 ETH, then confirmed that both the caller credit and contract balance were 0.6 ETH.
node compile.js
The compiler should report the SenderPayout contract and its credit, deposit, and withdraw functions.

Protect a withdrawal function before sending Ether
By updating credit before the external call, the function follows the checks-effects-interactions approach and prevents a recipient that calls back into withdraw from spending the same recorded credit again.
Reentrancy changes the order of operations
An Ether payment can execute code in the receiving contract, and a function that decreases credit after calling the recipient lets a callback observe the old balance and attempt another withdrawal.
The receiving address can reject the payment
Keep the failed-transfer check and design a recovery path when your application must handle a recipient that reverts, because a successful compile does not guarantee that every recipient accepts Ether.
When msg.sender is not the address you mean
msg.sender is the immediate caller, not always the end user. A router, multisignature wallet, or another contract becomes msg.sender when it calls your function, so choose an explicit recipient parameter when your payout should target a different address.
Frequently asked questions
The payment line is small, but the surrounding accounting and caller model decide whether it fits your contract.
Conclusion
Use payable(msg.sender).call{value: amount}(“”) when the caller should receive Ether, check its success flag, and reduce the caller credit before the payment. Compile the sample, then replace its simple credit mapping with the access rule and accounting model your contract needs.




