1
votes

I am develop a small ethereum website project . I know I am very new at this. I started to learn the basics of solidity but I have an issue I do not know how to solve . I hope I got someone how can help me .

Here the code I want to use the Person data as struct to the HistoryRecode inorder to track his/her information . but I got this error .

project:/contracts/Passport.sol:102:47: TypeError: This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature.
  function getPassport() public view returns (Person memory) {
                                              ^-----------^
,project:/contracts/Passport.sol:108:41: TypeError: This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature.
  (uint256 incidentTime, address owner, Person memory person) {
                                        ^------------------^

Compilation failed. See above.
Truffle v5.4.3 (core: 5.4.3)
Node v16.3.0
contract Compeny{
  address constant  ADMIN_ADDRESS = 0x8c0199C5D6e4B22A1948358F1bf48dD095Ae5300; 

  struct Person {
    uint ppNo ;
    bytes32  firstName;
    string gender ;
    string dayOfbirth ;
    string country ;
  }
   mapping(address => Person) private PersoneDictionary;
   HistoryRecord[] private historyRecords;
  function createOrUpdatePassport(
        address _owner,
        uint _ppNo ,
        bytes32 _firstName ,
        string memory _gender ,
        string memory _dayOfbirth ,
        string memory _country 
        ) public 
  {     
     checkAdminPermission();
    Person memory person = Person(
        _ppNo ,
     _firstName ,
     _gender ,
     _dayOfbirth, 
     _country 
     ) ;

      PersoneDictionary[_owner] = person;
      historyRecords.push(HistoryRecord({
          incidentTime : block.timestamp ,
          owner : _owner,
          person : person 
     }));
  }

  function getPerson() public view returns (Person memory) {
      return PersoneDictionary[msg.sender];
  }

 
  function getHistoryRecord(uint index) public view returns 
  (uint256 incidentTime, address owner, Person memory person) {
      checkAdminPermission();
      return (historyRecords[index].incidentTime, 
              historyRecords[index].owner, historyRecords[index].person);
  }

  struct HistoryRecord {
      uint256 incidentTime;
      address owner;
      Person  person;
  }

  // utility functions
  function getHistoryRecordLength() public view returns (uint) {
      checkAdminPermission();
      return historyRecords.length;
  }

  function checkAdminPermission() private view {
      if (msg.sender != ADMIN_ADDRESS) {
          revert();
      }
  }

}



1
I personally use Remix as IDE but it does not throw error for this contract in compiler version 0.8.4 ! But I had such problem before and I just added pragma experimental ABIEncoderV2 next to pragma solidity ^0.8.0 and problem was solved, try it! - Ahmad Gorji

1 Answers

0
votes

As far as I remember, you cannot return a struct unless you add the pragma experimental ABIEncoderV2 to your contract. As the name suggests that it is experimental and also limited to the internal functions.

Take a look at this question here

So what you can do is return all struct values individually like this:

function getPerson() 
public view returns(uint ppNo,  bytes32 firstName, string memory gender, string memory dayOfbirth, string memory country) 
{
    return (PersoneDictionary[msg.sender].ppNo, PersoneDictionary[msg.sender].firstName, 
            PersoneDictionary[msg.sender].gender, PersoneDictionary[msg.sender].dayOfbirth, 
            PersoneDictionary[msg.sender].country);
}