Учитывая, что ABI публично находится в блокчейне, почему никто не может вызвать TransferFrom() и украсть токены?

Я просто пытаюсь понять, как это на самом деле работает и как защищены активы, хранящиеся в блокчейне. Поскольку определения ABI общедоступны, адрес контракта также доступен, может ли кто-нибудь взаимодействовать со смарт-контрактом? Если да, то как вы его ограничиваете?

Например, если есть токен ERC20, который реализует transferFrom, то не может ли кто-нибудь назвать этот _toадрес настройки функции своим собственным?

Ответы (1)

Согласно стандарту ERC20, функция transferFrom может быть вызвана кем угодно. Но для того, чтобы добиться успеха, владелец токена должен позволить транжире потратить свой токен.

Пример онлайн неверен, но вот один:

  function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        uint256 value = _value * 10 ** uint256(decimals);
        require(value <= allowance[_from][msg.sender]);
        allowance[_from][msg.sender] -= value;
        _transfer(_from, _to, _value);
        return true;
    }

См. строку require, если она ложна, будет вызвана функция возврата, и состояние EVM вернется к тому, что было до этой транзакции.


Примечание. Как сказал Смаркс в комментариях, следующая строка:

uint256 value = _value * 10 ** uint256(decimals);

Подходит для моего кода, не используйте его в своем, если вы не знаете, что делаете (даже если он работает нормально)

Разве пособие не предназначено для чего-то другого? Может быть, я неправильно понимаю, но, насколько я знаю, пособие предназначено для одобрения того, чтобы кто-то тратил деньги от его имени. Например, бухгалтерия может разрешить каждому сотруднику тратить 100 токенов в месяц, даже если у самих сотрудников нет токенов.
Не имея отношения к вопросу здесь, я просто хотел указать, что умножение здесь 10 ** decimalsнестандартно и, вероятно, плохая идея. Смысл decimalsв том, чтобы позволить людям переводить такие суммы, как «0,01 токена». Если вы умножаете все свои аргументы на 10 ** decimals, вы убираете возможность сделать это. (С тем же успехом вы могли только что установить decimalsзначение 0.)
@eth.block "... насколько я знаю, пособие предназначено для одобрения того, чтобы кто-то тратил деньги от его имени." Точно. Для того, чтобы вы успешно звонили transferFrom(foo, ...), fooвы должны сначала разрешить вам потратить свой эфир. Вот что делает этот код.
Поэтому transferFromтребует предварительного одобрения. Отлично. Что насчет transfer? Что, если я передам _toкак свой собственный адрес и укажу _fromадрес, который, как я знаю, имеет достаточно токенов? Это вообще возможно?
Нет, потому что переменная from на самом деле является message.sender.
@smarx На самом деле это прекрасно, если вы знаете остальную часть моего кода. ;)
@ Andromelus Я не могу об этом говорить; Я просто хотел указать другим читателям, что это не то, что они должны копировать в свои собственные контракты.
@smarx Вы правы, я отредактирую свой ответ для этого