TypeError: Data location must be "memory" or "calldata" for parameter in function, but none was given - solidity

I am trying the following code but got that error.
If I add memory inside functions params I got new error:
TypeError: Data location can only be specified for array, struct or mapping types, but "memory" was given.
pragma solidity 0.8.7;
mapping (string => uint) wallet;
function saveWalletData(uint _qty , string _name) public{
wallet[_name] = _qty;
}
function consultarWallet(string _name) public view returns(uint){
return wallet[_name];
}

string is a reference type in Solidity. For all reference types, you need to specify their data location (docs).
In this case, you can use calldata for both, because you're not modifying value of the _name variable.
function saveWalletData(uint _qty , string calldata _name) public{
wallet[_name] = _qty;
}
function consultarWallet(string calldata _name) public view returns(uint){
return wallet[_name];
}
If you wanted to modify the value in memory, you'd need to use memory.

Related

Does the order of memory arguments in the Solidity function matter?

i'm trying to make the simple storage using Solidity. Here I'm just trying to map name to some number.
The problem is the following: if I use store_first() it does not work (the retrieve() function returns 0 in any case). But if I change the order of the arguments and place the string memory _name before uint256 _favoriteNumber everything works (the retrieve() function returns correct number)
Does the problem relates to the order (if yes, why?) or I missed something else?
// SPDX-License-Identifier: MIT
pragma solidity >0.6.0;
contract SimpleStorage {
mapping(string => uint256) public nameToNumber;
// If i use this function, the retrieve function always returns 0
function store_first(uint256 _favoriteNumber, string memory _name) public {
nameToNumber[_name] = _favoriteNumber;
}
// If i use this function, the retrieve function returns correct number
function store_second(string memory _name, uint256 _favoriteNumber) public {
nameToNumber[_name] = _favoriteNumber;
}
function retrieve(string memory _name) public view returns(uint256){
return nameToNumber[_name];
}
}

I keep on getting ParseError: Expected type name // when I want to return a struct I have just created

I am new in Solidity and I have been trying to create and get STRUCT without adding it to an Array. I alway see Structs with arrays and the method .push and I wanted to try it without it.
I have created a single Contract with one Struct and one function to create and get it.
If I create a single public function to create, but not return, the struct it doesn´t give me any error... Like the following:
struct Todo {
string name;
uint age;
}
function createTodo(string memory _name, uint _age) public pure{
Todo memory myTodo = Todo(_name, _age);
}
With the above code I would also like to know why it wouldn´t let me set the pointer "Todo" as storage like: Todo storage myTodo = Todo(_name, _age); It gives an TypeError: Todo memory is not implicity convertible to expect type struct storage pointer.
Next, I tried to modify the function to create and RETURN but then is when I start getting the ParseError.
The code is the following:
function getTodo(string memory _name, uint _age) public returns(struct myTodo) {
Todo memory myTodo = Todo(_name, _age);
return myTodo;
}
With the aobve code I also tried in "returns(struct), returns(struct memory)"....
I would really appreciate any type of help here.
Thank you very much
You received this error because you're wrong to set a returns keyword on getTodo() function. In your case, you must change your function in this way:
function getTodo(string memory _name, uint _age) external pure returns(Todo memory) {
Todo memory myTodo = Todo(_name, _age);
return myTodo;
}
If you want to handle storage structs, see this smart contract code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Test {
struct Todo {
string name;
uint age;
}
// Declare state variable
Todo[] todoArray;
// Push into array new struct
function createTodo(string memory _name, uint _age) public {
todoArray.push(Todo(_name, _age));
}
// Retrieve ToDo struct from specific index about struct array
function getTodo(uint _index) external view returns(Todo memory) {
return todoArray[_index];
}
}

Error in solidity code: Return argument type bytes1 is not implicitly convertible to expected type

