Web3 web3.eth.sendSignedTransaction 无效参数

Posted

技术标签:

【中文标题】Web3 web3.eth.sendSignedTransaction 无效参数【英文标题】:Web3 web3.eth.sendSignedTransaction Invalid params 【发布时间】:2019-12-12 11:31:25 【问题描述】:

我对以太坊很陌生,我已经使用 pantheon 客户端建立了一个专用网络。我已成功将合同部署到网络,并且在通过 remix 使用时与合同的所有交互都有效。

我正在尝试设置一个中继,其中交易在客户端签名,发送到 nodeJs 服务器,然后服务器将交易代理到合同。但是,当我将签名的交易传递给sendSignedTransaction() 时,我收到错误Invalid params,对我来说这是非常模糊的,我不确定我做错了什么/无效的参数是什么。 (关于如何调试的任何建议?)

更新

使用 web3 v1.2.0

错误

Error: Returned error: Invalid params
    at Object.ErrorResponse (/Users/ghost/node_modules/web3-core-helpers/src/errors.js:29:16)
    at Object.<anonymous> (/Users/ghost/node_modules/web3-core-requestmanager/src/index.js:140:36)
    at /Users/ghost/node_modules/web3-providers-ws/src/index.js:121:44
    at Array.forEach (<anonymous>)
    at W3CWebSocket.WebsocketProvider.connection.onmessage (/Users/ghost/node_modules/web3-providers-ws/src/index.js:98:36)
    at W3CWebSocket._dispatchEvent [as dispatchEvent] (/Users/ghost/node_modules/yaeti/lib/EventTarget.js:107:17)
    at W3CWebSocket.onMessage (/Users/ghost/node_modules/websocket/lib/W3CWebSocket.js:234:14)
    at WebSocketConnection.<anonymous> (/Users/ghost/node_modules/websocket/lib/W3CWebSocket.js:205:19)
    at WebSocketConnection.emit (events.js:188:13)
    at WebSocketConnection.processFrame (/Users/ghost/node_modules/websocket/lib/WebSocketConnection.js:552:26)
    at /Users/ghost/node_modules/websocket/lib/WebSocketConnection.js:321:40
    at process.internalTickCallback (internal/process/next_tick.js:70:11)

合同

pragma solidity ^0.5.1;

import "./Ownable.sol";

contract Entry is Ownable  
    mapping (address => string) hash;


    function addEntry(string memory _hash) public 
        hash[msg.sender] = _hash;
    

    function getHash() public view returns(string memory)
        return hash[msg.sender];
    


中继服务器

const Web3 = require('web3');
const express = require('express')
const app = express()
const port = 3003
const bodyParser = require('body-parser');
const cors = require('cors')

app.use(bodyParser.urlencoded(extended: true));
app.use(bodyParser.json())
app.use(cors())

var web3 = new Web3(Web3.givenProvider || "ws://localhost:7002");

app.post('/transaction/send', async (req, res) => 
    const tx, data = req.body;

    web3.eth.sendSignedTransaction(tx, function (err, transactionHash) 
      if(err) console.log(err);
      console.log(transactionHash);
    );
)

app.listen(port, () => console.log(`Example app listening on port $port!`))

前端

import React from 'react';
import './App.css';
import Web3 from 'web3';
import request from 'request-promise';

