1

I am trying to figure out how to have the balance of all players reset to (amount) when a certain condition happens. This is the function that will update a specific player balance. How do I make it reset the balance of all players at once?

mapping(address => uint256) investments;
mapping(address => uint256) joined;
mapping(address => uint256) withdrawals;
mapping(address => uint256) withdrawns;

// add deposit to curent deposit, and update joined timer
   investments[_customerAddress] = investments[_customerAddress].add(_incomingTronix);
   joined[_customerAddress] = block.timestamp;

   emit Invest(_customerAddress, _incomingTronix);
}
  • Comments are not for extended discussion; this conversation has been moved to chat. – eth Mar 26 at 1:55
0

For resetting the balance stored in mapping, you have to record the mapping entries, because you cannot use .length property with mappings. So one thing you can do to maintain array of addresses along with the mapping. Like so:

mapping(address => uint256) investments;
address [] investers;

Whenever you add something in the investments mapping, you can also push that address to investors array. Then you can do reset logic something like that:

function resetBalance(uint256 value)public {
    for (uint i=0; i< investers.length ; i++){
        investments[investers[i]] = value;
    }
}

Which can reset the balance with value. For sure you can use any logic you want here. Also this same approach can be use with all other players.

Since mapping are not behaving like arrays so we cannot directly get the value of from mapping, we must need to track keys of mapping.

Hope it helps...

  • Thanks! Going to test it now. – Zetal Mar 26 at 2:05
  • Not sure how to push addresses to the array though. – Zetal Mar 26 at 2:13
  • when first time you set the key value pair in mapping like this: investments[msg.sender] = value;. Right after this you can do investors.push(msg.sender). – Abdullah Aziz Mar 26 at 2:17
0

If I understand correctly, you want to reset all of the values in a mapping.

You'll find there is no efficient way to zero out a mapping. As Abdullah observes, you need a list of users with balances so the contract has a way to know what to do.

Without knowing how many users there might be I can't be sure it's unreasonable to iterate over the list. It's a concern: https://blog.b9lab.com/getting-loopy-with-solidity-1d51794622ad

You can do it with a mapping of balances and an unordered set of users who's balances are valid. Users not in that set have a zero balance regardless of garbage that might exist in the mapping. It's possible to nuke the set which can logically nuke the balances.

If you want it to work at any scale as I assume is the case, then you need to be able to confirm membership (user has a balance?) and nuke the set without iterating over the list in either case.

Here's the basic method: https://medium.com/robhitchens/solidity-crud-part-1-824ffa69509a

You can accomplish the "nuke" part by deleting the keyList array. Note that this leaves the old balances in the mapping, so always check validity and then decide if you want to return the stored value or a zero.

Have a look at this library: https://github.com/rob-Hitchens/UnorderedKeySet, explained here: https://medium.com/robhitchens/solidity-crud-epilogue-e563e794fde You can certainly apply the same logic in-line if you prefer.

pragma solidity 0.5.1;

import "./HitchensUnorderedKeySet.sol";

contract NukeBalances {

    using HitchensUnorderedKeySetLib for HitchensUnorderedKeySetLib.Set;
    HitchensUnorderedKeySetLib.Set validBalances;

    mapping(address => uint) balances;

    function addToBalance(address user, uint amount) public {
        bytes32 userKey = addressToBytes32(user);
        if(!validBalances.exists(userKey)) {
            balances[user] = amount;
            validBalances.insert(userKey);
        } else {
            balances[user] += amount;
        }
    }

    function userBalance(address user) public view returns(uint) {
        if(!validBalances.exists(addressToBytes32(user))) return 0;
        return balances[user];
    }

    function addressToBytes32(address a) public pure returns(bytes32) {
        return bytes32(uint(uint160(a)));
    }

    function nukeBalances() public {
        delete validBalances.keyList;
    }

}

Nothing but some quick superficial testing done here. No warranty. Test accordingly. ;-)

Hope it helps.

  • I edited the title to make it more findable by others with similar challenges. Hope that's okay with you. – Rob Hitchens - B9lab Mar 26 at 2:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.