Member "Push" not found... I tried to run my code the same way I did earlier with the Strings but this time with uints and it didn't work. New to Sol - solidity

I'm new to solidty so any new keyword is appreciated. I like the language so far, the syntax is close to Java and C#. I'm still a college student and the lack of info about solidity is a killer. I hope someone can help :/
pragma solidity ^0.8.7;
contract MyTestContarct{
Person[] public people;
uint256 public peopleCount;
struct Person {
string _firstName;
string _lastName;
}
function addPerson(string memory _firstName, string memory _lastName) public{
people.push(Person(_firstName, _lastName));
peopleCount +=1;
}
uint[] IntArrayTest;
uint256 public elementsCounter;
struct Numbers{
uint _number;
}
function addElements(uint _number) public{
IntArrayTest.push(Numbers(_number));
elementsCounter +=1;
} //It worked with string, why not with uint?
}

IntArrayTest is of type uint[] (array of unsigned integers), so you can only push uint items to this array.
However Numbers(_number) is not an uint - its type is Numbers.
You can create a Numbers variable in memory, and then pass its _number member (which has the uint type) to the IntArrayTest array.
uint[] IntArrayTest;
function addElements(uint _number) public{
Numbers memory numbers = Numbers(_number);
IntArrayTest.push(numbers._number);
elementsCounter +=1;
}
Or if you want to pass the Numbers type to an array, you'll need to delcare an array of this type.
struct Numbers{
uint _number;
}
Numbers[] NumbersArrayTest;
function addElements(uint _number) public{
NumbersArrayTest.push(Numbers(_number));
elementsCounter +=1;
}

Related

What type of input should I give to this function?

