While I’m on a roll, here are the other questions I have about this section on Error Handling:
Quiz question: When should you use
Answer: To avoid conditions which should never, ever be possible.
I put to avoid compilation errors, because
assert() can throw if there is an error in our code which does not comply with an invariant. However, is my answer wrong, because compilation errors refer to syntax and so won’t actually trigger
assert() , which is instead only triggered by coding errors which would result in an output which should be impossible (i.e. one that fails to meet an invariant condition)?
people[msg.sender] should always be equal to
newPerson (this is our invariant)
… so I understand why we need to combine the properties of each of these into single hex values with
abi.encodePacked() in order to be able to compare them.
But why does Solidity further require us to hash these hex values? Surely, if the unhashed hex values equal each other, this is enough to prove that our invariant condition has been met?
deletePerson function we have the following
assert(people[creator].age == 0);
I extended this as follows, and as expected it also works:
assert( people[creator].age == 0 && people[creator].height == 0 && people[creator].senior == false );
However, why can’t we also use the following, and how could we get it to work?
assert(people[creator].name == "");
Also, if we have deleted the person from our mapping, why do we still have a struct which contains the properties: age 0, height 0, senior false? Surely, if the person has been deleted, an
assert function with the above conditions for invariants should still fail, because the properties age, height and senior shouldn’t even exist? Instead, it seems like we still have a person, but one with no name, height 0, age 0 (and not a senior).
This anomoly is also evident when
getPerson is called for the same account which has just had its person deleted — it returns a person with no name, age 0, height 0, and senior
This seems strange to me — what’s actually happening here?
Following on from Question 3, if the whole
Person struct isn’t actually deleted, but its properties just effectively set to falsy values, could we improve the
getPerson function by including a
require function that throws and cancels execution if either:
(i) no person has been created for that address yet; or
(ii) the person created has since been deleted?
It would make sense to me that in these circumstances we should receive an error message such as “You must create a person before you can get it”, rather than
getPerson returning a person with no name, age 0, height 0, and senior
false, as it does at the moment.
In an attempt to create something along these lines, I’ve added the following to the
getPerson function body:
require( people[msg.sender].height != 0, "You must create a person before you can get it" );
This works, but it’s hardly ideal. Can we not ensure that the whole
Person struct is deleted from the mapping, and then have a
require function with the condition that a
Person struct exists for this address (no matter what property values it contains), and failing if it doesn’t?