您的位置:首页 > Web前端 > JavaScript

关于ethereumjs-tx在私链签名报错问题

2020-06-05 07:39 2401 查看

首先要先了解一下以太坊的chainid

 

 

CHAIN_ID Chain(s)
1 Ethereum mainnet
2 Morden (disused), Expanse mainnet
3 Ropsten
4 Rinkeby
30 Rootstock mainnet
31 Rootstock testnet
42 Kovan
61 Ethereum Classic mainnet
62 Ethereum Classic testnet
1337 Geth private chains (default)

 特别是在直接开启dev的情况下,默认id为1337

但是,要是你按web3的写法直接写(在tx为2.0版本的情况下)

[code]let account = '0x8e5761C0eeB594daF316161aFdc55914D8aB40DC'
let user2 = '0xB7BEA2D94f06353a15CCE8ab4AF5e98b2F3b87a3'
let strdata = '0x' + Buffer.from('asd').toString('hex')
var rawTx = {
from: account,
to: user2,
//gasPrice: "20000000000",	//可以默认,有需要可以查下如何设置gas节省旷工费
gas: 27052,	//如果报错gas过小,请把值调大
nonce:21,	//每次交易不能重复,不然会报错{"code":-32000,"message":"nonce too low"}
value:4052500000,	//单位转换web3.utils.toWei('0.1', 'ether')
data: strdata	//十六进制数据
};
var tx=new Tx(rawTx)
//开发节点其实可以直接使用web3.eth.sendTransaction,正式节点会报错,可能需要解锁,所以直接使用私钥调用
//这里说下测试中踏过的坑,geth开发节点创建用户 personal.newAccount("输入密码") 不会输出私钥,需要自行查询
//参考:https://blog.csdn.net/northeastsqure/article/details/79476831
//Buffer.from('FC1A5C66932BD7C93E05661A58FD534967739CE517D8695EBBE89135CEE78DA4', 'hex')
var privateKey = 'CF7AEE98197D1BA5D3AEC890647DC31045E2F242BDF5632C6BFB5B4DEF4F6F36'
tx.sign( Buffer.from('CF7AEE98197D1BA5D3AEC890647DC31045E2F242BDF5632C6BFB5B4DEF4F6F36', 'hex') )
var serializedTx = tx.serialize();
web3.eth.accounts.signTransaction('0x' + serializedTx.toString('hex')).then(signed => {
var tran = web3.eth.sendSignedTransaction(signed.rawTransaction);

tran.on('confirmation', (confirmationNumber, receipt) => {
console.log('confirmation: ' + confirmationNumber);
});

tran.on('transactionHash', hash => {
console.log('hash');
console.log(hash);

if(hash){
//res.writeHead(200, { "Content-Type": "application/json;charset=UTF-8" });

var data={
errcode:'0',
errmsg:'成功',
data:hash
};
console.log(data)
//res.end(JSON.stringify(data));
}else{
var data={
errcode:'1',
errmsg:'错误'
};
console.log(data)
//res.writeHead(200, { "Content-Type": "application/json;charset=UTF-8" });
//res.end(JSON.stringify(data));
}
});

tran.on('receipt', receipt => {
console.log('reciept');
console.log(receipt);
});

tran.on('error', console.error);
});

 这样会报错 invid sender

百度谷歌搜了一圈搜不到原因

最后沉下心去看官方的api

结果...

Chain and Hardfork Support

The 

Transaction
 and 
FakeTransaction
 constructors receives a second parameter that lets you specify the chain and hardfork to be used. By default, 
mainnet
 and 
petersburg
 will be used.

There are two ways of customizing these. The first one, as shown in the previous section, is by using an object with 

chain
 and 
hardfork
 names. You can see en example of this in ./examples/ropsten-tx.ts.

The second option is by passing the option 

common
 set to an instance of ethereumjs-common' Common. This is specially useful for custom networks or chains/hardforks not yet supported by 
ethereumjs-common
. You can see en example of this in ./examples/custom-chain-tx.ts.

[code]import { Transaction } from '../src'
import Common from 'ethereumjs-common'
import { bufferToHex, privateToAddress } from 'ethereumjs-util'

// In this example we create a transaction for a custom network.
//
// All of these network's params are the same than mainnets', except for name, chainId, and
// networkId, so we use the Common.forCustomChain method.
const customCommon = Common.forCustomChain(
'mainnet',
{
name: 'my-network',
networkId: 123,
chainId: 2134,
},
'petersburg',
)

// We pass our custom Common object whenever we create a transaction

const tx = new Transaction(
{
nonce: 0,
gasPrice: 100,
gasLimit: 1000000000,
value: 100000,
},
{ common: customCommon },
)

// Once we created the transaction using the custom Common object, we can use it as a normal tx.

// Here we sign it and validate its signature
const privateKey = new Buffer(
'e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109',
'hex',
)

tx.sign(privateKey)

if (
tx.validate() &&
bufferToHex(tx.getSenderAddress()) === bufferToHex(privateToAddress(privateKey))
) {
console.log('Valid signature')
} else {
console.log('Invalid signature')
}

console.log("The transaction's chain id is", tx.getChainId())

于是我们照猫画虎就好啦

[code]const customCommon = Common.forCustomChain(
'mainnet',
{
name: 'my-network',
networkId: 1337,
chainId: 1337,
},
'petersburg',
)
web3.eth.getTransactionCount("账号名").then(count=>{
var value=Buffer.from(web3.utils.toWei('10000', 'ether'), 'hex')
let account = '接收方'
let user2 = '发送方'
var rawTx = {
from: account,
to: user2,
gasPrice: 20000000000,	//可以默认,有需要可以查下如何设置gas节省旷工费
gas: 27052,	//如果报错gas过小,请把值调大
nonce:count,	//每次交易不能重复,不然会报错{"code":-32000,"message":"nonce too low"}
value:value,	//单位转换web3.utils.toWei('0.1', 'ether')
chainId: 1337
};
var tx=new Tx(rawTx,
{ common: customCommon })
var privateKey = '私钥'
tx.sign( Buffer.from(privateKey, 'hex'))
var serializedTx = tx.serialize();
console.log(serializedTx)

web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'))
.on('receipt', console.log).on('error', console.error);
})

至于怎么部署好geth之后拿到私钥,看前一篇https://blog.csdn.net/xxy41092/article/details/106239206

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: