I am attempting to write a contract that takes a two Ether deposit, has a function to check the balance of the contract, and also a function to remove the Ether from the contract and send it to the owner.
For example 0x17F
deploys the contract and is the owner, 0xCA3
initialized the accept()
function and two ETH is taken out of that address and appears as in the contract address 0xE2D
. Now I would like to pay out the contract holdings to the owner by way of the collect()
function.
When I try to run the collect()
function, it seems to execute but no ether is removed from the contract and none is sent to the owner.
My code:
pragma solidity >=0.7.0 <0.9.0;
contract AcceptEth {
address public owner;
uint public price = 2 ether;
mapping (address => uint) balance;
//uint256 contractBalance = address(this).balance;
uint256 public val = 1;
constructor() {
owner = msg.sender;
}
function accept() payable public {
// Error out if anything other than 2 ether is sent
require(msg.value == price);
//Remove the 2 ether from the initiator of the accept function, and add it to the contract address balance
balance[address(this)] += msg.value;
}
function check() public returns(uint256) {
//Error out if anyone other than owner tries to check the balance
require(msg.sender == owner);
//Show the balance on the contract address
return address(this).balance;
}
function collect() payable public {
//Error out if anyone other than the owner tries to collect
require(msg.sender == owner);
//Send the ether in the contract address, to the owner of the contract address
balance[owner] += balance[address(this)];
}
}
The last function appears to execute in remix, and renders a green check in the console. Besides that, nothing seems to happen. There may be something fundamental I am missing, so would appreciate if it appears I am doing something wrong in general with my contract if you could let me know.
So my question is, how can I retrieve the ETH from the contract and send it to the owner?
***Note that I am very new to Solidity and there may be lots of problems/misunderstandings I present here, so any commentary would be great.
Best Answer
I'm not sure if this is the block, but many new developers struggle with separating "balance" into protocol ETH balances, which every address has, and internal accounting concerns. A variable called
balance
is just a variable with no actual impact on the coins in the contract or any other user's account.This does internal accounting that isn't necessary and then does not transfer any ether.
A
balances
mapping such as that is usually used to track liabilities to users. Consider a contract with many user deposits. The contract balance would correctly report the funds in the treasury but the contract would be responsible for knowing how much belongs to slice and how much belongs to bob.balance alice: 100 balance bob: 50 balance contract: 150 <= ethereum knows that
Many cases require the contract to keep an eye on user balances (like an ATM) because knowledge of the total funds inside is insufficient for the internal logic, i.e. how much is alive allowed to withdraw?
You have no internal accounting requirement because you want all money to go to the owner. Here's a simple implementation based on your description of the goal.
Hope it helps.