当前位置:   article > 正文

【区块链】走进web3的世界-合约交互中的异常/边界处理_web3合约交互

web3合约交互

在以太坊智能合约中,异常处理是一个非常重要的问题,因为任何一个函数调用都有可能导致异常。常见的异常包括函数调用失败、无效参数、内部错误等。

        在 Solidity 中,可以使用 require、assert 和 revert 等关键字来处理异常。这些关键字可以用于检查输入参数、状态变量和函数调用的返回值,并在发生异常时抛出异常。

        今天我们主要从前端的角度来进行异常处理,这样可以保证我们交互的正常进行。

1、工程目录划分,更好的管理我们web3脚本

    

让我们的代码更加清晰明了

  • web3中与智能合约交互使用的是ABI,他是我们和智能合约交互的通道,可以将ABI通过命名统一管理,方便后续维护;
  • 在与智能合约交互的过程中,需要调用ABI的接口,以及通过web3.js/ethers.js等web3的一些库进行钱包连接,获取地址等操作,可以将其放入web3的文件夹中进行统一管理。

ABI(Application Binary Interface)是一种接口规范,用于描述不同模块之间的通信方式和数据格式。在以太坊智能合约中,ABI 用于描述智能合约的接口,包括合约地址、函数名、函数参数和返回值等。

2、前端在合约交互中的异常处理

在web3的脚本中,我们需要通过try{} catch {}将异常抛出,常见的异常情况包含:

  • 钱包连接异常;
  • 区块链交互付费过程中拒绝支付;
  • rpc不对,交互异常;
  • 调用合约报错(不存在方法、传参不对等);
  • 还有很多很多......

3、以下是一些常见的异常处理方式

3.1、try{} catch {}捕获抛出异常

  1. /**
  2. * 域名是否可注册
  3. * @param domainName domainName without .bnb
  4. * @returns boolean, if no error
  5. */
  6. static async isDomainAvailable(domainName: String): Promise<any> {
  7. try {
  8. const isAvailable = await BnbDomainUtils.registrarControllerContractReadOnly.available(domainName)
  9. return isAvailable
  10. } catch (error) {
  11. console.log(error);
  12. return false
  13. }
  14. }

3.2、检查交易是否成功

        在向智能合约发送交易时,需要检查交易是否成功。可以使用 Web3.js 提供的 send 方法,该方法会返回一个 Promise 对象,可以在 then 方法中获取交易的哈希值,并在 catch 方法中处理异常。

  1. myContract.methods.myFunction().send({ from: myAddress })
  2. .then((receipt) => {
  3. // 处理交易成功的情况
  4. })
  5. .catch((error) => {
  6. // 处理交易失败的情况
  7. });

3.3、捕获智能合约函数调用异常

        在调用智能合约的函数时,可能会出现异常,例如传入的参数无效、状态不满足要求等。可以使用 Web3.js 提供的 call 方法,该方法会返回一个 Promise 对象,可以在 then 方法中获取函数的返回值,并在 catch 方法中处理异常。

  1. myContract.methods.myFunction(myArg).call()
  2. .then((result) => {
  3. // 处理函数调用成功的情况
  4. })
  5. .catch((error) => {
  6. // 处理函数调用失败的情况
  7. });

3.4、处理 MetaMask 异常

        在使用 MetaMask 与智能合约交互时,可能会出现用户未授权、交易被拒绝等异常。可以使用 MetaMask 提供的 ethereum 对象,该对象包含了与钱包交互的 API。

  1. if (window.ethereum) {
  2. try {
  3. await window.ethereum.enable();
  4. // 处理用户已授权的情况
  5. } catch (error) {
  6. // 处理用户未授权的情况
  7. }
  8. } else {
  9. // 处理用户未安装 MetaMask 的情况
  10. }

3.5、使用事件监听器

        在智能合约中,可以使用事件来通知前端某些状态的变化。可以在智能合约中定义事件,然后在前端使用 Web3.js 监听事件的触发。

        通过使用事件监听器,前端可以实时获取智能合约的状态变化,从而更加及时地处理异常情况。

  1. // Solidity 中定义事件
  2. event Transfer(address indexed from, address indexed to, uint256 value);
  3. // 前端中监听事件
  4. myContract.events.Transfer()
  5. .on('data', (event) => {
  6. // 处理事件触发的情况
  7. })
  8. .on('error', (error) => {
  9. // 处理事件监听失败的情况
  10. });

3.6、限制交易的 gas 量

        在向智能合约发送交易时,可以指定交易的 gas 量。如果 gas 不足,交易会失败,并回滚交易。可以在前端限制交易的 gas 量,从而确保交易能够成功执行。

        通过限制交易的 gas 量,前端可以避免交易失败的情况。

  1. const gasLimit = 250000;
  2. myContract.methods.myFunction().send({ from: myAddress, gas: gasLimit })
  3. .then((receipt) => {
  4. // 处理交易成功的情况
  5. })
  6. .catch((error) => {
  7. // 处理交易失败的情况
  8. });

3.7、处理网络异常

        在与智能合约交互时,可能会遇到网络异常,例如网络延迟、断开等。可以在前端使用 Web3.js 提供的 setProvider 方法设置网络 provider,从而确保交互的稳定性。

        通过设置网络 provider,前端可以避免网络异常的情况。

  1. // 1、使用web3
  2. const provider = new Web3.providers.HttpProvider('https://ropsten.infura.io/v3/YOUR-PROJECT-ID');
  3. const web3 = new Web3(provider);
  4. // 2、使用ethers
  5. const provider = new ethers.providers.JsonRpcProvider(process.env.READ_ONLY_RPC)
  6. new ethers.Contract(
  7. contractAddress,
  8. Abi,
  9. provider
  10. )

总之,在与智能合约交互时,需要仔细处理异常,以保证交易的正确性和可靠性。可以使用 Web3.js 和 MetaMask 提供的 API 来处理异常。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/419584
推荐阅读
相关标签
  

闽ICP备14008679号