const Tx = require('ethereumjs-tx').Transaction;
const web3 = new Web3("http://localhost:8545");
const privKey = '[My Priv key here]';
const contractADDRESS = "0x4261d524bc701da4ac49339e5f8b299977045ea5";
const addressFrom = '0x627306090abaB3A6e1400e9345bC60c78a8BEf57';
const contractABI = ["constant":false,"inputs":["name":"_hash","type":"string"],"name":"addEntry","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","constant":true,"inputs":[],"name":"owner","outputs":["name":"","type":"address"],"payable":false,"stateMutability":"view","type":"function","constant":true,"inputs":[],"name":"getHash","outputs":["name":"","type":"string"],"payable":false,"stateMutability":"view","type":"function","constant":false,"inputs":["name":"newOwner","type":"address"],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","anonymous":false,"inputs":["indexed":true,"name":"previousOwner","type":"address","indexed":true,"name":"newOwner","type":"address"],"name":"OwnershipTransferred","type":"event"];


function App() 

  async function sendTx() 
    const data = await extraData();
    web3.eth.getTransactionCount(addressFrom).then(txCount => 
      const txData = 
        nonce: web3.utils.toHex(txCount),
        gasLimit: web3.utils.toHex(25000),
        gasPrice: web3.utils.toHex(10e9),
        to: contractADDRESS,
        from: addressFrom,
        data: data
      

      sendSigned(txData, function(err, result) 
        if (err) return console.log('error', err)
        console.log('sent', result)
      )

    )
  

  async function sendSigned(txData, cb) 
    const privateKey = new Buffer(privKey, 'hex')
    const transaction = new Tx(txData)
    transaction.sign(privateKey)
    const serializedTx = transaction.serialize().toString('hex')
    const response = request(
      method: 'POST',
      uri: 'http://127.0.0.1:3003/transaction/send',

      body: 
          tx: serializedTx,
          data: 'somehashhh'
      ,
      json: true,
    );
  

  async function extraData() 
    const contractInstance = new web3.eth.Contract(contractABI, contractADDRESS);
    return await contractInstance.methods.addEntry('somehashhh').encodeABI();
  

  return (
    <div className="App">
      <header className="App-header">
        <div onClick=() => sendTx()>Submit transaction</div>
      </header>
    </div>
  );


export default App;

这是前端发送的txData


data: "0x17ce42bd0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a736f6d6568617368686800000000000000000000000000000000000000000000"
from: "0x627306090abaB3A6e1400e9345bC60c78a8BEf57"
gasLimit: "0x61a8"
gasPrice: "0x2540be400"
nonce: "0x0"
to: "0x4261d524bc701da4ac49339e5f8b299977045ea5"

【问题讨论】:

我猜你错误的生成tx,请看***.com/questions/57081821/… 【参考方案1】:

经过大量的跟踪和错误后,堆栈溢出工作的 0 建议,我已经让交易签名工作了!最后我放弃了使用ethereumjs-tx(由于某种原因被很多人推荐)而只使用了纯Web3。

前端客户端

  async function sendTx() 
    const  address: from  = web3.eth.accounts.privateKeyToAccount(PRIVATE_KEY)
    const contract = new web3.eth.Contract(CONTRACT_ABI, CONTRACT_ADDRESS)
    const query = await contract.methods.updateCount();

    const signed = await web3.eth.accounts.signTransaction(
        to: CONTRACT_ADDRESS,
        from,
        value: '0',
        data: query.encodeABI(),
        gasPrice: web3.utils.toWei('20', 'gwei'),
        gas: Math.round((await query.estimateGas( from )) * 1.5),
        nonce: await web3.eth.getTransactionCount(from, 'pending')
    , PRIVATE_KEY)

    const response = await request(
      method: 'POST', json: true, 
      uri: 'http://127.0.0.1:3003/transaction/send', 
      body: 
        tx: signed.rawTransaction,
        data: 'some data'
      
    );

    console.log(response);
  

中继服务器

const Web3 = require('web3');
const express = require('express')
const app = express()
const port = 3003
const bodyParser = require('body-parser');
const cors = require('cors')

app.use(bodyParser.urlencoded(extended: true));
app.use(bodyParser.json())
app.use(cors())

var web3 = new Web3(Web3.givenProvider || "ws://localhost:7002");

app.post('/transaction/send', async (req, res) => 
    const tx, data = req.body;

    web3.eth.sendSignedTransaction(tx)
    .on('transactionHash', (txHash) => res.json(txHash))
    .on('error', console.log)
)

app.listen(port, () => console.log(`Example app listening on port $port!`))

希望这可以帮助其他人 ?

【讨论】:

以上是关于Web3 web3.eth.sendSignedTransaction 无效参数的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 npm 安装 web3 时找不到 web3/dist/web3.min.js

web3.js 和 web3-light.js 有啥区别?

以太坊 Web3.js 返回“找不到模块‘web3-requestManager’”

使用带有 web3 的 npm 链接

web3.0+元宇宙的热门话题

web3.personal.ecRecover 不起作用