You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Infura调用智能合约发送交易时遇eth_sendTransaction不可用错误

解决Infura下eth_sendTransaction不存在的错误

错误原因

Infura作为公共以太坊RPC节点,不支持eth_sendTransaction方法。该方法要求节点托管用户私钥并完成交易签名,而Infura出于安全考虑不提供此类服务。读函数(如getAppliances().call())无需签名,因此可以正常运行。

修复方案:本地签名交易后发送

需要手动构建交易、使用私钥完成本地签名,再通过eth_sendRawTransaction将签名后的交易发送至Infura。以下是修改后的完整Node.js代码:

修改后的代码

const web3 = require('web3');
const fs = require("fs");

const CONTRACT_ABI = `[
        {
                "anonymous": false,
                "inputs": [
                        {
                                "indexed": true,
                                "internalType": "address",
                                "name": "previousOwner",
                                "type": "address"
                        },
                        {
                                "indexed": true,
                                "internalType": "address",
                                "name": "newOwner",
                                "type": "address"
                        }
                ],
                "name": "OwnershipTransferred",
                "type": "event"
        },
        {
                "inputs": [
                        {
                                "internalType": "string",
                                "name": "name",
                                "type": "string"
                        },
                        {
                                "internalType": "bytes1",
                                "name": "pin",
                                "type": "bytes1"
                        }
                ],
                "name": "addAppliance",
                "outputs": [],
                "stateMutability": "nonpayable",
                "type": "function"
        },
        {
                "inputs": [
                        {
                                "internalType": "uint256",
                                "name": "",
                                "type": "uint256"
                        }
                ],
                "name": "appliances",
                "outputs": [
                        {
                                "internalType": "uint256",
                                "name": "id",
                                "type": "uint256"
                        },
                        {
                                "internalType": "string",
                                "name": "name",
                                "type": "string"
                        },
                        {
                                "internalType": "bool",
                                "name": "status",
                                "type": "bool"
                        },
                        {
                                "internalType": "bytes1",
                                "name": "pin",
                                "type": "bytes1"
                        }
                ],
                "stateMutability": "view",
                "type": "function"
        },
        {
                "inputs": [
                        {
                                "internalType": "uint256",
                                "name": "id",
                                "type": "uint256"
                        }
                ],
                "name": "getAppliance",
                "outputs": [
                        {
                                "components": [
                                        {
                                                "internalType": "uint256",
                                                "name": "id",
                                                "type": "uint256"
                                        },
                                        {
                                                "internalType": "string",
                                                "name": "name",
                                                "type": "string"
                                        },
                                        {
                                                "internalType": "bool",
                                                "name": "status",
                                                "type": "bool"
                                        },
                                        {
                                                "internalType": "bytes1",
                                                "name": "pin",
                                                "type": "bytes1"
                                        }
                                ],
                                "internalType": "struct Appliance",
                                "name": "",
                                "type": "tuple"
                        }
                ],
                "stateMutability": "view",
                "type": "function"
        },
        {
                "inputs": [],
                "name": "getAppliances",
                "outputs": [
                        {
                                "components": [
                                        {
                                                "internalType": "uint256",
                                                "name": "id",
                                                "type": "uint256"
                                        },
                                        {
                                                "internalType": "string",
                                                "name": "name",
                                                "type": "string"
                                        },
                                        {
                                                "internalType": "bool",
                                                "name": "status",
                                                "type": "bool"
                                        },
                                        {
                                                "internalType": "bytes1",
                                                "name": "pin",
                                                "type": "bytes1"
                                        }
                                ],
                                "internalType": "struct Appliance[]",
                                "name": "",
                                "type": "tuple[]"
                        }
                ],
                "stateMutability": "view",
                "type": "function"
        },
        {
                "inputs": [],
                "name": "getAppliancesCount",
                "outputs": [
                        {
                                "internalType": "uint256",
                                "name": "",
                                "type": "uint256"
                        }
                ],
                "stateMutability": "view",
                "type": "function"
        },
        {
                "inputs": [],
                "name": "owner",
                "outputs": [
                        {
                                "internalType": "address",
                                "name": "",
                                "type": "address"
                        }
                ],
                "stateMutability": "view",
                "type": "function"
        },
        {
                "inputs": [
                        {
                                "internalType": "uint256",
                                "name": "id",
                                "type": "uint256"
                        }
                ],
                "name": "removeAppliance",
                "outputs": [],
                "stateMutability": "nonpayable",
                "type": "function"
        },
        {
                "inputs": [],
                "name": "renounceOwnership",
                "outputs": [],
                "stateMutability": "nonpayable",
                "type": "function"
        },
        {
                "inputs": [
                        {
                                "internalType": "uint256",
                                "name": "id",
                                "type": "uint256"
                        },
                        {
                                "internalType": "bool",
                                "name": "status",
                                "type": "bool"
                        }
                ],
                "name": "toggleAppliance",
                "outputs": [],
                "stateMutability": "nonpayable",
                "type": "function"
        },
        {
                "inputs": [
                        {
                                "internalType": "address",
                                "name": "newOwner",
                                "type": "address"
                        }
                ],
                "name": "transferOwnership",
                "outputs": [],
                "stateMutability": "nonpayable",
                "type": "function"
        },
        {
                "inputs": [
                        {
                                "internalType": "uint256",
                                "name": "id",
                                "type": "uint256"
                        },
                        {
                                "internalType": "string",
                                "name": "name",
                                "type": "string"
                        },
                        {
                                "internalType": "bytes1",
                                "name": "pin",
                                "type": "bytes1"
                        }
                ],
                "name": "updateAppliance",
                "outputs": [],
                "stateMutability": "nonpayable",
                "type": "function"
        }
]`;
const CONTRACT_ADDRESS = "0x13d9FA79D364070510B410c2FaC1976F21E3e218";

