Extending the Smart Contract
In this topic, we want to extend our smart contract so that the owner can withdraw the fees from the contract.
We also want to add a function that performs a simple calculation for us.
Create a new file and add the following source code:
pragma solidity 0.8.20;
contract greeter{
string greeting = "Hello ";
uint256 price = 1 gwei;
address payable public owner;
constructor(){
owner = payable(msg.sender);
}
function greetMe(string memory _name) public payable returns(string memory _greeting){
if(msg.value >= price){
return string(abi.encodePacked(greeting, _name));
}else{
return "";
}
}
function withdraw() public returns (bool success){
if(msg.sender == owner){
(bool success, bytes memory data) = owner.call{value: address(this).balance}("");
// Let the user know, whether the sending was successful or not.
return success;
}
}
function getBalance() public view returns(uint balance){
return address(this).balance;
}
function calculate(uint a, uint b) public pure returns(uint){
return a + b;
}
}
We had to make a few changes to make it work. Let’s go through the pertinent lines.
In line seven, we have to add the keyword payable to the owner’s address. This is necessary to be able to send Ether to this address.
In line ten, we have to cast address to address payable, since msg.sender only returns a non-payable address type.
In line 21, we define the function for our withdrawal.
In line 22, only the owner is allowed to start the withdrawal.
In line 24, we send the amount to the owner. Here, we do this by a “call”. There are two more methods by which Ether can be sent – send and transfer. But they are not recommended.
Let’s have a look at the call statement. The value argument owner.call{value: } takes the amount that should be sent. We want to send the complete balance that is in the contract. This is done by address(this).balance.
The round brackets at the end are not interesting for us right now. With them, it is possible to specify a function of another smart contract that is called. But we want to be able to send the funds also to an EOA. EOAs don’t have functions. That’s why we must not specify a function and provide an empty string instead.
The call-method returns a success variable of type boolean and a data variable. The data variable is only filled if the receiver returns something.
In line 27, we return the success variable (true or false) to the user.
In line 31, we add a function that gives us the actual balance of the smart contract. You should notice the keyword “view”. We can use this to make it clear that we don’t change the state in this function. Instead, we only have a look at the balance and return it.
In line 35, we declare the function calculate.
With functionName(type varName1, type varName2) we can pass multiple parameters to a function.
The state mutability is set to pure. “pure” means that nothing is written to the blockchain and nothing is read from the blockchain. The returns part only states the data type and doesn’t give a variable name. This allows that the return variable remains unassigned.
In line 36, we add a and b and return it.
Now, we want to test our contract.
- Compile your contract, and if there is no error message, deploy it on the Remix VM (London).
- Then, switch to another account by selecting one from the accounts list.
Do a few greetings and pay some fees.
If you want to send some Ether with a transaction, you can state the amount in the field VALUE as shown in the screenshot. You can also chose the unit like Wei, gWei, Ether, etc. (This is like Cents and Euro).
If you click on getBalance, you should see each time that a certain amount is added to your contract’s balance.
Now, switch back to the account from which you deployed the contract. Click withdraw. If you inspect the account’s balance, you should see that the value got sent there. If you have sent only small amounts, you might need to unfold the account field to see the changes, depending on how wide the column is. By clicking on getBalance, you should see that the value is 0.