0

Dapp 在用户执行特定活动(例如接受 BNB 发送到 ICO)后,将 Bep20 令牌从远程钱包(我的钱包)发送给用户,它在安装了 metamask 的桌面上运行良好。执行此操作的代码是:


    var amountTosend = amount;
     var privateKey = 'PRIVATE_KEY';
  
    var accountFrom = web3provider.eth.accounts.privateKeyToAccount(privateKey).address;
     var contractCall = contractInstance.methods.transfer(addressTo, "0x"+amountTosend.toString(16));
     var icoAccount = web3provider.eth.accounts.privateKeyToAccount(privateKey);
         web3provider.eth.accounts.wallet.add(icoAccount);
contractCall.send({ from: accountFrom, gas: 2000000 }).then(function(hashdata) {
                             console.log(hashdata);

                            var rawTransaction = {
                                    
                                     "from": accountFrom,
                                     "nonce": nonce,
                                     "gasPrice": 20000000000,
                                   
                                     "gas": gas,
                                     "to": SmartContractAddress,
                                  
                                     "value": "0x" + amountTosend.toString(16),
                                    
                                     "data": hashdata.events.Transfer.raw.data,
                                      
                                     "chainId": chainid
                                 };

                                
                                 var privKey = new ethereumjs.Buffer.Buffer(privateKey, 'hex');
                              

                                 let tx = new ethereumjs.Tx(rawTransaction);
                                 tx.sign(privKey)
                                 let serializedTx = tx.serialize();

                                 console.log('serializedTx:', serializedTx);

                                 web3provider.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'), function(err, receipt) {
                                     if (!err) {
                                         console.log('success token sent to user: ' + receipt);
                                         alert('You have received your Tokens in your Wallet');
                                     } else {
                                         console.log('error: ' + err);
                                         alert("An error Occured: " + err);
                                     }
                                 });

})

在使用wallet connect作为提供者与web3modal连接的trust和metamask mobile等移动钱包上,我成功与钱包交互,提示用户发送BNB但

contractCall.send({ from: accountFrom, gas: 2000000 })

用于更改智能合约的状态以在将远程钱包添加到本地后发送用户 Bep20 令牌失败并出现未知帐户错误,使用:

web3provider.eth.accounts.wallet.add(icoAccount);

注意:如果我尝试跳过

contractCall.send({ from: accountFrom, gas: 2000000 })

并使用 contractCall.encodeABI() 作为数据参数,它工作正常,但实际上没有令牌发送给用户,我猜是因为智能联系人状态需要更改/更改

myContract.methods.myMethod([param1[, param2[, ...]]]).send

请我需要任何有用的帮助/提示来使这项工作在移动钱包上工作,我已经在这个错误上待了几天了,谢谢

4

1 回答 1

0

我终于修复了这个错误,我想为以后的访问者全面回答。简短的答案将首先实现解决方案,然后是长的综合答案,以帮助您更好地理解并学习修复错误的技术细节

注意: 我在移动浏览器上为我的 DAPP 和桌面上的 Metamask 使用 walletconnect 和 web3modal,我使用 vanilla javascript 来实现 web3

简短回答: 我必须将 givenProvider 设置为在 web3 实例上初始化的 currentProvider,这是我的 RPC URL 提供程序,对我来说,我的 RPC URL 提供程序是:https : //getblock.io/,它在 walletconnect/web3modal 提供程序选项中传递参数

我正在连接到 BSC,所以我的 RPC URL 是:https ://bsc.getblock.io/mainnet/?api_key=API_KEY

您可以使用您选择的其他 RPC URL 提供程序

所以 givenProvider 是这样设置的:

web3.givenProvider = web3.currentProvider;
web3.eth.givenProvider = web3.currentProvider;
web3.eth.accounts.givenProvider = web3.currentProvider;

在此处阅读有关设置提供商的 walletconnect 文档:https ://docs.walletconnect.com/quick-start/dapps/web3-provider

将 web3.givenProvider 设置为 web3.currentProvider 解决了问题,因为 web3.givenProvider 为空

长答案:

您需要了解 currentProvider 和 givenProvider 是什么,因为该错误会围绕 web3 提供程序解决。据我所知,在撰写此答案时,givenProvider 是在启用以太坊的浏览器中注入的提供程序,而 currentProvider 是您在 web3 初始化时传入的提供程序。

错误是:未知帐户

这个问题不会出现在安装了 metamask 的桌面浏览器上,因为注入了 givenProvider,当然除了提供程序节点上不存在的远程帐户

您必须使用以下方法将帐户添加到提供程序节点:

  var account=  web3provider.eth.accounts.privateKeyToAccount(PRIVATE_KEY);
var addAccount = web3provider.eth.accounts.wallet.add(account);

这解决了桌面浏览器上的错误,而无需进行太多配置或设置,这是因为掩码使您的浏览器启用以太坊并注入 givenProvider

但是对于移动浏览器,您将面临这个问题,因为移动浏览器不是支持以太坊的环境。在通过 walletconenct 初始化 web3 后,您必须将 givenProvider 设置为有效的提供程序。

注意: givenProvider 通过网络与区块链对话,在移动浏览器上为空。Console.log(web3) 将显示 web3 实例的值

将所有代码放在一起应该如下所示:


import WalletConnectProvider from "@walletconnect/web3-provider";
import Web3 from "web3";

//  Create WalletConnect Provider
const provider = new WalletConnectProvider({
  rpc: {
    1: "https://mainnet.mycustomnode.com",
    3: "https://ropsten.mycustomnode.com",
    100: "https://dai.poa.network",
    // ...
  },
});


await provider.enable();



//  Create Web3 instance
const web3 = new Web3(provider);

//FIX STARTS HERE

//set givenProvider to currentProvider
 web3.givenProvider = web3.currentProvider;
 web3.eth.givenProvider = web3.currentProvider;
 web3.eth.accounts.givenProvider = web3.currentProvider;

//add wallet to provider node
var account= web3.eth.accounts.privateKeyToAccount(PRIVATE_KEY);
var addAccount = web3.eth.accounts.wallet.add(account);
var accountFrom = account.address;

var gas = contractCall.estimateGas({ from: accountFrom });
 gas.then(function(gasTouse) {
contractCall.send({ 
from: accountFrom, gas: gasTouse }).then(function(hashdata){
   console.log(hashdata);

});
});

注意:确保您估算了 gas 并将其包括在内,因为没有它您可能会遇到一些与 gas 相关的错误。

快乐编码:)

于 2022-02-13T16:29:11.603 回答