Возврат сообщения об ошибке из смарт-контракта

Я пытаюсь вернуть сообщения об ошибках из solidity. У меня есть этот контракт:

pragma solidity ^0.4.23;
contract Simple {
    function arithmetics(uint a, uint b){           
                     require(a % 2 == 0, "Even value required.");             
                    b = b * 3; 
            }
}

Когда я тестирую в ремиксе, он возвращает мне следующее сообщение об ошибке:

транзакция с Simple.arithmetics с ошибкой: ошибка виртуальной машины: возврат. revert Транзакция была возвращена в исходное состояние. Причина, предусмотренная договором: «Требуется равное значение.». Отладьте транзакцию, чтобы получить больше информации.

Однако, когда я попытался вызвать его из своего dApp с помощью web3.js, я не получаю сообщения об ошибке, только это:

У сделки кончился газ.

Ответы (2)

Вы можете найти сообщение об ошибке, отслеживающее транзакцию. Например, используя geth, и я предполагаю, что ваш узел работает по адресу http://127.0.0.1:8545:

1- Откройте консоль

geth attach http://127.0.0.1:8545

2- Отследить транзакцию

debug.traceTransaction(<your TX hash here>)

Вы должны получить трассировку транзакции. Если ваш узел geth не был запущен с debugвключенным, вы можете просто выполнить HTTP-запрос, например:

curl -X POST --data '{"jsonrpc":"2.0","method":"debug_traceTransaction","params":["<your TX hash here>"],"id":1}' http://127.0.0.1

Теперь, когда у вас есть трассировка, вы можете украсить JSON, чтобы лучше видеть его. В самом низу вы найдете последнюю инструкцию и состояние EVM (и другие вещи). Последняя инструкция должна быть REVERTопкодом. Затем перейдите в MEMORYраздел, и вы можете преобразовать его в ascii, чтобы найти сообщение об ошибке. Например, в bash эта команда преобразует шестнадцатеричный формат в ascii:

echo <your HEX here> | xxd -r -p

Для web3 эта работа находится в стадии разработки и пока невозможна. Вы можете следить за этой темой: https://github.com/ethereum/web3.js/issues/1707.