Receive function in a contract without withdraw

At first it is impossible to recover a balance from a contract that does not have a withdrawal.

But, theoretically, if a contract inherited this. Being the same owner, would it be possible to implement a withdraw function for the inherited contract?

The main problem I see is that an ethers transfer cannot be done from another account. That is, you can't set a "from" other than the address.this, right?

I think the answer to your question is that yes you can define receive in a contract and then inherit that contract to add a withdrawal function.

Thanks for your answer.

I was thinking the same until I saw the following problem. All transfers are made from the original contract. Therefore, the transfer is made from the main contract and not from the inherited contract. How can you order a transfer from another contract? I think here is the key.

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

contract Receive is Ownable
{   
       constructor() {}
    
    
     function getBalance() public view onlyOwner returns(uint256)
    {
        
        return address(this).balance;
        
    }
    
	receive() external payable {}
	
}

If we inherit this contract we can access to balance without problems but the withdraw function does not come out from it. And without it leaving from that inherited address the contract cannot be emptied.

Withdraw Contract:


//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./Receive.sol";

contract Withdraw is Ownable
{   
      // The token contract
     Receive public token;

     constructor(Receive _token) 
    {
       token = _token;

    }
    
    function getBalance() public view onlyOwner returns(uint256)
    {
        
        return address(token).balance;
        
    }

    
        function withdraw() public onlyOwner payable
    {
        uint256 amount = address(token).balance;
        token.payable(owner()).transfer(amount); // this is impossible!!


    }
    
}

But how do you make a transfer FROM the inherited contract?

There is no such distiction, a contract and its inherited contracts all live under the same context (address, storage, balances).

And how would you solve the example that I have shown you?

It's not really a problem, the line that you point out as impossible should work without issue.

In this way the syntax is not allowed:


And in this way it also fails, reverts the transaction. Although I logically think that you will only access the balance of the contract withdraw.sol that is at zero.

I don't see a way to access the balance of the Receive contract.

Ok I just read your code more closely and I see that you have this:

contract Withdraw ... {
    constructor(Receive _token) {
       token = _token;
    }

This is not inheritance. Inheritance would be if you wrote contract Withdraw is Receive. In what you have written, it is correct that you will not be able to withdraw the balance of Receive.

First of all, thank you for your answers.

I understand what you tell me in this last post as well as you indicate of course that you can.

But the problem is with contract already deployed with receive function but without withdraw function.

That is why it used the address as if it were an interface

I understand then that a deployed contract cannot be inherited and therefore its balance cannot be accessed.

Exactly. Only the contract can access its own balance.

Confirmed that you cannot withdraw ethers in a contract without this function. What is received will be trapped in it forever.

Thanks for your reply