Ошибка Invalid Sender при отправке криптовалюты через Web3 PHP
При разработке платёжного модуля на PHP с библиотекой Web3 часто возникает ошибка invalid sender. Это значит, что сеть не может верифицировать отправителя транзакции. В большинстве случаев проблема не в приватном ключе, а в неправильном формировании подписи или параметров транзакции. Ниже мы пошагово разберём типичные причины и способы их устранения.
Почему возникает invalid sender?
Ошибка invalid sender в Ethereum и совместимых сетях (Polygon, BSC) появляется, когда:
- Неверно рассчитан nonce (счётчик транзакций адреса);
- Некорректно подписан raw-транзакция - не совпадает chain ID или формат подписи;
- Используется неправильный приватный ключ или формат ключа (без префикса 0x);
- Ошибка в расчёте gas limit или gas price (слишком низкое значение).
Поскольку на Node.js та же логика работает, ищем баг именно в PHP-коде.
Шаг 1: Проверьте nonce
Nonce должен быть точным количеством исходящих транзакций с кошелька. В вашем коде nonce получается через getTransactionCount с параметром pending. Это корректно, но убедитесь, что callback возвращает строку, а не объект BigNumber. Используйте toString() - как в примере. Если nonce на единицу больше или меньше - транзакция будет отклонена.
Шаг 2: Chain ID - частая ошибка в PHP
В Ethereum-транзакциях после EIP-155 обязательно указывается chain ID. В вашем коде chain ID не передаётся в конструктор Transaction. Для Polygon Mumbai (chain ID 80001) нужно явно указать четвёртый параметр:
$transaction = new \kornrunner\Ethereum\Transaction(
dechex($nonce),
dechex($gasPrice),
dechex($gasLimit),
env('CONTRACT_ADDRESS'),
dechex('0'),
$data,
80001 // chain ID
);Без chain ID подпись считается невалидной - сеть видит invalid sender.
Шаг 3: Формат приватного ключа
Убедитесь, что WALLET_PRIVATE_KEY в .env не содержит префикса 0x. Библиотека kornrunner/ethereum-tx ожидает чистую hex-строку (64 символа). Если ключ с префиксом - удалите его или обрежьте через substr.
Шаг 4: Gas limit для токенов ERC-20
Вызов estimateGas для метода transfer токена может вернуть значение, которого недостаточно для выполнения транзакции на стороне сети. Добавьте запас хотя бы 10-20% к полученному gas limit:
$gasLimit = bcadd($res->toString(), '20000'); // добавить 20000 газаСлишком низкий gas limit приводит к падению транзакции с разными ошибками, включая invalid sender.
Шаг 5: Проверьте адрес назначения и контракта
Убедитесь, что $to и CONTRACT_ADDRESS передаются в нижнем регистре (checksum-адреса могут не поддерживаться библиотекой). Приведите их к lowercase через strtolower.
Итог: что исправить в коде
- Добавить chain ID (80001 для Polygon Mumbai) в конструктор Transaction;
- Убрать префикс 0x из приватного ключа;
- Добавить запас gas limit (+20000);
- Привести адреса к нижнему регистру;
- Проверить, что nonce получен корректно (проверьте лог перед отправкой).
После этих изменений транзакция должна уйти без ошибки invalid sender. Если проблема остаётся - проверьте версии библиотек: web3p/web3.php и kornrunner/ethereum-tx должны быть обновлены до последних.