TransWikia.com

Signing a request with a signature gives the wrong from address

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!!!

One Answer

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

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP