У меня есть функция получения в моем смарт-контракте, которая возвращает одно из строковых значений в статически определенном массиве строк. При входе в функцию она выполняет проверку границ входящего индекса, используя require()
. Если проверка границ не удалась, что произойдет в моем приложении Node.JS, которое использовало Web3.js для выполнения вызова? Будет ли выброшена ошибка Javascript? Получу ли я NULL обратно?
Если у кого-то есть хорошая статья или веб-ресурс, который показывает правильный способ обработки ошибок из вызова Web3.JS, которые привели к запуску операции assert или require на стороне смарт-контракта, поделитесь ею.
Вот мой код смарт-контракта:
pragma solidity ^0.4.23;
import "github.com/OpenZeppelin/zeppelin-solidity/contracts/ownership/Ownable.sol";
contract VideoDummyData is Ownable{
// Constructor, MUST be public.
constructor() public {
// Unused.
}
// Array of sample video IDs.
string[3] m_aryVideoIds =
["ZUSPD9zOyJs", "4nqJiBRNQuw", "PLcxE4UkJt0"];
// Return one of the sample video IDs.
function getVideoIdAt (uint ndx) public view returns(string)
{
// Bounds check on the desired index.
require(ndx < m_aryVideoIds.length);
return m_aryVideoIds[ndx];
}
}
Поскольку вы вызываете view
функцию, первый обратный вызов вызовет ошибку более или менее немедленно.
В настоящее время возможно вернуть ошибки с помощью
require(expression, "error msg");
Проблема заключается в доступе к этому сообщению выше по стеку в Web3 и Node.
Тем временем вы можете использовать try
и .catch()
в обещанном коде, таком как абстракция трюфельного контракта.
Вы не будете знать точную причину, но сможете сделать вывод, учитывая требования контракта.
Надеюсь, поможет.
После того, как вы вызываете/отправляете методы, возвращаются по какой-либо причине, вы получаете приведенный ниже ответ в своем коде express/nodejs.
{
"data": {
"0x926192b712005c4eab709b7f7e1718435b6f2117580360b73e7601a439feffcd": {
"error": "revert",
"program_counter": 383,
"return": "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000165468697320496420616c72656164792065786973747300000000000000000000",
"reason": "This Id already exists"
},
"stack": "RuntimeError: VM Exception while processing transaction: revert This Id already exists\n at Function.RuntimeError.fromResults (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:13)\n at BlockchainDouble.processBlock (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\blockchain_double.js:627:24)\n at processTicksAndRejections (internal/process/task_queues.js:93:5)",
"name": "RuntimeError"
}
}
Теперь нам нужно показать пользователю соответствующее сообщение, чтобы пользователь мог понять, для чего мы можем использовать приведенный ниже код. Чтобы получить причину из возвращенного ответа. используйте приведенный ниже код в коде nodeJS/expressjs....
try {
await myContract.methods.foo().send();
} catch (e) {
const data = e.data;
const txHash = Object.keys(data)[0];
const reason = data[txHash].reason;
console.log(reason);
}
Итерация 122442
Роберт Ошлер
Итерация 122442
Роб Хитченс
call
оview
функции, поэтому транзакция для майнинга не требуется.