I have setter and getter:
function setFunc(bytes calldata _value) public {
getBytes = _value;
}
function getFunc() public view returns(bytes calldata) {
return getBytes;
}
When I run my code, the compiler shows that
TypeError: Return argument type bytes1 is not implicitly convertible to expected type (type of first return variable) bytes calldata.
--> contracts/GetterSetter.sol:38:16:
|
38 | return getBytes[];
| ^^^^^^^^^^
Before that I had another error:
TypeError: Data location must be "memory" or "calldata" for return parameter in function, but none was given.
--> contracts/GetterSetter.sol:37:51:
|
37 | function requestedBytes() public view returns(bytes) {
| ^^^^^
Could you help to resolve it and what input example should I provide into setter for correct functions working?
I will be really appreciate for your help!
The getter function return type needs to have the memory data location.
It's because the EVM loads the value from storage to memory, and then returns it from memory.
pragma solidity ^0.8;
contract MyContract {
bytes getBytes;
function setFunc(bytes calldata _value) public {
getBytes = _value;
}
function getFunc() public view returns(bytes memory) {
return getBytes;
}
}
The return type could have the calldata location only if it's returning the actual and unchanged calldata from the input param:
pragma solidity ^0.8;
contract MyContract {
function getFunc(bytes calldata _value) public pure returns(bytes calldata) {
return _value;
}
}
Hm.. I tried in Remix and it looks like woks as it should, but when I run it with Hardhat, it returns Zero.
await getset.setBytes32('0x7465737400000000000000000000000000000000000000000000000000000000');
const getBytes32 = await getset.requestedBytes32();
console.log('Bytes32:', getBytes32);

Solidity - Invalid BigNumber string (argument="value" value="" code=INVALID_ARGUMENT version=bignumber/5.4.2)

solidity newbie here. when I try to read the value of the people array. I'm getting an error:
call to SimpleStorage.people errored: Error encoding arguments: Error:
invalid BigNumber string (argument="value" value=""
code=INVALID_ARGUMENT version=bignumber/5.4.2)
my compiler version is 0.6.6. not sure what's wrong? any suggestions?
// SPD-License_Identifier: MIT
pragma solidity ^0.6.0;
contract SimpleStorage {
uint256 favNum;
struct People {
uint256 favNum;
string name;
}
People[] public people;
function store(uint256 _favNum) public {
favNum = _favNum;
}
function retrieve() public view returns(uint256) {
return favNum;
}
function addPerson(string memory _name, uint256 _favNum) public {
people.push(People(_favNum, _name));
}
}
The error happens when you're trying to call the people() function (from Remix IDE) without passing any value.
Since the People[] public people is a public property, it autogenerates a getter function during compilation. But because it's an array, the getter function requires an uint256 param specifying the index of the array that you want to retrieve.
When you pass an empty string, Remix tries to encode it to the BigNumber instance, but this fails. Only when you pass an (existing) index of the array, it works correctly:
If you want to get the whole array in one call, you need to create a separate getter function:
function getAllPeople() public view returns (People[] memory) {
return people;
}
You must click on the small arrow to the right of the deploy button, then the fields will be displayed so that you can complete the data that the contract must receive.

Iteract with arrays from another contract

Does anyone know how can I read meanings of variables in the array from another contract ? For example:
pragma solidity 0.8.7;
contract Contract1{
uint[] newData ;
constructor(uint _i){
newData.push(_i);
}
}
interface IContract1 {
function newData() external returns(uint[] memory);
}
contract Contract2 {
uint public newOne;
function foo(address _addr, uint _i) external{
newOne = IContract1(_addr).newData()[_i];
}
}
This code has compiled success in the Remix, but I have an error when I trying call foo()
Contract1.newData is an internal (default visibility when you don't specify it) property.
But the interface IContract1 defines an external function named newData() (without the index argument).
You can modify the newData property to have a public visibility, for which the compiler autogenerates a getter function (with the index argument).
Then you also need to update the function definition in the interface, so that it contains the index argument and returns just one item (and not the whole array).
pragma solidity ^0.8;
contract Contract1 {
// changed visibility to `public`
uint[] public newData;
constructor(uint _i){
newData.push(_i);
}
}
interface IContract1 {
// added `_index` argument
// changed the return value to one item of the array
function newData(uint256 _index) external returns(uint);
}
contract Contract2 {
uint public newOne;
function foo(address _addr, uint _i) external{
// changed the call to the getter function
// instead of trying to access the property directly
newOne = IContract1(_addr).newData(_i);
}
}
Note that the Contract1 constructor pushes the first item to the array, so you need to pass 0 (as for the first index) to the foo() function argument uint _i.
Repro steps:
Deploy Contract1 passing it 123 as constructor param. Deployed to address 0x456.
Deploy Contract2
Execute Contract2 function foo(0x456, 0), which will effectively set Contract2.newOne value to 123.