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

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];
}
}

Related

how to override openzeppelin _countVote function in GovernorCountingSimple.sol file?

I am making a DAO using openzeppelin and I downloaded the governance contract that they provide from the openzeppelin contract wizard. once I had imported this file into remix IDE an error popped up saying
"Function has to override specified but does not override anything"
so I followed that error to the GovernorCountingSimple.sol file and saw that it was the _countVote function but I can't seem to override it. I think I am just missing something simple but I don't know how to override it when the last argument within the function is "bytes memory" with no declared name and I cant seem to just call the super statement on the function to pass the last argument.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "#openzeppelin/contracts/governance/Governor.sol";
import "#openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "#openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "#openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "#openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
import "#openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
contract GovernernerContract is Governor, GovernorSettings, GovernorCountingSimple,
GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl {
constructor(
IVotes _token,
TimelockController _timelock,
uint256 _votingDelay,
uint256 _votingPeriod,
uint256 _quorumPercentage
)
Governor("governernerContract")
GovernorSettings( _votingDelay /* 1 block */, _votingPeriod /* 45818= ~ 1 week */, 0)
GovernorVotes(_token)
GovernorVotesQuorumFraction(_quorumPercentage)
GovernorTimelockControl(_timelock)
{}
// The following functions are overrides required by Solidity.
//this is my attempt to override the function but i dont know how to deal with the bytes
//memory argument
function _countVote(
uint256 proposalId,
address account,
uint8 support,
uint256 weight,
bytes memory // params
) internal override {
// super._countVote(proposalId,account,support,weight,*);
}
function votingDelay()
public
view
override(IGovernor, GovernorSettings)
returns (uint256)
{
// return super.votingDelay();
}
function votingPeriod()
public
view
override(IGovernor, GovernorSettings)
returns (uint256)
{
return super.votingPeriod();
}
function quorum(uint256 blockNumber)
public
view
override(IGovernor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
function state(uint256 proposalId)
public
view
override(Governor, GovernorTimelockControl)
returns (ProposalState)
{
return super.state(proposalId);
}
function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description)
public
override(Governor, IGovernor)
returns (uint256)
{
return super.propose(targets, values, calldatas, description);
}
function proposalThreshold()
public
view
override(Governor, GovernorSettings)
returns (uint256)
{
return super.proposalThreshold();
}
function _execute(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
internal
override(Governor, GovernorTimelockControl)
{
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}
function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
internal
override(Governor, GovernorTimelockControl)
returns (uint256)
{
return super._cancel(targets, values, calldatas, descriptionHash);
}
function _executor()
internal
view
override(Governor, GovernorTimelockControl)
returns (address)
{
return super._executor();
}
function supportsInterface(bytes4 interfaceId)
public
view
override(Governor, GovernorTimelockControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
You was closer to the solution...
Just change this line: super._countVote(proposalId,account,support,weight,*);
Instead of using this symbol * to omit last parameter, try with single quotes.
This should work:
super._countVote(proposalId,account,support,weight,'');

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

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.

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.

Solidity Mapping use string to find struct?

I want to use the mapping find the struct but the mapping just can use the bytes and I need to use the string.
pragma solidity >=0.4.22 <0.6.0;
pragma experimental ABIEncoderV2;
contract land{
address public owner;
constructor() public{
owner = msg.sender;
}
struct Landpaper{
string number;
string landaddress;
string landnumber;
string landpurpose;
uint landgrades;
uint256 landarea;
string holdpoints;
}
mapping(bytes8 => Landpaper) public lp;
modifier Permission(){
require(msg.sender == owner);
_;
}
function set(string memory rfidnumber, Landpaper memory _landpaperRecord) public Permission{
lp[rfidnumber]=_landpaperRecord;
}
function get(string memory rfidnumber) view public returns(Landpaper memory){
return lp[rfidnumber];
}
}
because I have to read the rfid UID and I will translate the UID to string, so I need to use the string set my data. I use the bytes8 and I input string type, I need to change my string to bytes8, plz told me how to do.
You can write a function to convert string to bytes8
function stringToBytes8(string memory sourceStr) private pure returns(bytes8) {
bytes8 temp = 0x0;
assembly {
temp := mload(add(sourceStr, 32))
}
return temp;
}
And call it from set and get functions
function set(string memory rfidnumber, Landpaper memory _landpaperRecord) public Permission {
bytes8 rfidb8 = stringToByte8(rfidnumber);
lp[rfidb8]=_landpaperRecord;
}
function get(string memory rfidnumber) public view returns(Landpaper memory) {
bytes8 rfidb8 = stringToByte8(rfidnumber);
return lp[rfidb8];
}
Though I would suggest to avoid performing conversion process in contract as it would consume unnecessary gas. Instead perform the conversion on client side and pass bytes8 as parameter
function set(bytes8 rfidnumber, Landpaper memory _landpaperRecord) public Permission {
lp[rfidnumber]=_landpaperRecord;
}
function get(bytes8 rfidnumber) public view returns(Landpaper memory) {
return lp[rfidnumber];
}

How to return array of address in solidity?

I am creating a smart contract in solidity ^0.5.1 in which I get the following error:
data location must be a memory for the return parameter in the function, but none was given.
In the below function I am getting error.
function getCitizen()public returns(address[]){
return citizenArray;
}
The smart contract that I have tried so far.
pragma solidity ^0.5.1;
contract Citizen{
struct Citizens{
uint age;
string fName;
string lName;
}
mapping(address => Citizens) citizenMap;
address [] citizenArray;
function setCitizen(address _address,uint _age,string memory _fName,string memory _lName) public{
//creating the object of the structure in solidity
Citizens storage citizen=citizenMap[_address];
citizen.age=_age;
citizen.fName=_fName;
citizen.lName=_lName;
citizenArray.push(_address) -1;
}
function getCitizen(address _address) public pure returns(uint,string memory ,string memory ){
return(citizenMap[_address].age,citizenMap[_address].fName,citizenMap[_address].lName);
}
function getCitizenAddress()public returns(address[]){
return citizenArray;
}
}
How can I return the array of addresses?
It make sense, as you are returning the storage array of address you cannot return it as it is, because it will try to return the actual address of citizenArray in the contract storage. You can send the array by making it in memory. Like this.
function getCitizenAddress()public view returns( address [] memory){
return citizenArray;
}
Once you put it as memory, you will get the warning for this which will state that as you are not changing any state in the function, you should mark it view, I already did that in the above code.
Lastly, when you resolved this error, you will get another error in this function:
function getCitizen(address _address) public pure returns(uint,string memory ,string memory ){
return(citizenMap[_address].age,citizenMap[_address].fName,citizenMap[_address].lName);
}
This error is because you mark this function as pure. There is a little but very important difference between pure and view.
view means you cannot change the state of the contract in that function.
pure means you cannot change the state in the function and not even can read the state or storage variables.
In the above function of getCitizen you are actually doing read operations in your return statement. You can fix this by just putting view instead of pure. Like So:
function getCitizen(address _address) public view returns(uint,string memory ,string memory ){
return(citizenMap[_address].age,citizenMap[_address].fName,citizenMap[_address].lName);
}
I hope it will resolve all your issues. Thanks
// SPDX-License-Identifier: MIT
// Version
pragma solidity >=0.8.0 < 0.9.0;
contract EstructuraDeDatos {
struct Customer {
string nameCustomer;
string idCustomer;
string emailCustomer;
}
mapping(address => Customer) public myClientes;
address[] public listClientes;
function registrationApp(string memory _name, string memory _id, string memory _email) public {
Customer memory customer = Customer(_name, _id, _email);
myClientes[msg.sender] = customer;
listClientes.push(msg.sender);
}
function retornarArrat() public view returns (address[] memory) {
return listClientes;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Citizen {
struct Citizens {
uint age;
string fName;
string lName;
}
mapping(address => Citizens) citizenMap;
address [] citizenArray;
function setCitizen(address _address,uint _age,string memory _fName,string memory _lName) public {
// Citizens storage citizen=citizenMap[_address];
//creating the object of the structure in solidity
Citizens storage citizen;
citizen = citizenMap[_address];
citizen.age=_age;
citizen.fName=_fName;
citizen.lName=_lName;
citizenArray.push(_address);
}
function getCitizen(address _address) public view returns(uint,string memory ,string memory) {
return (citizenMap[_address].age,citizenMap[_address].fName,citizenMap[_address].lName);
}
// function getCitizenAddress()public returns(address[]) {
// return citizenArray;
// }
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Citizen{
struct Citizens{
uint age;
string fName;
string lName;
}
mapping(address => Citizens) citizenMap;
address [] citizenArray;
function setCitizen(address _address,uint _age,string memory _fName,string memory _lName) public{
// Citizens storage citizen=citizenMap[_address];
//creating the object of the structure in solidity
Citizens storage citizen;
citizen = citizenMap[_address];
citizen.age=_age;
citizen.fName=_fName;
citizen.lName=_lName;
citizenArray.push(_address);
}
function getCitizen(address _address) public view returns(uint,string memory ,string memory ){
return(citizenMap[_address].age,citizenMap[_address].fName,citizenMap[_address].lName);
}
function getCitizenAddress()public view returns(address[] memory){
return citizenArray;
}
}