Ethereum Asked by coder123 on December 7, 2021
I am using ethers to get a signed request. I have a signature for the address 0x518171C334AD3adc1cF990A884D67963201B675F
.
It is, c4b71f516c36468022d61b0e22016c6bc69bc2c99666fb7e63e3d04841c82ff53d5c687ebe43b290d03caa6766e8e957192faa6b360f4102b536c54c3318304f1b
.
When I use ethers.js, to serialize my transaction with my signature I get a transaction which is something like
0xf86a808477359400825208943e245df5a4de41e65cecd1f98b96ca06c3d319f087470de4df8200008029a0c4b71f516c36468022d61b0e22016c6bc69bc2c99666fb7e63e3d04841c82ff5a03d5c687ebe43b290d03caa6766e8e957192faa6b360f4102b536c54c3318304f
As it is an ECDSA signature, it keeps on changing every time I generate it. And every time I try to decode the serialized transaction I get a different from address.
This means that there must be something wrong in how I am using the function.
This is the code I am working with, with one of the signatures that I have generated (mentioned above)
const { utils } = require('ethers');
const bn = require('bignumber.js');
const { serializeTransaction, parseEther } = utils;
const tx2 = require('ethereumjs-tx');
async function serialize1() {
const wei = parseEther('0.02');
console.log(wei);
const gasPrice = '0x' + (2000000000).toString(16);
console.log(gasPrice);
const tx = {
gasPrice: gasPrice,
gasLimit: 21000,
to: '0x3e245df5a4de41e65cecd1f98b96ca06c3d319f0',
value: wei,
nonce: 0,
data: '',
chainId: 3,
};
const serializedTransaction = await serializeTransaction(tx);
console.log(serializedTransaction);
const signature = 'c4b71f516c36468022d61b0e22016c6bc69bc2c99666fb7e63e3d04841c82ff53d5c687ebe43b290d03caa6766e8e957192faa6b360f4102b536c54c3318304f1b';
console.log('---------------------------------------------');
const signedSerialized = await serializeTransaction(tx, Buffer.from(signature, 'hex'));
console.log(signedSerialized);
}
serialize1();
When I decode this transaction, I get
{
"nonce": 0,
"gasPrice": 2000000000,
"gasLimit": 21000,
"to": "0x3e245df5a4de41e65cecd1f98b96ca06c3d319f0",
"value": 20000000000000000,
"data": "",
"from": "0x0d67ffdd9b1d8858582d903bf0093e22b9da682e",
"r": "c4b71f516c36468022d61b0e22016c6bc69bc2c99666fb7e63e3d04841c82ff5",
"v": "29",
"s": "3d5c687ebe43b290d03caa6766e8e957192faa6b360f4102b536c54c3318304f"
}
Which is clearly not the from address I want. Am I using the serialize function in the correct way? Is the encoding that I am sending the signature in correct? Any other way I can use this signature? Any other package?
Any help will be greatly appreciated!!!
You don't sign a request with a signature, you sign a transaction. You cannot generate generic signatures to be associated to transactions later on, you need to have access the complete object you want to sign - the raw transaction in your case - before the process works correctly.
Each library and wallet has its own signing implementation. With ethers.js in particular, you can use the Signer
object to sign a transaction. From the [ethers.js official documentation][1]:
signer.signTransaction( transactionRequest ) ⇒ Promise< string< DataHexString > >
Returns a Promise which resolves to the signed transaction of the transactionRequest. This method does not populate any missing fields.
Sub-classes must implement this, however they may throw if signing a transaction is not supported, which is common for security reasons in many clients.
Signer usually refers to an external wallet - i.e MetaMask - not controlled by your ÐApp.
If instead you control the wallet with your app - so not a ÐApp anymore ;) - below some examples of signing transactions and messages with ethers.js and a wallet. You can find them inside the [Wallet official documentation][2] also:
// Create a wallet instance from a mnemonic...
mnemonic = "announce room limb pattern dry unit scale effort smooth jazz weasel alcohol"
walletMnemonic = Wallet.fromMnemonic(mnemonic)
// ...or from a private key
walletPrivateKey = new Wallet(walletMnemonic.privateKey)
walletMnemonic.address === walletPrivateKey.address
// true
// The address as a Promise per the Signer API
walletMnemonic.getAddress()
// { Promise: '0x71CB05EE1b1F506fF321Da3dac38f25c0c9ce6E1' }
// A Wallet address is also available synchronously
walletMnemonic.address
// '0x71CB05EE1b1F506fF321Da3dac38f25c0c9ce6E1'
// The internal cryptographic components
walletMnemonic.privateKey
// '0x1da6847600b0ee25e9ad9a52abbd786dd2502fa4005dd5af9310b7cc7a3b25db'
walletMnemonic.publicKey
// '0x04b9e72dfd423bcf95b3801ac93f4392be5ff22143f9980eb78b3a860c4843bfd04829ae61cdba4b3b1978ac5fc64f5cc2f4350e35a108a9c9a92a81200a60cd64'
// The wallet mnemonic
walletMnemonic.mnemonic
// {
// locale: 'en',
// path: 'm/44'/60'/0'/0/0',
// phrase: 'announce room limb pattern dry unit scale effort smooth jazz weasel alcohol'
// }
// Note: A wallet created with a private key does not
// have a mnemonic (the derivation prevents it)
walletPrivateKey.mnemonic
// null
// Signing a message
walletMnemonic.signMessage("Hello World")
// { Promise: '0x14280e5885a19f60e536de50097e96e3738c7acae4e9e62d67272d794b8127d31c03d9cd59781d4ee31fb4e1b893bd9b020ec67dfa65cfb51e2bdadbb1de26d91c' }
tx = {
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
value: utils.parseEther("1.0")
}
// Signing a transaction
walletMnemonic.signTransaction(tx)
// { Promise: '0xf865808080948ba1f109551bd432803012645ac136ddd64dba72880de0b6b3a7640000801ca0918e294306d177ab7bd664f5e141436563854ebe0a3e523b9690b4922bbb52b8a01181612cec9c431c4257a79b8c9f0c980a2c49bb5a0e6ac52949163eeb565dfc' }
// The connect method returns a new instance of the
// Wallet connected to a provider
wallet = walletMnemonic.connect(provider)
// Querying the network
wallet.getBalance();
// { Promise: { BigNumber: "42" } }
wallet.getTransactionCount();
// { Promise: 0 }
// Sending ether
wallet.sendTransaction(tx)
[1]: https://docs.ethers.io/v5/api/signer/#Signer-signTransaction
[2]: https://docs.ethers.io/v5/api/signer/#Wallet--methods
Answered by Giuseppe Bertone on December 7, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP