I am using HardHat and ethers to send mint transaction:

  const ABI = (await ethers.getContractFactory("MyContract")).interface

  const contract_address = "0xABCDABCD"
  const [signer] = await ethers.getSigners()

  const MyContract = await new ethers.Contract(contract_address, ABI, signer)

  tx = await MyContract.mint({ gasPrice: price * 4 })

Now I want the mint transaction to be private. The doc I found was this:

  const provider = new ethers.providers.JsonRpcProvider("https://dark-red-uranium.discover.quiknode.pro/XXXXXXX");
  const network = await provider.send("eth_sendPrivateTransaction", ["FILL_ME_ARG_1"]);

How do I send the mint transaction using this syntax?

1 Answer 1


The document stating that it requires a signed transaction. With ethers.js you should sign the transaction locally and send it. The below should work:

  provider = ethers.getDefaultProvider('http://localhost:8545')
  myWallet = new ethers.Wallet("0x59c699..sample private key...", provider)
  myAddress = await myWallet.getAddress()
  raw_tx = await MyContract.populateTransaction.mint()
  //make sure "from" is "myAddress"
  raw_tx.from = myAddress
  raw_tx = await myWallet.populateTransaction(raw_tx)
  signed_tx = await myWallet.signTransaction(raw_tx)
  console.log("signed tx ", signed_tx)
  /// Continute with your eth_sendPrivateTransaction as example in document with  "tx" is the signed_tx above
  /// For example: tx = await provider.sendTransaction(signed_tx); should work with normal provider

By looking at the populated raw tx, you can modify the gas price before it's signed, it may not be gasPrice field anymore after EIP 1559, depends on the blockchain One thing to note is that the default JsonRpcSigner may not allow signTransaction, my solution is to use Wallet of ethers to import either privatekey or some menomic to sign. Not sure if there is a cleaner way to do it.

  • When we run the 4th line raw_tx = await MyContract.populateTransaction.mint(), won't the transaction be submitted open to the blockchain? Dec 29, 2022 at 20:46
  • No, it builds your transaction locally. There is nothing to submit because it's not signed yet. You can look at how it is implemented here : github.com/ethers-io/ethers.js/blob/…
    – minhhn2910
    Dec 30, 2022 at 2:26
  • If you dont trust the library to build that for you, you can just craft your own raw transaction without calling MyContract.populateTransaction.mint(). This link ethereum.org/en/developers/docs/transactions/#the-data-field shows you how to do it, the most important thing are the to field pointing to your contract instance, and the data field must be the 4 byte encoding of the mint() function, and nonce.
    – minhhn2910
    Dec 30, 2022 at 2:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.