- ethereum/
- Ethereum 如何从交易凭证重新创建原始交易,以验证v、r、s签名?
Ethereum 如何从交易凭证重新创建原始交易,以验证v、r、s签名?
Ethereum 如何从交易凭证重新创建原始交易,以验证v、r、s签名?,ethereum,web3,Ethereum,Web3,我正在尝试验证以太坊交易
以下是我的步骤。
1.进行交易
2.使用eth.getTransaction()获取事务
3.使用ethereumjs tx重新创建事务
但有时我无法验证交易
案例1:私有测试网上的简单发送以太事务
获取事务详细信息
{
blockHash: "0x2125539ac67b4569828737ffb1731048e00121954f0555d0dc96af665071a62b",
blockNumber: 24615,
from: "0x81c24515cd
我正在尝试验证以太坊交易
以下是我的步骤。
1.进行交易
2.使用eth.getTransaction()获取事务
3.使用ethereumjs tx重新创建事务
但有时我无法验证交易
案例1:私有测试网上的简单发送以太事务
获取事务详细信息
{
blockHash: "0x2125539ac67b4569828737ffb1731048e00121954f0555d0dc96af665071a62b",
blockNumber: 24615,
from: "0x81c24515cdf1a4b68f34e3e2824d44b28d00f010",
gas: 90000,
gasPrice: 18000000000,
hash: "0x9e4ce952759eae925173c6c6055c1afe577a48462caacd8d4fb742e911eae053",
input: "0x",
nonce: 0,
r: "0x826b5348acbec72bab39c5debc8493e34d23b351bc7c20ded25d2a4eed736093",
s: "0x2a87e18b22c76d61ce9d6a4d56949afa025f1611aa6bb9fd9d6c502d61f7361b",
to: "0x487f5eea74ea5f3e94093d8b0501f1d2b0d5310a",
transactionIndex: 0,
v: "0x10f469",
value: 1000000000000000000
}
{
区块散列:“0x2125539ac67b4569828737ffb1731048e00121954f0555d0dc96af665071a62b”,
区块编号:24615,
发件人:“0x81c24515cdf1a4b68f34e3e2824d44b28d00f010”,
煤气:90000,
加斯普里斯:180亿,
散列:“0x9e4ce952759eae925173c6c6055c1afe577a48462caacd8d4fb742e911eae053”,
输入:“0x”,
零时:,
r:“0x826b5348acbec72bab39c5debc8493e34d23b351bc7c20ded25d2a4eed736093”,
s:“0x2A87E18B22C76D61CE9D6A4D6949AFA025F1611AA6B9FD9D6C502D61F7361B”,
致:“0x487F5EEA74EA5F3E94093D8B051F1D2B0D5310A”,
transactionIndex:0,
v:“0x10f469”,
价值:10000000000000000
}
然后使用事务详细信息和ethereumjs-tx创建一个transaction
const EthereumTx = require('ethereumjs-tx')
const test_arr1 = {
nounce: "0x"+parseInt(0, 10).toString(16),
gasPrice: "0x"+parseInt(18000000000, 10).toString(16),
gasLimit: "0x"+parseInt(90000, 10).toString(16),
to: '0x487f5eea74ea5f3e94093d8b0501f1d2b0d5310a',
value: "0x"+parseInt(1000000000000000000, 10).toString(16),
data: '0x',
v: '0x10f469',
r: '0x826b5348acbec72bab39c5debc8493e34d23b351bc7c20ded25d2a4eed736093',
s: '0x2a87e18b22c76d61ce9d6a4d56949afa025f1611aa6bb9fd9d6c502d61f7361b'
}
const tx = new EthereumTx(test_arr1);
const recoveredAddress = "0x"+tx.getSenderAddress().toString('hex')
recoveredAddress is 0x81c24515cdf1a4b68f34e3e2824d44b28d00f010 which is correct
const EthereumTx = require('ethereumjs-tx')
const test_arr2 = {
nounce: "0x"+parseInt(129, 10).toString(16),
gasPrice: "0x"+parseInt(18000000000, 10).toString(16),
gasLimit: "0x"+parseInt(309588, 10).toString(16),
to: '0xad5e2d5cb93f098423597c891d2f1ed35f904ca1',
value: "0x",
data: '0x03e63bdb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000890000000b000000012e507fe5cce2f11c2a520a265f593c08372834fec925f84bbe5a72793ec5096d03fd11970afed8b767adfed60caf3f0c1de0dbda06d48f9afc3661717dbf85641b3f011114d3a41bf16a8d8cc33769aba2abe14efb14487295c80da13b3e333707202d1bdea56f75616202491b4bcc437b6a5b7a79284a08e28bcd0a90e3d87bf10000000000000000000000000000000000000000000000',
v: '0x2a',
r: '0xdd4fe550275bd35ffd4babf6ac3578575594011f027923046da78a7b179ffb66',
s: '0x2584e1f3f36185f6cd9358146f2479dde41dbb85ced5859c845a065cb5bdc42b',
chainId: 3
}
const tx2 = new EthereumTx(test_arr2);
const recoveredAddress = "0x"+tx2.getSenderAddress().toString('hex')
recoveredAddress is 0x9c9d4315824275f545b2e96026a7075f75125b9b which is NOT correct. It should be 0x0d6883a0e7071513c7d90a27bf2715bc71ecf107
常量EthereumTx=require('ethereumjs-tx')
常数测试\u arr1={
名词:“0x”+parseInt(0,10).toString(16),
加斯普里斯:“0x”+parseInt(18000000000,10)。toString(16),
gasLimit:“0x”+parseInt(90000,10).toString(16),
至:“0x487F5EEA74EA5F3E94093D8B051F1D2B0D5310A”,
值:“0x”+parseInt(10000000000000000,10).toString(16),
数据:“0x”,
v:'0x10f469',
r:'0x826b5348acbec72bab39c5debc8493e34d23b351bc7c20ded25d2a4eed736093',
s:'0x2A87E18B22C76D61CE9D6A4D6949AFA025F1611AA6B9FD9D6C502D61F1F7361B'
}
const tx=新以太坊tx(测试1);
const recoveredAddress=“0x”+tx.getSenderAddress().toString('hex')
恢复的地址是0x81c24515cdf1a4b68f34e3e2824d44b28d00f010,这是正确的
案例2:ropsten testnet中的智能合约
获取事务详细信息
{
blockHash: "0xead9335751dbdb4a874b2bb48ac15ddafbec6f2ba55a5932bf6ec1a0475166e7",
blockNumber: 3026266,
from: "0x0d6883a0e7071513c7d90a27bf2715bc71ecf107",
gas: 309588,
gasPrice: 18000000000,
hash: "0xe69d8b108af59198857dd5b045769748dbe1ca3ad9bba7dbbb512643b9d85b5a",
input: "0x03e63bdb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000890000000b000000012e507fe5cce2f11c2a520a265f593c08372834fec925f84bbe5a72793ec5096d03fd11970afed8b767adfed60caf3f0c1de0dbda06d48f9afc3661717dbf85641b3f011114d3a41bf16a8d8cc33769aba2abe14efb14487295c80da13b3e333707202d1bdea56f75616202491b4bcc437b6a5b7a79284a08e28bcd0a90e3d87bf10000000000000000000000000000000000000000000000",
nonce: 129,
r: "0xdd4fe550275bd35ffd4babf6ac3578575594011f027923046da78a7b179ffb66",
s: "0x2584e1f3f36185f6cd9358146f2479dde41dbb85ced5859c845a065cb5bdc42b",
to: "0xad5e2d5cb93f098423597c891d2f1ed35f904ca1",
transactionIndex: 0,
v: "0x2a",
value: 0
}
{
区块散列:“0xEAD9335751DBB4A874B2BB48AC15DDAFBEC6F2BA55A5932BF6EC1A0475166E7”,
区块编号:3026266,
发件人:“0x0d6883a0e7071513c7d90a27bf2715bc71ecf107”,
煤气:309588,
加斯普里斯:180亿,
散列:“0xe69d8b108af59198857dd5b045769748dbe1ca3ad9bba7dbbb512643b9d85b5a”,
输入:"0x03E63BDB0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000890000000B000000012E507FE5CE2F1C2A520A265F593C08372834FEC925F54BBE5A72793EC5096D03FD11970AFED8B767ADFED60CAF3F00DBDA06D48F9AFC661717DBF85641B3F011114D3A41BF16A8D8CC339ABEA14EFB14487C80B333707202D1BDEA56F75616202491B4BCC437B6A5B7A79284A08E28BCD0A90E3D87BF1000000000000000“,
暂时:129,
r:“0xDD4FE550275BD35FFD4BABF6AC357857559401F027923046DA78A7B179FFB66”,
s:“0x2584e1f3f36185f6cd9358146f2479dde41dbb85ced5859c845a065cb5bdc42b”,
致:“0xad5e2d5cb93f098423597c891d2f1ed35f904ca1”,
transactionIndex:0,
v:“0x2a”,
数值:0
}
然后使用事务详细信息和ethereumjs-tx创建一个transaction
const EthereumTx = require('ethereumjs-tx')
const test_arr1 = {
nounce: "0x"+parseInt(0, 10).toString(16),
gasPrice: "0x"+parseInt(18000000000, 10).toString(16),
gasLimit: "0x"+parseInt(90000, 10).toString(16),
to: '0x487f5eea74ea5f3e94093d8b0501f1d2b0d5310a',
value: "0x"+parseInt(1000000000000000000, 10).toString(16),
data: '0x',
v: '0x10f469',
r: '0x826b5348acbec72bab39c5debc8493e34d23b351bc7c20ded25d2a4eed736093',
s: '0x2a87e18b22c76d61ce9d6a4d56949afa025f1611aa6bb9fd9d6c502d61f7361b'
}
const tx = new EthereumTx(test_arr1);
const recoveredAddress = "0x"+tx.getSenderAddress().toString('hex')
recoveredAddress is 0x81c24515cdf1a4b68f34e3e2824d44b28d00f010 which is correct
const EthereumTx = require('ethereumjs-tx')
const test_arr2 = {
nounce: "0x"+parseInt(129, 10).toString(16),
gasPrice: "0x"+parseInt(18000000000, 10).toString(16),
gasLimit: "0x"+parseInt(309588, 10).toString(16),
to: '0xad5e2d5cb93f098423597c891d2f1ed35f904ca1',
value: "0x",
data: '0x03e63bdb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000890000000b000000012e507fe5cce2f11c2a520a265f593c08372834fec925f84bbe5a72793ec5096d03fd11970afed8b767adfed60caf3f0c1de0dbda06d48f9afc3661717dbf85641b3f011114d3a41bf16a8d8cc33769aba2abe14efb14487295c80da13b3e333707202d1bdea56f75616202491b4bcc437b6a5b7a79284a08e28bcd0a90e3d87bf10000000000000000000000000000000000000000000000',
v: '0x2a',
r: '0xdd4fe550275bd35ffd4babf6ac3578575594011f027923046da78a7b179ffb66',
s: '0x2584e1f3f36185f6cd9358146f2479dde41dbb85ced5859c845a065cb5bdc42b',
chainId: 3
}
const tx2 = new EthereumTx(test_arr2);
const recoveredAddress = "0x"+tx2.getSenderAddress().toString('hex')
recoveredAddress is 0x9c9d4315824275f545b2e96026a7075f75125b9b which is NOT correct. It should be 0x0d6883a0e7071513c7d90a27bf2715bc71ecf107
常量EthereumTx=require('ethereumjs-tx')
常数测试_arr2={
名词:“0x”+parseInt(129,10)。toString(16),
加斯普里斯:“0x”+parseInt(18000000000,10)。toString(16),
gasLimit:“0x”+parseInt(309588,10).toString(16),
至:“0xad5e2d5cb93f098423597c891d2f1ed35f904ca1”,
值:“0x”,
数据:“0x03E63BDB0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000890000000B000000012E507FE5CE2F1C2A520A265F593C0C08372834FEC925F85BBE5A72793EC5096D03FD11970AFED8BF767ADFED60CAF3F00CF6D4F9AFC661717DBF85629541B3F011114D3A41BF16A8D8CC33769ABEA14EFB14487C80DA13E333707202D1BDEA56F7566202491B4BCC437B6A5B7A79284A08E28BCD0A90E3D87BF1000000000000000',
v:'0x2a',
r:'0xDD4FE550275BD35FFD4BABF6AC357857559401F027923046DA78A7B179FFB66',
s:'0x2584e1f3f36185f6cd9358146f2479dde41dbb85ced5859c845a065cb5bdc42b',
链号:3
}
常数tx2=新以太坊TX(测试2);
const recoveredAddress=“0x”+tx2.getSenderAddress().toString('hex')
恢复的地址为0x9C9D431582475F545B2E96026A7075F75125B9B,该地址不正确。该地址应为0x0d6883a0e7071513c7d90a27bf2715bc71ecf107
为什么呢?
如何正确地重新创建原始事务
或者是否有任何其他方式验证带有v、r、s签名的交易
提前感谢。如果您使用的是web3js v1.0,您只需使用即可。他们文档中的示例:
web3.eth.accounts.recover({
messageHash: '0x1da44b586eb0729ff70a73c326926f6ed5a25f5b056e7f47fbc6e58d86871655',
v: '0x1c',
r: '0xb91467e570a6466aa9e9876cbcd013baba02900b8979d43fe208a4a4f339f5fd',
s: '0x6007e74cd82e037b800186422fc2da167c747ef045e5d18a5f5d4300f8e1a029'
})
> "0x2c7536E3605D9C16a7a3D7b1898e529396a65c23"
另一个选项是,您可以在使用Solidity的ecrecover()
的合同中调用视图
函数
ecrecover(字节32哈希,uint8 v,字节32 r,字节32 s)返回(地址):从椭圆曲线签名中恢复与公钥关联的地址,错误时返回零
例如:
function verify(bytes prefix, bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) external pure returns(address) {
bytes32 prefixedHash = keccak256(prefix, msgHash);
return ecrecover(prefixedHash, v, r, s);
}
但是,您必须小心使用前缀。不同的客户端可能使用不同的前缀。例如,geth
使用prefix=“\x19Ethereum签名消息:\n32”对事务进行签名“
谢谢您的回复。在这种情况下,msgHash是什么?看起来hash和blockHash不是一个…而是你签名的消息的sha3散列。顺便说一句,你最初的方法也没有什么问题。我运行了您的签名发送并返回了正确的地址:>signed.getSenderAddress().toString('hex');'0d6883a0e7071513c7d90a27bf2715bc71ecf107'。也许是因为你在你的对象中拼错了“nonce”?是的,你是对的!这是因为我的打字错误。谢谢