Sign with different chainId
siquylee opened this issue · 10 comments
Thank you the great work. I signed a transaction using micro-eth-signer
library then recreated the transaction from hex
field. It threw an error 'Cannot recover signature: invalid recovery bit' when I tried to get the sender. Here is the code
let hex = "0xf86c0383023e38825208948bac311a9fb1fc90c4ab8cee1c8437087169849a8853444835ec58000080820a95a0cc6c14bf8ca2b7f864f986925e77a92b9ca4ed3ec6dde30b36500bc3a233456ea00142fa729584f570cc2c66daa11e99d6660164f27240a3e4deb6b523937629a3";
let tx = new Transaction(hex);
tx .raw.chainId = numberTo0xHex(1337);
console.log(tx );
console.log(tx .sender);
The weird thing is that I could decode the hex
to get the sender correctly with this tool that used ethereumjs-tx. I signed the transaction with the following code:
let pk = "8c6b19592316688fd537f726db8f2c2237af5cd1a0eb634efdb4bc3c3677f693";
let adr = "0x081766f51efed19582636972b461fe32f33dfab6";
const ethTx = new Transaction({
chainId: 1337,
to: "0x8bac311a9fb1fc90c4ab8cee1c8437087169849a",
gasLimit: numberTo0xHex(21000),
gasPrice: numberTo0xHex(147000),
value: numberTo0xHex(BigInt(6000000000000000000)),
nonce: numberTo0xHex(1)
} );
ethTx.raw.chainId = numberTo0xHex(1337);
let signedTx = await ethTx.sign(pk, false);
It seems that the transaction signed by chainId 1 not 1337 that caused the above error. The question is how I could set different chaindId?
tx .raw.chainId = numberTo0xHex(1337);
is incorrect/unsupported way of changing chainId. The correct way is specifying chainId when creating new Transaction
. But since you are passing hex
string, it's not an option I guess.
Thank you very much for quick response. I tried the following code but the chainId is stil 0x01.
async function testHex() {
let pk = "8c6b19592316688fd537f726db8f2c2237af5cd1a0eb634efdb4bc3c3677f693";
const ethTx = new Transaction({
chainId: 1337,
to: "0x8bac311a9fb1fc90c4ab8cee1c8437087169849a",
gasLimit: 21000,
gasPrice: 21000,
value: BigInt(6000000000000000000),
nonce: 10
});
let signedTx = await ethTx.sign(pk, false);
let hex = signedTx.hex;
console.log(hex);
// Restore the transaction from the hex value
let restoredTx = new Transaction(hex);
console.log(restoredTx.raw.chainId);
}
Did I set chainId correctly ?
You are using gasPrice, I think that makes library think you are using legacy type transaction.
If you want to use gasPrice instead of new fields, maybe pass chain name through second argument (mainnet by default).
Great, it works. Thank you very much for your hep.
I recommend using new tx type with maxFeePerGas, and maxPriorityFeePerGas, but that may not be possible with your network?
So if you use maxFeePerGas, you can pass chainId. If you use gasPrice, you should pass network name as a second argument. We map network name to chainId through some process, so maybe take a look at the code - maybe you will need to modify micro eth code to add 1337
Honestly I'm new to Ethereum & cryptography. I'm using your library to build an a blockchain education app. I start using new tx type with maxFeePerGas, and maxPriorityFeePerGas and it works fine. I have one more question. Could micro-eth-signer decode the legacy raw transaction to get the sender?
Yes
I appreciate your help much. Is this the correct way to get sender from a legacy ETH transaction.
let hex = "0xf86e8083023e3883023e38941b4e1bb8ef8c474f4d0006fb6b69e969f4042f3a890d8d726b7177a8000080820a96a0ece7c1db9395de2dab9b724809d5b1c7947c6630eee76e8c40a88eac5930d0c7a01804147852ec93bab9acb7de52c35e6e6a72052d7bc1319f7b8a37f078aa4c79";
let tx = new Transaction(hex);
console.log(tx.sender);
It's a transaction sent from Brave wallet. The correct sender/from field is 0xe3aced781d71a65226c4fbd6140a2b0253ce4e32
. When I tried to decode the sender field with your library, it threw an error Cannot recover signature: invalid recovery bit
You've forgot to pass chainId. It is used in recovering sender lubkey.
I got it. Thank you so much