Delgus
@Delgus

Можно ли проитерироваться по мапе в Solidity?

Есть например пример смарт-контракта-кошелька. можно положить на счет эфир, можно снять. я хочу чтобы можно было уничтожить контракт но при этом разослать всем кто хранил эфир обратно
pragma solidity >=0.4.22 <0.7.0;
import "../Owner.sol";
contract Wallet is Owner {
    mapping (address => uint) private balances;

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }
    
    function withdraw(uint money) public payable {
        require(balances[msg.sender] >= money);
        balances[msg.sender] -= money;
        msg.sender.transfer(money);
    }
    
    function balance() public view returns (uint) {
        return balances[msg.sender];
    }
    
    function kill() public isOwner { //onlyOwner is custom modifier
       // не знаю что тут делать
        for (uint i = 0; i < balances.length; i++) {
            
        }
        selfdestruct(msg.sender);  // `owner` is the owners address
    }
}
  • Вопрос задан
  • 174 просмотра
Решения вопроса 1
@Tyavochka
Solidity Developer
В текущем варианте контракта нет способа узнать всех хранящих средства на кошельке, т.к. из mapping никак не вытащить индексы (их там нет), поэтому надо дополнительно хранить массив всех владельцев.
В цикле метода kill - перебрать всех владельцев и отправить средства. Помимо этого нужна защита от reentrancy - вытащить значение balances, далее обнулить значение в mapping и только после этого вызвать transfer.

Еще один совет: когда есть цикл по неопределенному количеству элементов, то можно встрять на слишком большом потреблении газа для одной транзакции. В таком случае выход - разделить kill() на два метода. Один метод будет возвращать заданному числу владельцев средства, второй метод собственно вызывать selfdesctruct при выводе всех средств.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы