What type of input should I give to this function? - solidity

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

Related

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

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

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

I want to find the substring (index 0 to 13) of bytes32 data and convert it into uint256 data

I am stuck in solidity code. I want substring of below data and convert it to uint256 data
bytes32 hmacSha256 = 0xf83bf40815929b2448b230d51fa2eaa5b8ccffd87691db7e62bf817b2cbb56ad;
I want first 13 chars of above hmacSha256 data i.e. 'f83bf40815929' and its uint256 ie. 4366982094870825.
I tried a number of things but to failure.
Code and tried code is below:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
/**
* #title Storage
* #dev Store & retrieve value in a variable
*/
contract TestContract {
function getsubstring1() public pure returns (string memory, uint256, string memory) {
bytes32 hmacSha256 = 0xf83bf40815929b2448b230d51fa2eaa5b8ccffd87691db7e62bf817b2cbb56ad;
bytes memory tempH = bytes(abi.encodePacked(hmacSha256));
uint256 uintHash = uint256(hmacSha256);
//I want below values as result.
// _hs is first 13 chars of hmacSha256.
//neither i could derive the _hs and nor _h from _hs.
string memory _hs = '0xf83bf40815929';
uint256 _h = 0xf83bf40815929;
//What I tried
//bytes13 _hs1 = bytes13(hmacSha256);
//but its returning 0xf83bf40815929b2448b230d51f which is double the length of expected value 0xf83bf40815929
//string memory _hs1 = substring(string(abi.encodePacked(hmacSha256)), 0, 13);
//above code is throwing error:Failed to decode output: null: invalid codepoint at offset 0; bad codepoint prefix
// bytes memory _hs2 = tempH[0:13] ;
//above giving error that its for bytes calldata dynamic array
//uint256 _h1 = uint256(bytes(abi.encodePacked(_hs)));
return (_hs, _h, _hs1);
}
function substring(string memory str, uint startIndex, uint endIndex) public pure returns (string memory) {
bytes memory strBytes = bytes(str);
bytes memory result = new bytes(endIndex-startIndex);
for(uint i = startIndex; i < endIndex; i++) {
result[i-startIndex] = strBytes[i];
}
return string(result);
}
}
You need to perform few typecasts and bitwise operatations, see the code comments.
Code:
pragma solidity ^0.8;
contract TestContract {
function getsubstring() external pure returns (bytes7, uint256) {
bytes32 hmacSha256 = 0xf83bf40815929b2448b230d51fa2eaa5b8ccffd87691db7e62bf817b2cbb56ad;
bytes7 first7Bytes = bytes7(hmacSha256); // get the first 7 bytes (14 hex characters): 0xf83bf40815929b
bytes7 thirteenHexCharacters = first7Bytes >> 4; // move 4 bytes (1 hex character) to the right: 0x0f83bf40815929
bytes32 castBytes = bytes32(thirteenHexCharacters); // cast the bytes7 to bytes32 so that we can cast it to integer later
bytes32 castBytesMoved = castBytes >> 200; // move 200 bytes (50 hex characters) to the right: 0x000000000000000000000000000000000000000000000000000f83bf40815929
uint256 integerValue = uint256(castBytesMoved); // cast the bytes32 to uint256
return (thirteenHexCharacters, integerValue);
}
}
Returned values:
bytes7: 0x0f83bf40815929
uint256: 4366982094870825

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.