solidity array mapping with array inside struct - solidity

Unable to execture createSchema function. It gives following error
revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Testing {
struct Schema {
mapping(string => string) entity;
}
struct SchemaMapping {
// mapping(string => string) key;
// mapping(string => string) value;
string[] key;
string[] value;
}
mapping(uint256 => Schema) schemas;
mapping(uint256 => SchemaMapping[]) schemaMappings;
function createSchema(uint256 id, string memory key, string memory value) public {
SchemaMapping[] storage schemamapping = schemaMappings[id];
schemamapping[id].key.push(key);
schemamapping[id].value.push(value);
schemas[id].entity[key] = value;
}
function getSchemaElemet(uint256 id) public view returns (SchemaMapping[] memory) {
return schemaMappings[id];
}
}

I adjusted your smart contract. The issue in your original contract is that you were trying to add values into schemaMapping without create SchemaMapping at specific index.
Smart contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Testing {
struct Schema {
mapping(string => string) entity;
}
struct SchemaMapping {
string[] key;
string[] value;
}
mapping(uint256 => Schema) schemas;
mapping(uint256 => SchemaMapping[]) schemaMappings;
function createSchema(uint256 id, string memory key, string memory value) public {
SchemaMapping[] storage schemamapping = schemaMappings[id];
// NOTE: I created an empty space in storage for create object and after bind it with values.
SchemaMapping storage singleSchemaItem = schemamapping.push();
// NOTE: I put values inside keys
singleSchemaItem.key.push(key);
singleSchemaItem.value.push(value);
schemas[id].entity[key] = value;
}
function getSchemaElemet(uint256 id) public view returns (SchemaMapping[] memory) {
return schemaMappings[id];
}
}

Related

Get array from struct

so I have this contract
pragma solidity >=0.7.0 <0.9.0;
struct Universe{
uint256 year;
uint64[3] space;
}
contract myContract {
mapping(address => Universe) public myUni;
function setSomething(uint256 _year, uint64[3] memory _space) public {
Universe memory testUni = Universe({
year: _year,
space: _space
});
myUni[msg.sender] = testUni;
}
}
And I am currently trying to test if the array is being passed correctly with truffle:
pragma solidity >=0.7.0 <0.9.0;
const myContract = artifacts.require("./1_Storage.sol");
contract('myContract', (accounts) => {
it('checks if setSomething works', async () => {
const myContractInstance = await myContract.new();
const spaceData = [6000, 6000, 6000];
await myContractInstance.setSomething(2543,spaceData,{from: accounts[1]});
const myPassedData = (await myContractInstance.myUni(accounts[1]));
console.log(myPassedData);
console.log(spaceData);
});
});
The issue is, that I am not able to get spaceData passed into the function and I don't know why. The console.log(myPassedData); shows me only the year and when I try something like console.log(myPassedData.spaceData); it says undefined.
Thanks #sms for the link. As stated in the solidity Documentation:
If you have a public state variable of array type, then you can only
retrieve single elements of the array via the generated getter
function. This mechanism exists to avoid high gas costs when returning
an entire array.
So I had to write a Getter-Function inside of the Contract to be able to access the array:
function getUniverseArray(address _address) public view returns (uint64[3] memory) {
return myUni[_address].space;
}

How can i push element on array defined on struct in Solidity?

I'm starting to approach with Solidity (current version 0.8.0) smart contracts, but I can't understand why the compiler print me an error during the push.
The problem is the following: I'm trying to push an element on array in struct but compile failed with error: Copying of type struct memory[] memory to storage not yet supported.
Here my example:
contract TestNFT is ERC721, Ownable {
struct Child {
string name;
}
struct Father {
string name;
Child[] childs;
}
mapping(uint256 => Child) private _childs;
uint256 nextChild = 0;
mapping(uint256 => Father) private _fathers;
uint256 nextFather = 0;
constructor(string memory name, string memory symbol)
ERC721(name, symbol)
{}
function mint(
string memory name
) public onlyOwner {
_safeMint(msg.sender, nextCharacter);
_childs[nextChild] = Child(name);
nextChild++;
}
function mintFather(string memory name) public onlyOwner {
_safeMint(msg.sender, nextClan);
_fathers[nextFather] = Father(name, new Child[](0));
nextFather++;
}
function insertChildToFather(uint256 fatherId, uint256 childId)
public
onlyOwner
{
Child memory child = _childs[childId];
_fathers[fatherId].childs.push(child);
}
}
How can I fix the insertChildToFather function?

Solidity: return array in a public method

I am trying to create a public funcion that returns an array,
this is the error
Return argument type mapping(uint256 => struct ItemList.Item storage
ref) is not implicitly convertible to expected type (type of first
return variable) uint256[] memory.
pragma solidity ^0.5.0;
contract ItemList {
uint public itemCount = 0;
mapping(uint256 => Item) public items;
event ItemCreated (
uint id,
string proofdocument
);
struct Item {
uint id;
string proofdocument;
}
constructor() public {
}
function createItem(string memory _proofdocument) public {
itemCount++;
items[itemCount] = Item(itemCount, _proofdocument);
emit ItemCreated(itemCount, _proofdocument);
}
function getItems() public pure returns(uint256[] memory ) {
return items; <----------ERROR
}
}
Thanks Andrea
You can get every item in the loop via web3.js library
const array = []
for (let i = 0; i < itemCount; itemCount += 1) {
array.push(contract.getItem(i)) // where getItem do items[I] in solidity
}
Or you can use pragma experimental version:
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract ItemList {
uint public itemCount = 0;
struct Item {
uint id;
string proofdocument;
}
Item[] items;
constructor() public {}
function createItem(string memory _proofdocument) public {
itemCount++;
items.push(Item(itemCount, _proofdocument));
}
function getItems() external view returns(Item[] memory) {
return items;
}
}

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

Array returns "Undeclared identifier. Did you mean "Candidate" or "candidate"?"

when trying to set up an array of structs i get an error that says "Undeclared identifier. Did you mean "Candidate" or "candidate"?"
Ive tried to create an empty array by writing
uint[] memory candidate;
and
bytes[] memory candidate
above the function in which i'm getting errors to instantiate it. However, this doesn't work either and gives errors. It does not compile.
pragma solidity 0.5.0;
contract Election {
string public candidate;
struct Candidate {
uint id;
string name;
uint voteCount;
}
mapping(uint => Candidate) candidate;
uint public candidatesCount;
function createCandidate(string storage name ) private {
candidatesCount ++;
candidates[candidatesCount] = Candidate(candidatesCount, name, 0);
}
function addCandidates () public {
createCandidate("Candidate1");
createCandidate("Candidate2");
}
}
change
mapping(uint => Candidate) candidate;
to
mapping(uint => Candidate) candidates;
and
function createCandidate(string storage name ) private
to
function createCandidate(string memory name ) private