Private-Key

正確的交易簽名

  • July 22, 2017

我正在嘗試在 nodejs 中實現投票系統。當提供使用者私鑰時,我的伺服器需要能夠創建交易並將其發送到乙太坊區塊鏈。我曾嘗試使用不同的模組這樣做,但我似乎總是遇到同樣的問題。- 與 RPC 的連接工作正常 - 交易似乎創建得恰到好處 - 交易註冊為由我的本地節點發送到網路,但永遠不會出現在區塊鏈中。

我已經設法在使用 web3 時註冊了交易,但如果我想自己簽署交易,我就不能這樣做。測試是使用測試網(ropsten 和 kovan)上的本地或遠端(infura)節點完成的。我可能有問題的提示:-使用 web3 創建事務(成功)時,我的本地節點將事務雜湊視為“0x456515 …”,地址為“0xcfnsk55sghHG …”-使用ethereumjs 執行相同操作時-tx 來簽署交易,節點將其視為“456515…”和“&cfnsk55sghHG…”我正在尋找有關問題所在或如何解決問題的任何資訊/幫助=)

var Web3 = require('web3');
var Tx = require('ethereumjs-tx');
var _ = require('lodash');
var SolidityFunction = require('web3/lib/web3/function');
var keythereum = require("keythereum");
var web3 = new Web3();

web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545"));

var toAccount ='0x2824dD13D388ed0Df7Ae1b5697b7b66E737E021a';
var fromAccount = '0x4129c6A02caB77DeEdBDC221904a3dc1ab7cAAfE';
var privateKey = Buffer.from('My Private Key', 'hex' );
gasPrice = web3.eth.gasPrice;
gasPriceHex = web3.toHex(gasPrice);
gasLimitHex = web3.toHex(300000);
console.log('Current gasPrice: ' + gasPrice + ' OR ' + gasPriceHex);
nonce =  web3.eth.getTransactionCount(fromAccount) ;
nonceHex = web3.toHex(nonce);
console.log('nonce (transaction count on fromAccount): ' + nonce + '(' + nonceHex + ')');

var rawTx = {
   nonce: '0x85555',
   gasPrice: gasPriceHex,
   gasLimit: gasLimitHex,
   to: toAccount,
   from: fromAccount,
   value: web3.toHex(web3.toWei ( 1, "ether")),
   data: '0x7f7465737435000',
   chainId: '0x3',
};

var tx = new Tx(rawTx);
tx.sign(privateKey);
var serializedTx = tx.serialize();

web3.eth.sendRawTransaction('0x'+serializedTx.toString('hex'), function (err, hash) {
   if (err) {
       console.log('Error:');
       console.log(err);
   }
   else {
       console.log('Transaction receipt hash pending');
       console.log(hash);
   }
});

謝謝你

我不知道這是否是發送原始交易的正確方法,但它確實有效。剛剛測試過了。

const Web3 = require('web3');
const Tx = require('ethereumjs-tx');
const config = require('./config');

const web3 = new Web3(new Web3.providers.HttpProvider(config.provider)); //link provided by Infura.io
web3.eth.defaultAccount = "0xc929c890f1398d5c1ecdf4f9ecec016906ac9f7f";

const getNonce = () => {
 return new Promise((resolve, reject) => {
   web3.eth.getTransactionCount(web3.eth.defaultAccount, (error, result) => {
     if(error) reject(error);
     resolve(web3.toHex(result));
   })
 })
}
const getGasPrice = () => {
 return new Promise((resolve, reject) => {
   web3.eth.getGasPrice((error, result) => {
     if(error) reject(error);
     resolve(web3.toHex(result.toNumber()));
   })
 })
}

const sendRawTransaction = (rawTx) => {
 const privateKey = "190b820c2627f26fd1b973b72dcba78ff677ca4395c64a4a2d0f4ef8de36883c";
 const tx = new Tx(rawTx);
 const privateKeyBuffer = Buffer.from(privateKey, 'hex');
 tx.sign(privateKeyBuffer);
 const serializedTx = tx.serialize();
 web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {
     console.log('Error:', err);
     console.log('Hash:', hash);
 });
}

Promise.all([getNonce(), getGasPrice()])
 .then(values => {
   const rawTx = {
     to: '0x203D17B4a1725E001426b7Ab3193E6657b0dBcc6',
     gasLimit: web3.toHex(1000000),
     value: web3.toHex(web3.toWei('0.1', 'ether')),
     nonce: values[0],
     gasPrice: values[1]
   };
   console.log(rawTx);
   return(rawTx);
 })
 .then(sendRawTransaction)
 .catch(e => console.log(e))

安慰:

{ 
 to: '0x203D17B4a1725E001426b7Ab3193E6657b0dBcc6',
 gasLimit: '0xf4240',
 value: '0x16345785d8a0000',
 nonce: '0x5',
 gasPrice: '0x4a817c800' 
}
Error: null
Hash: 0x2a156efdaa6be587544f32cdf7bac140bbee20dafda2c561a4c9195c6fa6729c

這是我生成密鑰對和地址的方式:

const keythereum = require('keythereum');
const utils = require('ethereumjs-util');

const params = {keyBytes: 32, ivBytes: 16};
const dk = keythereum.create(params);
const private = utils.bufferToHex(dk.privateKey);
const public = utils.bufferToHex(utils.privateToPublic(dk.privateKey));
const address = utils.bufferToHex(utils.privateToAddress(dk.privateKey));

好吧,我終於找到了所有這些問題的答案,正如之前所說的那樣,這裡的隨機數有問題,除了它有點微妙。您使用帳戶發送的每筆交易都應該增加與該帳戶相關的隨機數。最好的方法是使用:

nonce = web3.eth.getTransactionCount(fromAccount);

但是在測試網上(ropsten,而不是 kovan),初始帳戶隨機數設置為 0x100000,因此您必須使用:

nonce = web3.eth.getTransactionCount(fromAccount) + 1048576;

在客戶端(geth、parity、…)中顯示為“&28…”或“0x28…”的地址沒有區別。使用連續隨機數時要非常小心。

引用自:https://ethereum.stackexchange.com/questions/12823