• Почему разные EVM жалуются на то, что не могут оценить газ?

    @Tyavochka
    Solidity Developer
    Такой ответ должен означать ошибку при выполнении, причем любую. Например, метамаск чаще всего пишет в такой ситуации, что недостаточно средств для оплаты газа. Для понимания нужно увидеть код или же прописать во всех require текст ошибки (если конечно падает на нем). Еще как вариант контракт слишком большой, но тогда его не получится принципиально задеплоить
    Ответ написан
  • КОД-РЕВЬЮ СмартКонтракта Solidity. Контракт переводит деньги на 2 кошелька. Всё правильно написал?

    @Tyavochka
    Solidity Developer
    Вот эти две сточки
    uint _50 = address(this).balance/100*50; //50% of balance of contract
    uint _25 = address(this).balance/100*25; //25% of balance of contract

    будут выполняться во время работы конструктора. Т.е. если заранее на адрес контракта (до его создания) не отослать ничего - то address(this).balance будет равен 0. Эти переменные надо вычислять каждый раз, когда нужно переводить eth.
    Также рекомендую сначала делать все умножение, а потом все деление: меньше проблем с округлением.
    Чтобы контракт срабатывал автоматически, метод перевода средств должен быть в receive() external payable{}. И лучше не использовать balance, т.к. в него будут попадать прошлые остатки. В этом плане подойдет msg.value (если говорить об автоматическом переводе).
    address payable addr1 и вторую переменную стоит сделать константой, если не планируется обновлять эти адреса в будущем. А если говорим о промышленном коде с тестированием, то неплохой вариант сделать их immutable и задавать в конструкторе.
    Помимо этого необходим метод для вывода оставшихся 25% иначе застрянут на адресе контракта на совсем.
    И наверное добавлю еще одну мелочь: transfer не самый идеальный способ переводить средства (если говорим о реальном контракте), из-за ограничения по газу на такой методу, рекомендую глянуть Address.sol (кажется метод sendValue) из библиотеки openzeppelin.
    Ответ написан
    3 комментария
  • TypeError: "send" and "transfer" are only available for objects of type "address payable", not "address".?

    @Tyavochka
    Solidity Developer
    Начиная с 0.8.x версии, для перевода средств (send и transfer) необходимо чтобы тип был `address payable`, при этом `msg.sender` стал просто `address` (ссылка на документацию). Т.е. нужно привести к типу `address payable` и код должен заработать:
    payable(msg.sender).transfer(amount);
    Ответ написан
    Комментировать
  • Как сделать несколько криптовалютных переводов за одну транзакцию?

    @Tyavochka
    Solidity Developer
    Для сети Ethereum потребуется воспользоваться smart-контрактом, например, https://multisender.app/.
    В идеале конечно создать и развернуть свой, чтобы не потребовалось никому доверять.
    Но в любом случае комиссия за перевод на несколько адресов будет больше, чем на один адрес, но меньше, чем если делать все по отдельности.
    Ответ написан
    Комментировать
  • Можно ли проитерироваться по мапе в Solidity?

    @Tyavochka
    Solidity Developer
    В текущем варианте контракта нет способа узнать всех хранящих средства на кошельке, т.к. из mapping никак не вытащить индексы (их там нет), поэтому надо дополнительно хранить массив всех владельцев.
    В цикле метода kill - перебрать всех владельцев и отправить средства. Помимо этого нужна защита от reentrancy - вытащить значение balances, далее обнулить значение в mapping и только после этого вызвать transfer.

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

    @Tyavochka
    Solidity Developer
    Ethereum контракт может создавать другие контракты, но даже при этом он не будет владеть приватным ключом от нового адреса. Если нужен приватный ключ как для обычного кошелька - то не получится. Но в принципе можно создавать контракты-кошельки с настроенным доступом и распоряжаться средствами на таком кошельке
    Ответ написан
    Комментировать
  • Как в Solidity перевести эфир с адреса на адрес?

    @Tyavochka
    Solidity Developer
    Начиная с какой-то версии (не помню точно какой), transfer работает только с address payable.
    Попробуйте такой вариант:
    function pay(address payable _user, uint _value) payable public {
            _user.transfer(_value);
     }

    Еще хочу добавить, что transfer не самый предпочтительный способ перевода средств из-за ограничения в газе (23 000). Хотя, если уверены, что принимающая сторона не имеет fallback функции или она очень простая, то пойдет.
    Ответ написан
  • Для чего нужен интерфейс смарт-контракта?

    @Tyavochka
    Solidity Developer
    Интерфейс необходим для вызова любой функции контракта из клиента или другого контракта.
    В вызов входит сигнатура метода - первые 4 байта хеша от имени функции и ее параметров (без возвращаемого значения).
    В большинстве случаев у вас есть весь контракт и нет необходимости выделять отдельно интерфейс.
    Интерфейс может помочь унифицировать код, а также пригодится там, где точно неизвестна реализация контракта - например нужна работа с любыми токенами, которые поддерживают ERC20.
    Еще интерфейс будет полезен для всяких грязных хаков с fallback функциями и delegatecall (proxy) - когда вызов идет через промежуточный контракт.
    Ответ написан
    1 комментарий