[Ethereum] Need only sign transaction feature (not send transaction)

dappsmetamaskweb3js

I am developing an online store BNB as a payment. Customers will sign transactions using Metamask and then frontend code(js) need to post call to our backend server with the txHash, and then we will broadcast the transaction to the network using our backend service.

But I am not able to find it using web3.js( web.eth.account.signTransaction() will not work in my case as we don't customer private keys).

I Need to know how to with web3 or with Metamask js library, any example of code will be helpful.

Best Answer

Unfortunately it is not currently possible to sign a transaction without broadcasting it with Metamask. The reason behind this is that such an approach would break the current account nonce management system of Metamask. There is a Github thread about this : https://github.com/MetaMask/metamask-extension/issues/3475.

I see two ways to overcome this limitation :

  • Use the deprecated Metamask eth_sign method which enables to sign an arbitrary hash and therefore a transaction hash (this would not be possible with personal_sign which adds a specific prefix to the message before hashing it, making the signature of transactions impossible). Note that this way of doing is not very clean and could be hard to implement. Furthermore, it is very unsafe for the user who doesn't know what he is actually signing. In fact, trying to get the user to sign a transaction with eth_sign could be considered an attack.

  • Implement a meta-transaction system : A much cleaner way of doing. Ask the user to sign a message and from this message sign a transaction in your backend. I wrote a simple exemple in an answer to this post : ETH - Pre-Paid smart contract so users don't pay transactions.

Related Topic