Is there a way to drain all the user.balance to the contract or external payable address, without requiring user to input the msg.value?

The most intuitive version I had looks a bit like this on solidity 0.5.0:


However it seems like contract address is inherently not payable, so I tried to first cast it into a payable address:

address payable payableContract = address(uint160(address(this)))

But it doesn’t seem to work either. Someone suggested me to look into Contract Factory which might solve the problem. What would be the best way to get around it, in order to achieve the same result?

  • A contract can't forcibly take a user's ether.
    – user19510
    Commented May 29, 2019 at 5:43
  • @smarx Is there a way for the user to pre-authorize the transaction?
    – Hugo
    Commented May 29, 2019 at 10:54
  • The only way an externally owned account's balance can be transferred is if that account sends a transaction that does transfers that ether away.
    – user19510
    Commented May 29, 2019 at 12:46
  • @smarx Like a escrow contract?
    – Hugo
    Commented May 29, 2019 at 15:31
  • Are you talking about Eth balance or ERC20 balance? I'll show you what you _can_do, but focusing on one or the other will simplify it. Commented May 30, 2019 at 17:33

1 Answer 1


You need to reverse the flow of things or this will never make sense.

There is no way to code a contract to transfer funds from a user wallet. Not all, not some, not any.


That means the destination (to) is address(this) and the amount is the msg.sender's balance. from: address is implicitly address(this) because nothing else is possible. Therefore, from isn't mentioned in the syntax.

What you actually want to happen is for the user to sign a transaction that sends their money to your contract. I don't know why it has to be their entire balance and that sounds to me like another design misstep but here is how you would do it.

It's a front-end concern. Again, for emphasis, because only the user can authorize the transfer of their own funds. On the contract side, all you can do is receive it, validate the transaction and possibly reject it if something is wrong.

function depositFunds() public payable {
  // carry on
  // msg.value and msg.sender inform about who and how much

On the front end you would Web3 or a similar library to help the user form a valid transaction with amount: as much as possible, to: your contract, {gas: amount, gasPrice: bid}.

The user has to pay for gas, and this will reduce the amount of funds available to send to your contract. You have to take that into account. Your front end will have to figure out:

  • gas estimate for the transaction
  • gasPrice (Ether cost consumed = gas estimate * gasPrice)
  • Funds available to send (user's balance - cost consumed), leaving the user with exactly 0 remaining balance.

If the browser (or server) performs the computation, then the user will be presented the option to sign a transaction sending x amount, and bidding y for gas, with a gas estimate of z leaving them with a final balance of 0.

It's unclear to me why anyone would agree to such terms.

Hope it helps.

  • Hey Rob, really appreciate your effort and time to answer this question. I enjoy your charity and details in the response. We want to build something that essentially requires Alice to pre-authorize a pending transaction that will send her entire balance to Bob on a future date. Therefore, one of the biggest design challenges is that we don't know what that future msg.balance will be, when certain conditions are met.
    – Hugo
    Commented May 30, 2019 at 23:09
  • The simplest approach is to have Alice to place some funds in a contract that will only release to Bob. Bob would be able to see the funds are locked up for him. A lot depends on the real use case you have in mind. Commented May 31, 2019 at 0:47
  • Are there other approaches that can creatively get around it?
    – Hugo
    Commented May 31, 2019 at 16:15
  • As asked, nothing obvious, but the way you describe "send full balance" does not seem reasonable to me. I think you might be imposing hidden assumptions into a use-case that should be approached another way. If you were my client, I would ask you what Alice and Bob need to know and do and keep asking until you explain it without telling me how you think it should be coded. Commented May 31, 2019 at 16:19
  • 1
    Thanks for all the advices you've provided so far. Been looking up multi-sig wallets for the past hour now. Ethereum community definitely needs more people like yourself. You are the man, Rob!
    – Hugo
    Commented May 31, 2019 at 23:42

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.