const web3js = new web3(new web3.providers.HttpProvider("https://sepolia.infura.io/v3/9e644c118b7c44068674e2d12a776536"));

var myAddress = '0x46Be881Fa6935a8FC969A4ddDFC74d625c558996';
const privateKey = Buffer.from('82f98661ea7e05ac4bad0965da4b8a1fab93cf27e606d1185a275c91f96aac9b', 'hex')
var contractABI = JSON.parse(CONTRACT_ABI);
var contractAddress = CONTRACT_ADDRESS;

const contract = new web3js.eth.Contract(contractABI, contractAddress);

async function main() {
    // 1. 获取地址当前nonce(避免交易重复)
    const nonce = await web3js.eth.getTransactionCount(myAddress, 'pending');
    
    // 2. 编码合约方法调用数据
    const functionData = contract.methods.addAppliance("fan", web3.utils.numberToHex(1)).encodeABI();
    
    // 3. 构建交易对象
    const txObject = {
        nonce: web3js.utils.toHex(nonce),
        gasLimit: web3js.utils.toHex(200000), // 可根据实际情况调整gas上限
        gasPrice: web3js.utils.toHex(await web3js.eth.getGasPrice()),
        to: contractAddress,
        data: functionData,
        from: myAddress
    };
    
    // 4. 本地签名交易
    const signedTx = await web3js.eth.accounts.signTransaction(txObject, privateKey);
    
    // 5. 发送签名后的原始交易
    const txReceipt = await web3js.eth.sendSignedTransaction(signedTx.rawTransaction);
    console.log("交易回执:", txReceipt);

    // 调用读函数验证结果
    let applianceOnOff = await contract.methods.getAppliances().call();
    console.log("设备列表:", applianceOnOff);
}

main()
    .then(() => process.exit(0))
    .catch(error => {
        console.error(error);
        process.exit(1);
});

关键修改说明

  • 放弃contract.methods.addAppliance().send({from: myAddress})的自动签名逻辑,改为手动处理交易签名与发送
  • 通过getTransactionCount获取地址nonce,确保交易按顺序执行
  • 使用encodeABI()编码合约方法调用的字节数据
  • 调用accounts.signTransaction完成本地私钥签名
  • 用sendSignedTransaction提交签名后的原始交易

额外提示

  • 合约中toggleAppliance函数声明的第二个参数bool status未在函数体中使用(直接取反现有状态),可考虑移除冗余参数或调整逻辑
  • 私钥请勿硬编码在代码中,建议使用环境变量或加密存储方式管理

内容的提问来源于stack exchange,提问作者Martin Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 05:15:28