3

我正在为以太坊使用 web3.js 模块。在执行交易时,我收到错误响应。

错误:

"Error: Invalid JSON RPC response: ""
    at Object.InvalidResponse (/home/akshay/WS/ethereum/node_modules/web3-core-helpers/src/errors.js:42:16)
    at XMLHttpRequest.request.onreadystatechange (/home/akshay/WS/ethereum/node_modules/web3-providers-http/src/index.js:73:32)
    at XMLHttpRequestEventTarget.dispatchEvent (/home/akshay/WS/ethereum/node_modules/xhr2/lib/xhr2.js:64:18)
    at XMLHttpRequest._setReadyState (/home/akshay/WS/ethereum/node_modules/xhr2/lib/xhr2.js:354:12)
    at XMLHttpRequest._onHttpResponseEnd (/home/akshay/WS/ethereum/node_modules/xhr2/lib/xhr2.js:509:12)
    at IncomingMessage.<anonymous> (/home/akshay/WS/ethereum/node_modules/xhr2/lib/xhr2.js:469:24)
    at emitNone (events.js:111:20)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)"

我正在使用 ropsten 测试网络 url 来测试我的智能合约:

https://ropsten.infura.io/API_KEY_HERE

当我调用该balanceOf函数时,它可以正常工作,但是当我尝试调用函数时transfer,它会向我发送此错误。代码如下:

router.post('/transfer', (req, res, next)=>{
  contractInstance.methods.transfer(req.body.address, req.body.amount).send({from:ownerAccountAddress})
  .on('transactionHash',(hash)=>{
console.log(hash)
  }).on('confirmation',(confirmationNumber, receipt)=>{
    console.log(confirmationNumber)
    console.log(receipt)
  }).on('receipt', (receipt)=>{
    console.log(receipt)
  }).on('error',(err)=>{
    console.log(err)
  })
})

请让我知道我错在哪里。

编辑:我正在使用 web3js 版本"web3": "^1.0.0-beta.34"

4

2 回答 2

4

补充一下 maptuhec 所说的,在 Web3 中调用“状态更改”函数或状态更改事务时,必须签名!

以下是您尝试调用公共函数(甚至是公共合约变量)时的示例,该函数仅读取(或“查看”)并从您的智能合约返回一个值而不更改其状态,在我们不需要指定一个交易主体然后将其作为交易签名,因为它不会改变我们合约的状态。

contractInstance.methods.aPublicFunctionOrVariableName().call().then( (result) => {console.log(result);})

**

改变状态的交易

**

现在,考虑下面的例子,这里我们试图调用一个“状态改变”函数,因此我们将为它指定一个适当的事务结构。

web3.eth.getTransactionCount(functioncalleraddress).then( (nonce) => {
        let encodedABI = contractInstance.methods.statechangingfunction().encodeABI();
 contractInstance.methods.statechangingfunction().estimateGas({ from: calleraddress }, (error, gasEstimate) => {
          let tx = {
            to: contractAddress,
            gas: gasEstimate,
            data: encodedABI,
            nonce: nonce
          };
          web3.eth.accounts.signTransaction(tx, privateKey, (err, resp) => {
            if (resp == null) {console.log("Error!");
            } else {
              let tran = web3.eth.sendSignedTransaction(resp.rawTransaction);
              tran.on('transactionHash', (txhash) => {console.log("Tx Hash: "+ txhash);});

有关signTransactionsendSignedTransactiongetTransactionCountestimateGas的更多信息

于 2018-07-16T14:20:24.533 回答
1

使用 Web3.js 时,您应该签署交易。当您调用非常量的函数时,例如 transfer,您应该签署交易,然后发送已签署的交易(有一个名为 sendSignedTransaction 的方法)。使用 web3js 很难,我推荐使用 ehtersjs,有了它一切都容易多了。

于 2018-07-16T08:05:01.643 回答