How can i push element on array defined on struct in Solidity? - 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?

Related

I generated a flattened of my contract using Remix but it gives error: Definition of base has to precede definition of derived contract

I thibk the error is occurring because the contract "ERC721Burnable" is trying to inherit from two other contracts "Context" and "ERC721", but "Context" is not defined in the code you provided. So, the definition of a base contract must precede the definition of a derived contract.
How can I make sure that the definition of the "Context" contract is included before the definition of the "ERC721Burnable" contract. Additionally, How can I make sure that "Context" is defined in the same file or imported from a different file.
Bellow is the code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/common/ERC2981.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "#openzeppelin/contracts/utils/math/SafeMath.sol";
contract AliveNatureNFT is ERC721, ERC721Enumerable, ERC721URIStorage, ERC2981, Pausable, ERC721Burnable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
// percentage split for commission and liquidity pool
uint96 public commissionPercentage;
uint96 public liquidityPercentage;
// address of the commission recipient
address public commissionRecipient;
// address of the liquidity pool
address public liquidityPoolRecipient;
// Owner address
address public ownerNFT;
//Base URI
string private url;
struct ProjectData {
string name;
uint256 projectTokenId;
string methodology;
string region;
string emissionType;
string uri;
address creator;
}
struct RetireData {
uint256 retireTokenId;
address beneficiary;
string retirementMessage;
uint256 timeStamp;
uint256 amount;
}
mapping (uint256 => ProjectData) private _projectData;
mapping (uint256 => RetireData) private _retireData;
modifier onlyOwner(address _sender) {
require(_sender == ownerNFT, "Only the owner can call this function");
_;
}
modifier onlyAdmin (address _sender) {
require(_sender == commissionRecipient, "Only the heir can call this function");
_;
}
constructor(
uint96 _liquidityPercentage, address _liquidityPoolRecipient,
string memory _MyToken, string memory _Symbol, string memory _url, address _ownerNFT
) ERC721(_MyToken, _Symbol) {
commissionPercentage = 100;
liquidityPercentage = _liquidityPercentage;
commissionRecipient = 0xE3506A38C80D8bA1ef219ADF55E31E18FB88EbF4;
liquidityPoolRecipient = _liquidityPoolRecipient;
ownerNFT = _ownerNFT;
_setDefaultRoyalty(commissionRecipient, commissionPercentage);
url = _url;
}
function _baseURI() internal view override returns (string memory) {
return url;
}
function pause(address _sender) external onlyAdmin(_sender) {
_pause();
}
function unpause(address _sender) external onlyAdmin(_sender) {
_unpause();
}
function safeMint(address _to, string memory _uri, string memory _name,
string memory _methodology, string memory _region, string memory _emissionType, address _sender) public whenNotPaused onlyOwner(_sender) {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(_to, tokenId);
_setTokenURI(tokenId, _uri);
// Create a new ProjectData struct and store it in the contract's storage
_projectData[tokenId] = ProjectData({
projectTokenId : tokenId,
uri : _uri,
name : _name,
methodology : _methodology,
region : _region,
emissionType : _emissionType,
creator : _sender
});
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
internal
whenNotPaused
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId, batchSize);
if (from != address(0)) {
address owner = ownerOf(tokenId);
require(owner == msg.sender, "Only the owner of NFT can transfer or burn it");
}
}
function _burn(uint256 tokenId) internal whenNotPaused override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function burnToken(uint256 tokenId, string memory _retirementMessage, uint256 _amount, address _sender) public whenNotPaused onlyOwner(_sender) {
address owner = ownerOf(tokenId);
require(owner == msg.sender, "Only the owner of NFT can burn it");
_burn(tokenId);
// Create a new ProjectData struct and store it in the contract's storage
_retireData[tokenId] = RetireData({
retireTokenId : tokenId,
beneficiary : msg.sender,
retirementMessage : _retirementMessage,
timeStamp : block.timestamp,
amount : _amount
});
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
// The following functions are overrides required by Solidity.
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC2981, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
I'm trying to group everything in a flattened contract to have the complete ABI

TypeError: Member "push" is not available in struct SmartRegistryData.CDMD memory[] memory outside of storage

**// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract SmartRegistryData{
struct TP {
uint id;
}
struct OP {
uint id;
}
struct BP{
uint id;
}
//ContractDescriptionMetaData
struct CDMD {
uint ID;
address providerAdress;
TP TechnicalPerspective;
OP OperationalPerspective;
BP BusnissPerspective;
}
mapping(uint => CDMD) public CDMDS;
mapping(address => CDMD) public CDMDSA;
struct PROVIDER{
uint8 id;
string name;
address publicAddress;
string entrepriseName;
string entreprisedomain;
string entreprisedescription;
}
// Store provider
mapping( address => PROVIDER) public _listproviders;
function retreiveCDMDbyProvider(address _publicAddress, address publicAddress)public{
CDMD [] memory CDMDarray = new CDMD[](100);
// CDMD balance[] = new CDMD[](100);
CDMD storage cdmd = CDMDSA[_publicAddress];
if(CDMDSA[_publicAddress].providerAdress== publicAddress){
CDMD memory cdma = CDMDSA[_publicAddress];
//balance.push(cdma);
}
}
}**
when I'm typing --- truffle compile I get this error
how Can I push a struct into a dynamic array ??
there is another solution to retrieve a set of struct according to a specified attribute, such as address.

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