В смарт-контрактах Ethereum обработка исключений является очень важной проблемой, потому что любой вызов функции может вызвать исключение. Общие исключения включают сбои вызовов функций, недопустимые параметры, внутренние ошибки и многое другое.
В Solidity для обработки исключений можно использовать такие ключевые слова, как require, assert и revert. Эти ключевые слова можно использовать для проверки входных параметров, переменных состояния и возвращаемых значений вызовов функций, а также для создания исключений при возникновении исключений.
Сегодня мы в основном обрабатываем исключения с точки зрения внешнего интерфейса, чтобы обеспечить нормальный ход нашего взаимодействия.
1. Разделите каталог проекта, чтобы лучше управлять нашими сценариями web3.
Сделайте наш код более понятным и лаконичным
- ABI используется для взаимодействия со смарт-контрактом в web3.Это канал для нашего взаимодействия со смарт-контрактом.ABI можно единообразно управлять с помощью именования, чтобы облегчить последующее обслуживание;
- В процессе взаимодействия со смарт-контрактом необходимо вызвать интерфейс ABI, а также использовать некоторые библиотеки web3, такие как web3.js/ethers.js, для подключения кошелька и получения адреса и т. д., которые можно положить в папка web3 для управления объединением.
ABI (Application Binary Interface) — это спецификация интерфейса, используемая для описания методов связи и форматов данных между различными модулями. В смарт-контракте Ethereum ABI используется для описания интерфейса смарт-контракта, включая адрес контракта, имя функции, параметры функции и возвращаемое значение и т. д.
2. Обработка исключений внешнего интерфейса в контрактном взаимодействии
В сценариях web3 нам нужно генерировать исключения через try{} catch {}. Общие исключения включают:
- Соединение с кошельком ненормальное;
- Отказ от оплаты в процессе интерактивного платежа в блокчейне ;
- RPC неправильный, и взаимодействие ненормальное;
- Сообщается об ошибке при вызове контракта (метод не существует, параметры не равны);
- И многое, многое другое...
3. Ниже приведены некоторые распространенные методы обработки исключений.
3.1, попытка{} поймать {} захват выдает исключение
/**
* 域名是否可注册
* @param domainName domainName without .bnb
* @returns boolean, if no error
*/
static async isDomainAvailable(domainName: String): Promise<any> {
try {
const isAvailable = await BnbDomainUtils.registrarControllerContractReadOnly.available(domainName)
return isAvailable
} catch (error) {
console.log(error);
return false
}
}
3.2. Проверьте, прошла ли транзакция успешно
При отправке транзакции на смарт-контракт необходимо проверить, прошла ли транзакция успешно. Вы можете использовать метод send, предоставленный Web3.js, который вернет объект Promise, вы можете получить хеш-значение транзакции в методе then и обработать исключение в методе catch.
myContract.methods.myFunction().send({ from: myAddress })
.then((receipt) => {
// 处理交易成功的情况
})
.catch((error) => {
// 处理交易失败的情况
});
3.3 Исключение вызова функции смарт-контракта
При вызове функций смарт-контрактов могут возникать исключения, такие как переданные недопустимые параметры, статус не соответствующий требованиям и т.д. Вы можете использовать метод вызова, предоставленный Web3.js, который возвращает объект Promise, вы можете получить возвращаемое значение функции в методе then и обработать исключение в методе catch.
myContract.methods.myFunction(myArg).call()
.then((result) => {
// 处理函数调用成功的情况
})
.catch((error) => {
// 处理函数调用失败的情况
});
3.4 Обработка исключений MetaMask
При использовании MetaMask для взаимодействия со смарт-контрактами могут возникать такие исключения, как несанкционированная авторизация пользователя и отклонение транзакции. Вы можете использовать объект ethereum, предоставленный MetaMask, который содержит API для взаимодействия с кошельком.
if (window.ethereum) {
try {
await window.ethereum.enable();
// 处理用户已授权的情况
} catch (error) {
// 处理用户未授权的情况
}
} else {
// 处理用户未安装 MetaMask 的情况
}
3.5 Использование прослушивателей событий
В смарт-контрактах события могут использоваться для уведомления внешнего интерфейса об определенных изменениях состояния. События можно определить в смарт-контракте, а затем использовать Web3.js во внешнем интерфейсе для отслеживания запуска события.
Используя прослушиватель событий, внешний интерфейс может получать изменения состояния смарт-контракта в режиме реального времени, чтобы более своевременно справляться с нештатными ситуациями.
// Solidity 中定义事件
event Transfer(address indexed from, address indexed to, uint256 value);
// 前端中监听事件
myContract.events.Transfer()
.on('data', (event) => {
// 处理事件触发的情况
})
.on('error', (error) => {
// 处理事件监听失败的情况
});
3.6. Ограничьте количество газа для транзакций
При отправке транзакции на смарт-контракт можно указать количество газа для транзакции. Если газа недостаточно, транзакция завершится ошибкой, и транзакция будет отменена. Количество газа транзакции может быть ограничено на внешнем интерфейсе, чтобы гарантировать успешное выполнение транзакции.
Ограничивая количество газа в транзакции, внешний интерфейс может избежать сбоя транзакции.
const gasLimit = 250000;
myContract.methods.myFunction().send({ from: myAddress, gas: gasLimit })
.then((receipt) => {
// 处理交易成功的情况
})
.catch((error) => {
// 处理交易失败的情况
});
3.7. Обработка сетевых исключений
При взаимодействии со смарт-контрактами вы можете столкнуться с сетевыми аномалиями, такими как сетевые задержки, отключения и т. д. Вы можете использовать метод setProvider, предоставляемый Web3.js, для установки сетевого провайдера на внешнем интерфейсе, чтобы обеспечить стабильность взаимодействия.
Установив сетевого провайдера, внешний интерфейс может избежать сетевых аномалий.
// 1、使用web3
const provider = new Web3.providers.HttpProvider('https://ropsten.infura.io/v3/YOUR-PROJECT-ID');
const web3 = new Web3(provider);
// 2、使用ethers
const provider = new ethers.providers.JsonRpcProvider(process.env.READ_ONLY_RPC)
new ethers.Contract(
contractAddress,
Abi,
provider
)
В заключение, при взаимодействии со смарт-контрактами необходимо тщательно обрабатывать исключения, чтобы обеспечить правильность и надежность транзакций. Вы можете использовать API, предоставляемый Web3.js и MetaMask, для обработки исключений.