struct khatian{
uint64 khatianiId;
bytes32 plotHash;
uint16 percentOwn;
bytes32 buyFrom;
bytes32[] sellTo;
uint16[] sellPercentage;
uint[] ownerArray;
uint16[] perOwnerPercentage;
bool isExist;
}
function addKhatianFromOld(uint64 _khatianiId, bytes32 _plotHash, uint16 _percentOwn, bytes32 _buyFrom, uint[] _user, uint16[] _percentage) public{
require(msg.sender == contarctOwner, "Sender is not authorized");
require(plotMapping[_plotHash].isExist == true, "Plot doesn't exist");
bytes32 khatianHash = keccak256(abi.encodePacked(_khatianiId, _plotHash));
require(khatianMapping[khatianHash].isExist != true, "Khatian already exists");
require(khatianMapping[_buyFrom].isExist, "previous Khatian doesn't exist");
require(khatianMapping[_buyFrom].percentOwn >= _percentOwn, "Not enough land to sell");
for(uint j = 0; j< _user.length; j++){
require(userMapping[_user[j]].isExist == true, "User's NID doesn't exist");
}
This are my code snippet. I getting this error
''Error: expected array value (argument=null, value="1", code=INVALID_ARGUMENT, version=abi/5.5.0)''
What type of data should I give input here? specially in bytes32_buyFrom, uint[] _user, uint16[] _percentage?
I tried to give address and other string as input
Add memory / calldata keyword after declaring uint[] just like this uint[] memory _user and uint16[] memory _percentage let me know if it works
First of all, you must change the signature method adding the where memorized the data passed in input. In detail, you can consider that adding in memory the arrays.
Insomuch, change your method signature method in this way:
function addKhatianFromOld(uint64 _khatianiId, bytes32 _plotHash, uint16 _percentOwn, bytes32 _buyFrom, uint[] memory _user, uint16[] memory _percentage) public{
// your logic
}
To reply about your question:
In bytes32 parameter, in this function, you must give a format bytes32 from a string. You can see my answer to this thread for convert string to bytes32;
In uint[] array parameter, you must filled it with integer number starting from a maximum range value: 115792089237316195423570985008687907853269984665640564039457584007913129639935
(2**256);
In uint16[] array parameter, you must filled it with integer number starting from a maximum range value:
65536
(2**16)
In following attach an example of request with vainput

There is Array.push function in solidity how it is return length of the array?

pragma solidity >=0.5.0 <0.6.0;
contract ZombieFactory {
event NewZombie(uint zombieId, string name, uint dna);
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
struct Zombie {
string name;
uint dna;
}
Zombie[] public zombies;
function _createZombie(string memory _name, uint _dna) private {
uint id = zombies.push(Zombie(_name, _dna)) - 1; //**here how it is return length of array**
emit NewZombie(id, _name, _dna);
}
function _generateRandomDna(string memory _str) private view returns (uint) {
uint rand = uint(keccak256(abi.encodePacked(_str)));
return rand % dnaModulus;
}
function createRandomZombie(string memory _name) public {
uint randDna = _generateRandomDna(_name);
_createZombie(_name, randDna);
}
}
I want to know how it is working i tired to searched in google but i cant get exact results try to explain how it returning length of array and basically it just add the element ...
before solidity v0.6.
Arrays have a member "push" define as :
Dynamic storage arrays and bytes (not string) have a member function called push that you can use to append an element at the end of the array. The element will be zero-initialised. The function returns the new length.
It's changed after v0.6.
Reference https://docs.soliditylang.org/en/v0.8.12/060-breaking-changes.html

How to pass array of struct of type voter in solidity?

I want to pass an array of struct to a function. The array is of type voter. So below is my code. But I am getting error as
UnimplementedFeatureError: Copying of type struct Election.voter memory[] memory to storage not yet supported.
struct voter{
string name;
address constituency;
uint age;
bool isVoted;
}
struct constituency{
string name;
voter[] candidates;
}
constituency[] public constituencyRegister;
function addConstituency(string memory _name,voter[] memory _candidates)
public
{
constituency memory c = constituency(_name, _candidates);
constituencyRegister.push(c);
}
In the following line you are trying to assign a memory array of struct to a storage array of struct, since c contains _candidates:
constituencyRegister.push(c);
Instead, you could push to a storage var, get its reference and only then assigning the name and pushing each _candidates element to the array:
pragma solidity ^0.8.0;
contract MuC {
struct voter{
string name;
address constituency;
uint age;
bool isVoted;
}
struct constituency{
string name;
voter[] candidates;
}
constituency[] public constituencyRegister;
function addConstituency(string memory _name,voter[] memory _candidates)
public
{
constituency storage c = constituencyRegister.push();
c.name = _name;
for(uint i = 0; i < _candidates.length; i++) {
c.candidates.push(_candidates[i]);
}
}
}
This is compiling for me with 0.8.9.

Solidity variable definition: (bool sent, )

In Solidity, this sentence:
(bool sent, ) = msg.sender.call{value: _amount}("");
What is the sense of that "," after sent variable?
Any link to offcial documentation?
Many thanks.
It means you do not need to define both the variables to access the return values. You can access either of these variables as follows
(,uint256 alpha) = testFunction(); //access first returned variable
(uint256 beta,) = testFunction(); //access second returned variable
function testFunction() public pure returns(uint256,uint256){
return (1,2);
}
Solidity functions can return multiple variables of different types.
If you only want to keep one variable, then you can declare a variable and then use commas:
function multiValueFunction() public returns (bool, string memory, uint[] memory, uint {
//do something
return (true, "New String", [1,2], 21)
}
function differentFunction() public {
uint numberToKeep;
(,,,numberToKeep) = multiValueFunction();
}
Expected: numberToKeep = 21
Each comma represents the place of a returned variable (that is not kept)
It just means that the function will return two variables and you just want to store the first one.
This kind of syntax (variable type) is called Tuple In Python and other languages.
In Solidity,
they're not considered a proper type but can be used as a shorthand.
See the Official Docs: Destructuring Assignments and Returning Multiple Values
example:
uint256 amount = 10 ether;
require(
amount <= address(this).balance,
"Trying to withdraw more money than the contract has."
);
(bool success, ) = (msg.sender).call{value: amount}("");
require(success, "Failed to withdraw money from contract.");
above code, Roughly, Can be translated with basic if else statements like following:
uint256 amount = 10 ether;
bool success;
if(amount <= address(this).balance) {
success = true;
} else {
success = false;
return "Trying to withdraw more money than the contract has.";
}
if(success) {
(msg.sender).call{value: amount}("")
} else {
return "Failed to withdraw money from contract.";
}
here's another contract as example,
use this link https://remix.ethereum.org/#version=soljson-v0.6.9+commit.3e3065ac.js&optimize=false&gist=83bfbd85ef79387f760154999eb4f192&runs=200&evmVersion=null to play around in remix online
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.8.0;
contract myContract {
uint index;
function myFunction() public {
( , , uint256 standardDepositAmount, , ) = returnTuple();
require(standardDepositAmount == 3);
// do something...
}
function returnTuple() public pure returns (uint, uint, uint, uint, uint) {
return (1, 2, 3, 4, 5);
}
}

return multiple array in solidity

I am trying to return multiple array from a function.
My code is looks like this:
struct Document{
bytes32 _documentNumber;
bytes32 _documentStatus;
uint _documentScore;
}
mapping(bytes32=>Document) public mapDocuments; // Holds Docno as key
mapping(address=>bytes32[]) public mapUserDocNos; // Holds User address as key with valuehaving array of all document nos
mapping(bytes32=>DocumentDetails) public mapDocumentDetails; // Holds Docno as key
//And i am storing data in map like this:
function addDocument(address _user, bytes32 _docNo,
bytes32 _documentStatus,uint _documentScore,
uint _createdDateStr) returns (bool status){
DocumentDebuggingLog(block.timestamp, "Step 1",_user);
Document memory document;
DocumentDebuggingLog(block.timestamp, "Step 2",_user);
document._customerAccountAddress= _user;
document._documentNumber= _docNo;
document._documentScore=_documentScore;
document._documentStatus=_documentStatus;
mapDocuments[_docNo]=document;
mapUserDocNos[_user].push(_docNo);
return true;
}
//trying to retrieve :
function getDocumentListByUser(address _user) returns (bytes32[] _docNumber,
bytes32[] _docStatus,uint[] _docScore){
bytes32[] _documentNumber;
bytes32[] _documentStatus;
uint[] _documentScore;
DocumentDebuggingLog(block.timestamp, "step 1 in getDocumentListByUser",_user);
for(uint i=0;i<mapUserDocNos[_user].length;i++){
//bytes32 dockey= mapUserDocNos[_user][i];
//DocumentDebuggingLog(block.timestamp, dockey,_user);
_documentNumber.push( mapDocuments[mapUserDocNos[_user][i]]._documentNumber);
_documentStatus.push( mapDocuments[mapUserDocNos[_user][i]]._documentStatus);
_documentScore.push( mapDocuments[mapUserDocNos[_user][i]]._documentScore);
}
return (_documentNumber,_documentStatus,_documentScore);
}
But i am not able to get any data from above function.Where i am doing wrong? is there any other way to return multiple array from a function in solidity?
Try to change below in function getDocumentListByUser
FROM:
bytes32[] _documentNumber;
bytes32[] _documentStatus;
uint[] _documentScore;
TO:
uint256 arrLength = mapUserDocNos[_user].length
bytes32[] memory _documentNumber = new bytes32[](arrLength);
bytes32[] memory _documentStatus = new bytes32[](arrLength);
uint[] memory _documentScore = new uint[](arrLength);
Try below:
function getDocumentListByUser(address _user) returns (bytes32[] _docNumber, bytes32[] _docStatus,uint[] _docScore) {
uint256 arrLength = mapUserDocNos[_user].length
bytes32[] memory _documentNumber = new bytes32[](arrLength);
bytes32[] memory _documentStatus = new bytes32[](arrLength);
uint[] memory _documentScore = new uint[](arrLength);
DocumentDebuggingLog(block.timestamp, "step 1 in getDocumentListByUser",_user);
for(uint i=0;i<mapUserDocNos[_user].length;i++){
//bytes32 dockey= mapUserDocNos[_user][i];
//DocumentDebuggingLog(block.timestamp, dockey,_user);
_documentNumber.push( mapDocuments[mapUserDocNos[_user][i]]._documentNumber);
_documentStatus.push( mapDocuments[mapUserDocNos[_user][i]]._documentStatus);
_documentScore.push( mapDocuments[mapUserDocNos[_user][i]]._documentScore);
}
return (_documentNumber,_documentStatus,_documentScore);
}
Due to the limitations of Ethereum Virtual Machine, you can currently return only a fixed sized array. Please look at the answer with code examples from the official solidity faq.