Hi @tinyHamster
I had modify a bit your sample to answer your questions you can find it bellow
When passing a gender to the addPerson function the number you pass should be existing in the enum:
An enum start from 0 and increments itself automatically, so for your Gender enum it will have only 0 and 1 available as gender.
addPerson -> âjoeâ,âfooâ,20,1 //is correct
addPerson -> âsarahâ,âbarâ,24,0 //is correct
addPerson -> âeggâ,âfriedâ,12,6 // will fail and trow an error âtransact to PersonContract.addPerson errored: VM error: invalid opcodeâ
Because 6 is not define in your enum.
To display the available value of an enum you have different options the one i prefer is to add a âlastâ enum and to display the value of the last enum -1.
You can also hard code it in a string.
Let me know if you want more information and if i had answer your questions
pragma solidity 0.5.1;
contract PersonContract{
constructor () public {
owner = msg.sender ;
}
address owner ;
/*
* If you don't set a value to the first enum
* the value of the first enum will be zero
* so in this case female ==0 and male==1
*/
enum Gender {female, male, notBinary, last}
struct Person {
string name;
string lastName;
uint age;
Gender varGender;
}
mapping (address => Person[]) mapPerson;
function addPerson ( string memory _name, string memory _lname, uint _age, Gender _gender ) public returns (uint){
require(_gender == Gender.female || _gender == Gender.male,
"Gender should be 0 for female and 1 for male");
return mapPerson[msg.sender].push(Person(_name, _lname, _age, _gender))-1 ; // how can an user select the gender , by typing jjust 0,1 ?
}
// Here we show that 2 is the maximum value female=0,male=1,notBinary=2
function MaximumValueForGender() pure public returns(uint){
return uint(Gender.last) - 1;
}
function showGendersWithString() pure public returns(string memory){
return ("Directly write the option here: female=0,male=1,notBinary=2");
}
function callPersonGender (uint id) view public returns (string memory){
string memory gender;
if (mapPerson[owner][id].varGender == Gender.male)
gender = "male";
else if (mapPerson[owner][id].varGender == Gender.female)
gender = "female";
return gender;
}
}
Edit:
You can also use an input as a string but it ll cost more gas to compare the string passed as argument.
function compareString(string memory _name) pure public returns(Gender){
if(uint(keccak256(abi.encodePacked("male"))) == uint(keccak256(abi.encodePacked(_name)))) {
return Gender.male;
}else if(uint(keccak256(abi.encodePacked("female"))) == uint(keccak256(abi.encodePacked(_name)))) {
return Gender.female;
} else{
return Gender.notBinary;
}
}
function addPersonWithString ( string memory _name, string memory _lname, uint _age, string memory _gender ) public returns (uint){
require(compareString(_gender) == Gender.notBinary,
"Gender should be 'male' or 'female'");
return mapPerson[msg.sender].push(Person(_name, _lname, _age, compareString(_gender)))-1 ;
}