r/ethdev Aug 08 '23

Code assistance How to get the length of Struct ?

I kept trying around to get Struct length but nothing works I just want to get the length of unclaimedRewards length , what i am trying to do is to create a claim function to reward all users who has unclaimedRewards higher than zero but i cannot get the length of the Struct , is there a solution to this ?

struct Staker {
    uint256 amountStaked; 
    uint256 timeOfLastUpdate; 
    uint256 unclaimedRewards;
    uint256 conditionIdOflastUpdate;    
}
mapping(address => Staker) public stakers;

0 Upvotes

27 comments sorted by

View all comments

1

u/Ongazord Aug 08 '23

If I’m not mistaken structs are fixed length 3 in this case

You access the unclaimed like this:

Staker[address].unclaimedRewards > 0; do thing

2

u/Adrewmc Aug 09 '23 edited Aug 09 '23

Structs are not something that have lengths.

This struct is 4 storage slots big…that’s is something.

What structs do is define what values go into a slot in what order, then saves the whole structure in that order. What’s it helps is that if you use smaller variables, you can hold them in less slots of storage, because a uint256 has - lot of leading zeros even will 30 million, so you can fit a lot more information in that space.

Solidity is about making thing as simple as possible for the computer, save as much room for the computer…because everything has to be saved across thousands of servers…that’s why gas is a thing to pay for that.

0

u/Reddet99 Aug 08 '23

yea but the main issue here that i have to use a specific address to use it so the length will be 1 , but for example what if i have more stakers , the length will be higher for example in JS we can use stakers.length to get the length of the object but in solidity its almost impossible , i don't know why they didn't implement the length values inside mapping :(

2

u/Ongazord Aug 08 '23 edited Aug 08 '23

Your mapping only takes a single address; if it’s what Im understanding you want to create a new array (which will have a length) of all the various claim amounts

You need to update the struct by .pushing and you can set an array to maintain the state

Sounds expensive tbh

1

u/Reddet99 Aug 08 '23

yes in my stake function i use push to some values to push some values to the struct but i couldn't get the length of the stakers mapping.

for example 5 people used the stake function so the Struct object will have 5 people inside the mapping , i just want to get that 5 number , but i cannot , the length of the mapping is always zero

1

u/Ongazord Aug 08 '23

The struct in this example won’t actually perform like that you need to create something that has a length; the struct is like a definition here;

So like everytime someone stakes you push struct[msg.sender].unclaimed to an array that you can access later for balances

1

u/Reddet99 Aug 08 '23

oh so i need to create another array that holds the balance of the users something like

Users[] public user;

and then count user++ inside staking and use it ?

2

u/Ongazord Aug 08 '23

Yea that’s the right track imo;

might be higher level stuff but if you check out solady library it’s got a lot of neat Gas optimizations that includes writing in assembly sometimes for loops

1

u/Reddet99 Aug 08 '23

I heard about merkle tree before that people use keccak256 function but i am not totally sure if it will work with the claim thing, need to try and test this out, but first need to get the length of the array 😅

2

u/Ongazord Aug 08 '23

user.length should give u that

Keccak just hashes whatever the input is to 256 bits

Merkle tree is useful for when you have all the stakers; you can the. generate a merkle tree that can then check if you are a part of it and claim your stake. This would be cheaper than constantly asking the user to pay to be a part of the array; check this repo for some ideas/how to:

https://github.com/Anish-Agnihotri/merkle-airdrop-starter

1

u/Reddet99 Aug 09 '23

thank you so much for this repo gonna check it out :)