【问题标题】:Error: Returned error: The method eth_sendTransaction does not exist错误:返回错误:方法 eth_sendTransaction 不存在
【发布时间】:2021-09-15 01:46:40
【问题描述】:

我正在尝试使用此代码将 erc20token 从合约地址转移到 eth 地址:

                var _from = "from Address";
                var contAddress = "contract address";
                var _to = "to address";

                var _Amount = '50';
                var txnObject = {
                    "from":_from,
                    "to": _to,
                    "value": web3.utils.toWei(_Amount,'ether'),
                    // "gas": 21000,         (optional)
                    // "gasPrice": 4500000,  (optional)
                    // "data": 'For testing' (optional)
                    // "nonce": 10           (optional)
                }
            
                web3.eth.sendTransaction(txnObject, function(error, result){
                    if(error){
                        console.log( "Transaction error" ,error);
                    }
                    else{
                        var txn_hash = result; //Get transaction hash
                        //$('#Tx').text(txn_hash);
                        alert(txn_hash);
                    }
                });

但我收到此错误:

Transaction error Error: Returned error: The method eth_sendTransaction does not exist/is not available

我已经搜索了很多并尝试了此代码,但它没有工作。可能是什么原因?这段代码是错误的还是别的什么?

注意:我使用的是 infura ropsten 网络节点。

【问题讨论】:

    标签: ethereum web3 web3js


    【解决方案1】:

    除了错误信息,与您的问题相关的其他问题很少。


    让我们从错误消息开始。

    eth_sendTransaction 方法不存在/不可用

    eth_sendTransaction() 用于当您希望您的节点为您签署交易时(使用 ulocked 帐户)。但是您连接到的节点不支持此方法。很可能是 Infura 或其他第三方节点提供商,它们不为您持有您帐户的私钥。

    因此,您需要在应用上签署交易,然后将签署的交易广播到您的节点。实现这一目标的方法很少。

    例如,您可以使用web3.eth.signTransaction() 对tx 进行签名,然后使用web3.eth.sendSignedTransaction() 将(已签名的)tx 提交到您的节点。

    或者您可以使用 accounts.wallet.add() 方法,然后使用 Contract 实例 send() 方法 - 请参阅答案的中间部分。


    您的 sn-p 创建一个常规的 ETH 传输 - 它不会创建一个令牌传输。

    您可以使用 Web3 Contract 方法来帮助您构建传输 ERC-20 代币的交易。

    // this is one of the other ways to sign a transaction on your end
    web3.eth.accounts.wallet.add(privateKeyToTheSenderAddress);
    
    // for this case, you can use a generic ERC-20 ABI JSON interface
    const myContract = new web3.eth.Contract(jsonInterface, contractAddress);
    
    // invoke the `transfer()` method on the contract
    // sign it using the private key corresponding to the `senderAddress`
    // and broadcast the signed tx to your node
    myContract.methods.transfer(toAddress, amount).send({from: senderAddress});
    

    我不确定这只是问题的错误措辞,还是逻辑错误。但是你不能转移属于合约的代币,除非合约代码允许你这样做。

    为什么?因为您需要发件人的私钥才能转移他们的代币。这是因为transfer()方法通常是如何构建的:

    function transfer(address _to, uint256 _amount) external returns (bool) {
        balances[msg.sender] -= _amount; // decreases balance of the transaction sender
        // ...
    }
    

    交易发送者需要使用他们的私钥签署交易。如果你想让发送者成为合约(减少合约的代币余额),你需要有它的私钥。你没有的(实际上不可能知道合约的私钥)。

    但如果交易发送方是授权地址,您的合约可能允许减少其余额。示例:

    function withdrawTokensFromContract(uint256 _amount) external {
        require(msg.sender == address(Ox123), 'Not authorized');
        balances[address(this)] -= _amount; // decreases balance of the contract
        // ...
    }
    

    在这种情况下,如果您使用属于授权地址的私钥签署了交易,则可以减少合约的代币余额。

    或者这只是一个不正确的措辞,您只是想将代币(存储在合约地址中)从Address A 转移到Address B。在这种情况下,您可以放心地使用答案中间部分描述的transfer()方法,并使用属于Address A的私钥对交易进行签名。

    【讨论】:

    • 使用了传输方法,它说“无法读取未定义的属性'添加'”,而 web3 像这样链接“"
    • 哦,我假设您在后端 JS (node.js) 上使用 web3。 wallet 扩展名似乎未包含在您的 web3 脚本中。因此,您可以导入另一个包含 wallet 功能的 web3 脚本 - 或者...在前端 JS 中定义私钥通常是不明智的,因为任何显示页面的人都可以读取私钥。在这种情况下,您可以使用例如实现Ethereum Provider API 的 MetaMask 浏览器扩展来签署交易,而无需在代码中传递私钥。
    • 您能否推荐任何包含所有必要扩展的 web3 脚本?
    猜你喜欢
    • 2022-07-08
    • 2019-08-04
    • 2021-10-01
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    相关资源
    最近更新 更多