@ivga80 @filip @gabba @pedromndias
Here are a few questions I have from this section about payable functions…
Question 1
This question is about the position of…
balance += msg.value;
…in the createPerson
function.
In the assignment, why is it ok to add msg.value
to the contract’s balance at the beginning of the function body, immediately after require()
? … instead of putting this code at the very end, like we did with emit
?
If emit
is placed before assert()
the event still shouldn’t be emitted if assert()
fails, because revert is called and cancels execution of all of the function body’s prior code. Despite this, however, in the lesson we learnt that it is still safer to place emit
at the very end of the function body, as we only want to emit the event if the new person is definitely created. So, surely this same security logic should apply to updating the balance — only doing it at the very end of the function body when we can be sure execution has been successful, and the ether definitely charged and credited to the contract…
Question 2
The assignment solution defined the state variable balance
as public
:
uint public balance;
In reality, is it more likely that the contract owner would want the contract balance to be stored in a private
state variable, with a separate getter function (restricted to the contract owner) to access the balance? e.g.
address public owner;
uint private balance; // balance defined as private
constructor() public {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Operation restricted to the contract owner");
_;
}
/* public getter function wrapped around private balance variable,
but access restricted to contract owner */
function getBalance() public view onlyOwner returns(uint) {
return balance;
}
I wanted to add the name balance
to the uint
returned from the getBalance
function (just like we did previously with age
and height
— but when I add this to the code, as follows …
returns(uint
balance
)
… it throws the following warning (and I don’t understand what the problem is):
Warning: This declaration shadows an existing declaration. ...
... The shadowed declaration is here:
uint private balance; // Use with getBalance function restricted to onlyOwner
Question 3
I tried to make the getPerson
function payable
but it throws an error because it seems that view
is incompatible with payable
— does this mean that viewing a contract’s data must always be free of charge?
Question 4
Why did we include a return
statement in the withdrawAll
function, when, as far as I can see, we aren’t using the returned value (the total balance withdrawn) anywhere? Is it because it gives us the option of using this value somewhere else in the contract? If so, what functionality could we add that would utilise it? I’ve tried to experiment with this, but without any results…