128

关于 eth_sendRawTransaction 的尝试

today · 于 发布 · 最后由 rubyu2回复 · 2037 次阅读

这几天心血来潮,想研究一下eth_sendRawTransaction这个方法。看了一些文档。按照以下流程开搞(基于ubuntu系统)

  1. 安装ethereumjs-tx
  2. 安装keythereum
  3. 利用js得到加签的交易,js代码如下
var Tx = require('ethereumjs-tx');
var keythereum = require("keythereum");
var datadir = "keystore地址";
var fromkey = keythereum.importFromFile("交易发送方的地址", datadir);
var privateKey = keythereum.recover('交易发送方的密码', fromkey);
var rawTx = {
  nonce: '0x29e',//由eth_getTransactionCount获取。参数为交易发送方地址
  to: '交易接收方地址',
  gasPrice:'0x4a817c800',
  gasLimit: '0x47e7c4',
  value: '0xa', 
  data: ''
}
var tx = new Tx(rawTx);
tx.sign(privateKey);
var serializedTx = tx.serialize();
var rawparam = serializedTx.toString('hex');
  1. 发起交易 curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["步骤三得到的rawparam"],"id":1}',得到交易hash。
  2. 根据上一步得到的交易hash查询交易 eth_getTransactionByHash,发现,交易始终没有记录到区块上,即查询返回的结果中 blockNumber 一直是null。

请教各位大神,这是怎么回事儿呢。是不是我的哪一步操作有问题呢?求助

  • 43 large
    lgn21st

    流程大体上是对的,采用手动构造 TX 然后签名生成 bytecode 的过程有很多坑,给你几个检查点你参考一下:

    1. 验证你的 Private Key - 你通过 keythereum 还原出的 private key 是不是正确的,这个需要验证一下,比如你通过这个 private key 生成的 public key 是不是就是你的 account address?(ethereumjs-tx 提供了私钥到公钥的转换方法)
    2. 构造的交易中,是不需要包含 from 的,因为这个交易是通过私钥签名的,而私钥生成的签名是可以还原出公钥地址的,所以交易本身不需要冗余存储发送方信息。
    3. 同上条,构造交易中,只需要指定 gasPrice 和 gasLimit,而不需要指定 gas,因为 gas 消耗量是不可能被精确估算的,所以只需要 price 和 limit 两个参数,多余的 gas 会被退回来。
    4. 关于 nonce,这个字段需要取你的发送账号所发起的交易的计数器,可以通过 eth_getTransactionCount 来获取当前的 nonce
    5. 发送前,必须确保你的发送账号以太币余额,余额必须满足发送交易所消耗的 gas 数量

    最后,生成的字节码可以直接到第三方,比如 https://etherscan.io/pushTx 来广播你的交易,如果广播失败,可以直接看到错误提示信息,也许对你有帮助。

  • 128
    today

    @lgn21st 非常感谢,问题解决了。是因为我之前nonce一直用的eth_getTransactionCount的结果+1,导致了错误。

  • 51 large
    rubyu2

    嗯,nonce是从0开始的,所以拿到count之后,直接用就是对的。