[Ethereum] Data location must be “calldata” for parameter in external function, but none was given

remixsolidity

I'm trying to compile my code in Remix and I try to fix it but I keep getting the same error:

Data location must be “calldata” for parameter in external function, but none was given".

The problem is in the function createNewUser() external

event startMessage(string message);

function createNewUser (string _name, string _email, uint _aadhaar, string _sign) external {
  if((checkUser[msg.sender] == true)||(checkAadhaar[_aadhaar] == true))
  {
    startMessage('Failed !! User already Registered..');
  }
  else if((checkUser[msg.sender] != true)&&(checkAadhaar[_aadhaar] != true))
  {
    var newUser = Person(msg.sender, _name, _email, _aadhaar, _sign, new uint[](0), new uint[](0));
    addressToPerson[msg.sender] = newUser;

    checkUser[msg.sender] = true;
    checkAadhaar[_aadhaar] = true;

    startMessage('Welcome !! Successful Registration on Charter');
  }
}

Best Answer

Either

function createNewUser (string memory _name, string memory _email, uint _aadhaar, string memory _sign) public

or

function createNewUser (string calldata _name, string calldata _email, uint _aadhaar, string calldata _sign) external

Explanation:

Unlike tradition computers, EVM has many different “memories”, each accessed with its own set of instructions. Thus one cannot have “universal” memory pointer, but has to use different pointer types for different “memories”.

In Solidity, all reference types, such as string, bytes, or struct, should always be accompanied with explicit specifier telling the compiler what “memory” the reference actually refers to. See Reference Types section in documentation for details.

While, basically, “external” is just syntactic sugar for “public“, for some reason Solidity compiler disallows “memory” references in “external“ function parameters. The documentation just says:

Note that external functions require parameters with a data location of calldata.

without any further explanation. The compiler also disallows “calldata” references in parameters of non-“external” functions, and there is good reason for this, because non-“external” functions may be called internally, thus there could be no call data at all.