探索 web3 时代:如何链接钱包,开启全新数字世界

本人确实懒散成性。发表文章后,便心生满足,鲜有再次动笔之意。然我心知肚明,尚有诸多知识值得分享,毕竟早年历经诸多挫折。查阅前辈所言,已详尽阐述,故未曾赘述。审视先前文稿,略显草率,本次我决意深入探讨,毕竟我也曾是新手,愿我能助同路人一臂之力。

懈怠的后果是错失众多学习和进阶良机。目睹他人不断前行,内心常感不安。认识到持续懈怠将注定落后于人,我今次决心摒弃惰性,将所学知识与大家共享,以期助力他人。

image.png

从零开始:判断钱包是否安装

需求遭遇时,我倍感困惑。流程包括判别钱包安装、连接钱包,查阅文档后得悉相关要点,操作看似简便,实则复杂。首要任务是掌握检测用户钱包安装的技巧,这可能涉及JavaScript等基本编程知识。若不具备相关技能,则需重新学习。

image.png

请完成钱包绑定。此操作涉及交互细节,故要求掌握基础区块链知识,包括但不限于理解ABI和合约地址。若知识不足,请预留学习时间。概而言之,尽管步骤繁琐,持之以恒自能掌握。

image.png

两个钱包的连接问题

image.png

需特别指出,尽管连接逻辑相似,但注入的对象各异,需另行定义方法。当两钱包并存时,系统将自动激活,因此需确保识别。两者的链接机制亦不同,需分别编写调用策略。虽看似复杂,实则,对具备基本编程概念者而言,此过程并不繁难。关键在于,针对不同钱包编写相应的连接程序。

若采用MetaMask钱包,须定制连接方法;同理,使用TrustWallet亦需如此。此过程虽复杂,持之以恒定可达成。

ABI和合约地址的重要性

备注:ABI是指您合约的抽象接口,亦即调用合约所需的地址。在BSC区块链浏览器中,可通过代币名称进行搜索,以定位所需代币的合约地址。例如,本例中搜索的是币安智能链的USDT代币,其中“55”即为USDT的合约地址。输入此地址可查得详细地址信息。点击合约代码链接,向下浏览可查看其ABI。


const isNetwork = 97. //BSC测试链ID
//小狐狸调用
 async initWeb3() {
      const web3 = new Web3(window.ethereum); //注入对象window.ethereum
      if (window.ethereum) {
        window.ethereum.enable();  //默认连接
        ethereum.on('accountsChanged', this.accountsChanged); //监听账户变化
        ethereum.on('networkChanged', this.networkChanged);//监听网络变化
        ethereum.on('close', this.disconnect);  //断开连接
      } else {
        alert('no wallet');
        return;
      }
      const Contract = new web3.eth.Contract(abi, address); 
      this.allMethods = Contract.methods;
      //轮询去获取地址
      const timer = setInterval(async () => {
        const address = await this.getAddress(web3);
        if (address) {
        //地址
          this.address = address;
          //网络
          this.network = ethereum.networkVersion;
          sessionStorage.setItem('address', this.address);
          
        //限制网络,当不在限制的网络时,强行切换(比如限制只能在BSC主链),不需要可以注释
          if (this.network != isNetwork) {
            this.switchNetwork();
            this.address = '';
          }
          clearInterval(timer);
        }
      }, 1000);
    }
    //获取地址
    async getAddress(web3) {
      const account = await web3.eth.getCoinbase();
      if (account) {
        return account;
      }
      return false;
    }
    //切换网络方法,
  switchNetwork() {
  //调用小狐狸api方法,传入你要切换的网络id
      try {
        window.ethereum.request({
          method: 'wallet_switchEthereumChain',
          params: [{ chainId: Web3.utils.toHex(isNetwork) }],
        });
      } catch (switchError) {
        if (switchError.code === 4902) {
          alert('add this chain id');
        }
      }
    }
    
    
    const isBscNet = 'bsc-testnet';
    //Binance Wallet调用
   async initBSCWeb3() {
      const web3 = new Web3(window.BinanceChain);//注入对象window.ethereum
      if (window.BinanceChain) {
        window.BinanceChain.enable();
        BinanceChain.on('accountsChanged', this.accountsChanged);//监听账户变化
        BinanceChain.on('chainChanged', this.BSCNetChanged);//监听网络变化
        BinanceChain.on('disconnect', this.disconnect);//断开连接
        // BinanceChain.on('close', this.disconnect);
      } else {
        alert('no wallet');
        return;
      }
      const Contract = new web3.eth.Contract(abi, address);
      this.allMethods = Contract.methods;
      this.network = window.BinanceChain.chainId;
      //网络不对时切换网络,不需要可以注释
      if (this.network != isBscNet && this.network !== '0x61') {
        this.switchBSCNet();
        this.address = '';
      }
      //获取地址,异步
      const account = await web3.eth.getAccounts();
      if (account) {
        this.address = account[0];
        sessionStorage.setItem('address', this.address);
      }
    }
    //Binance Wallet 切换网络
     async switchBSCNet() {
      try {
        await window.BinanceChain.switchNetwork(isBscNet);
      } catch (switchError) {
        if (switchError.code === 4902) {
          alert('add this chain id');
        }
      }
    }
    
    
    //walletConnect 链接方法, 有些坑,看上篇文章
     async walletConnect() {
      const provider = new WalletConnectProvider({
        infuraId: infuraId, //需要自己去申请,上篇文章有讲
        qrcode: true,
      });
      if (!provider.on) {
        return;
      }
      // Subscribe to accounts change
      provider.on('accountsChanged', this.accountsChanged);
      provider.on('disconnect', (code, reason) => {
        this.disconnect();
      });
      provider.on('close', () => {
        localStorage.removeItem('walletconnect');
      });
      await provider.enable();
      const web3 = new Web3(provider);
      const accounts = await web3.eth.getAccounts();
      this.address = accounts[0];
      const Contract = new web3.eth.Contract(abi, address);
      this.allMethods = Contract.methods;
      this.network = await web3.eth.net.getId();
    }

ABI与合约地址是实现钱包连接的核心要素。若不掌握相关信息,连接钱包将不可行。故,深入理解相关内容至关重要。例如,在BSC区块链浏览器中搜索目标代币,进而定位其合约地址和ABI信息。

代币方法的调用

image.png

自行发行代币时,您将获得后台提供的ABI和地址。具备所需参数后,即可通过调用方法,连接您的MetaMask或钱包。此方法涵盖了代币操作,例如余额查询与转账。以USDT为例,可调用相应方法查询余额;BSC作为主币,其操作亦适用web3.eth方法,其中同样包含余额查询与转账功能。

代币调用操作至关重要。不熟悉相关方法,将导致任务无法完成。例如,掌握USDT余额查询和BNB协议余额查询的技术是必要的。

开源项目的启示

image.png

大致上,我曾探究过其他人的开源作品。若您采用React框架,不妨参考@web3-react,此项目可能对您的问题有更佳解决方案。然而,我倾向于Vue。开源资源是学习佳选。若您面临难题,不妨审视他人项目,了解其解决之道。例如,使用React的用户可以研究@web3-react以观察他们如何处理钱包连接问题。

即便非React使用者,亦确信投入时间后,可从开源项目中汲取丰富知识。例如,可掌握运用React解决钱包连接问题的技巧,亦或学习Vue的相关解决方案。

作者头像
比特派钱包官网创始人

bitpie比特派钱包官方

上一篇:上海黄金交易所手机 app 是什么?详细介绍与使用指南
下一篇:区块链防被割韭菜指南:必备知识与策略

相关推荐