Skip to content
This repository has been archived by the owner on Oct 3, 2024. It is now read-only.

fix: added warning about using private keys in plaintext #1031

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/build/quick-start/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,7 @@ We provide [two different testing environments](../../build/test-and-debug/getti
By incorporating local testing into your development workflow, you can effectively verify the behavior and functionality of your contracts in a controlled environment, ensuring a smooth deployment process to the mainnet.

For detailed instructions on configuring the local testing environment and performing tests using Mocha and Chai, refer to the dedicated [Testing](../../build/test-and-debug/getting-started.md) page.

## Always use encrypted private keys

Be sure to see [private key best practices](../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.
98 changes: 98 additions & 0 deletions docs/build/support/private-key-management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
head:
- - meta
- name: "twitter:title"
content: Private Key Management | zkSync Docs
---

# Working with Private Keys

In all our tutorials and guides, we use private keys to interact with zkSync. Most tutorials use `.env` files to store private keys in "plaintext", which [is considered bad practice](https://github.com/Cyfrin/foundry-full-course-f23/discussions/5). In this guide, we'll teach you a few safer ways to manage your keys.

You can take a look at the [.env pledge](https://github.com/Cyfrin/foundry-full-course-f23/discussions/5) which is an oath developers should take before working with private keys in their development files.

The main rule of thumb, is that you should never have a private key associated with real funds in plaintext. By "in plaintext" we mean unencrypted. If you are sure that a private key has no funds and will never have funds associated with it, feel free to put that key in a `.env` file. Otherwise, head the suggestions below.

## Hardhat

For the hardhat framework, there is no built-in encryption methods for private keys, and for this reason alone foundry is preferred. They have [configuration variables](https://hardhat.org/hardhat-runner/docs/guides/configuration-variables), however, these keep your private key in plain text and just move the file location to somewhere else in your directory.

Instead, we can use javascript (or typescript) to encrypt and decrypt our keys ourselves according to [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335).

You can see the full example with [deployment in Ethers here.](https://github.com/PatrickAlphaC/ethers-simple-storage-fcc/blob/main/encryptKey.js)

`encryptKey.js`:

```javascript
const ethers = require("ethers"); // ^6.2.3 of ethers
const fs = require("fs-extra");
require("dotenv").config();

async function main() {
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY);

const encryptedJsonKey = await wallet.encrypt(process.env.PRIVATE_KEY_PASSWORD);
console.log(encryptedJsonKey);
fs.writeFileSync("./.encryptedKey.json", encryptedJsonKey);
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
```

This is a `nodejs` script you can run to encrypt your key and save it to `.encryptedKey.json`. Once you have your key encrypted, you can then decrypt it in your scripts like so:

```javascript
const ethers = require("ethers");
const fs = require("fs-extra");
require("dotenv").config();

async function main() {
const encryptedJson = fs.readFileSync("./.encryptedKey.json", "utf8");
let wallet = new ethers.Wallet.fromEncryptedJsonSync(encryptedJson, process.env.PRIVATE_KEY_PASSWORD);
}
```

::: warning
If you do this, remember to add `.encryptedKey.json` to your `.gitignore` file!
:::

## Foundry

Foundry supports [encrypting keys by default](https://www.youtube.com/watch?v=VQe7cIpaE54) by using the `cast wallet import` command. Normally, to run a foundry script, you'd run a command like so to deploy a smart contract:

```bash
forge script script/Deploy.sol --private-key $PRIVATE_KEY --rpc-url $RPC_URL
```

Where `PRIVATE_KEY` is your private key from a `.env` file. This is of course not good because once again our private key is in plaintext.

However, we can encrypt our key by running:

```
cast wallet import account_name --interactive
```

And it will drop you into a shell to import your private key. Once it's imported, you'll be able to see it with `cast wallet list`.

Then, you can run your script like so:

```bash
forge script script/Deploy.sol --account account_name --sender $WALLET_ADDRESS --rpc-url $RPC_URL
```

The [foundry documentation](https://book.getfoundry.sh/tutorials/best-practices?highlight=patrick#private-key-management) has additional notes on secure private key management.

## Your own

And of course, you can always roll your own private key solution if you choose to do so.

# Summary

1. Never have a private key associated with real funds in plaintext.
2. Ideally, use a separate wallet for testing and development.
3. If you accidentally expose a private key, consider the whole thing compromised and try to move funds to a new wallet.
6 changes: 6 additions & 0 deletions docs/build/tooling/foundry/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ contract Greeter {
forge create src/Greeter.sol:Greeter --constructor-args "Hello zkSync" --private-key <PRIVATE_KEY> --rpc-url https://sepolia.era.zksync.dev --chain 300 --zksync
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

### Deploying Factory Contracts

To deploy contracts like `GreeterFactory.sol`, use the `is-system` flag.
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tooling/hardhat/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ Rename `.env.example` to `.env` and input your private key:
WALLET_PRIVATE_KEY=YourPrivateKeyHere...
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

Your private key will be used for paying the costs of deploying the smart contract.

## Compile and deploy a contract
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tooling/hardhat/hardhat-zksync-deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ const config: HardhatUserConfig = {
};
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

- `accounts` represents a list of the private keys or mnemonic object for the account used in the deployment process.

:::tip Accounts on zkSync Era Test Node or zksync-cli Local Node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ The template provides a ready-to-use `hardhat.config.ts` file that targets zkSyn
WALLET_PRIVATE_KEY=YourPrivateKeyHere...
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

Your private key will be used for paying the costs of deploying the smart contract.

::: warning
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tutorials/how-to/deploy-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ export default async function (hre: HardhatRuntimeEnvironment) {
}
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

To deploy contract on `zkSync Sepolia Testnet` that we already specified as default network in our **hardhat.config.ts**, run command:

```bash
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tutorials/how-to/deposit-erc-20-to-l2.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ WALLET_PRIV_KEY=<YOUR_PRIVATE_KEY>
L1_RPC_ENDPOINT=<RPC_URL>
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

### Step 3: Create the Deposit Script

Create a new file `deposit-erc20.ts` and insert the below code:
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tutorials/how-to/deposit-eth-to-l2.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ WALLET_PRIV_KEY=<YOUR_PRIVATE_KEY>
L1_RPC_ENDPOINT=<RPC_URL>
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

### Step 3: Create the Deposit Script

Create a new file `deposit.ts` and insert the below code:
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tutorials/how-to/send-message-l2-l1.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ yarn add zksync-ethers@5 ethers@5 typescript @types/node ts-node
"RICH_WALLET_PRIV_KEY=0x..";
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

6. Create a `file.ts` file in the root directory with the next script:

```ts
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tutorials/how-to/send-transaction-l1-l2.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@ User needs to perform next steps:
"RICH_WALLET_PRIV_KEY=0x..";
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

4. Add script to package.json file next script:

```js
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tutorials/how-to/test-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,12 @@ describe("Greeter", function () {
});
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

Execute the following command in your terminal to run the tests:

```bash
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tutorials/how-to/transfer-token-l2.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ const zkSyncProvider = new zksync.Provider("https://sepolia.era.zksync.dev");
const zkSyncWallet = new zksync.Wallet("<SENDER-PRIVATE-KEY>", zkSyncProvider);
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

### 4. Store the recipient's public key

Save the recipient's wallet address to a variable, replacing `<RECIPIENT-PUBLIC-KEY>` with their public key.
Expand Down
4 changes: 4 additions & 0 deletions docs/build/tutorials/how-to/verify-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ To configure your private key, copy the `.env.example` file, rename the copy to
WALLET_PRIVATE_KEY=YourPrivateKeyHere....
```

::: warning
Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.
:::

Your private key will be used for paying the costs of deploying the smart contract.

Initiate contract deployment using this command:
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tutorials/how-to/withdraw-erc-20-to-l1.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ WALLET_PRIV_KEY=<YOUR_PRIVATE_KEY>
L1_RPC_ENDPOINT=<RPC_URL>
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

### Step 3: Create the Withdrawal Script

Create a new file `withdraw-erc20.ts` and insert the following code. This script utilizes the `withdraw` method from the `Wallet` class of the zkSync Javascript SDK to withdraw ETH. Adjust the `AMOUNT` and `TOKEN_ADDRESS` variable if necessary.
Expand Down
6 changes: 6 additions & 0 deletions docs/build/tutorials/how-to/withdraw-eth-to-l1.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ WALLET_PRIV_KEY=<YOUR_PRIVATE_KEY>
L1_RPC_ENDPOINT=<RPC_URL>
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

### Step 3: Create the Withdrawal Script

Create a new file `withdraw.ts` and insert the following code. This script utilizes the `withdraw` method from the `Wallet` class of the zkSync Javascript SDK to withdraw ETH. Adjust the `AMOUNT` variable if necessary.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,12 @@ Make sure you deposit funds on zkSync Era using [one of the available bridges](h

1. In the `deploy` folder, create the file `deploy-factory.ts` and copy/paste the following code, replacing `<WALLET_PRIVATE_KET>` with your private key.

::: warning
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's please update all instances where this warning should be added. I believe the other tutorials also need this warning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!


Be sure to see [private key best practices](../../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

```ts
import { utils, Wallet } from "zksync-ethers";
import * as ethers from "ethers";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,12 @@ yarn hardhat compile

2. Create a file named `deploy/deployFactoryAccount.ts`. Then, copy and paste the following code into it. Remember to add your `DEPLOYER_PRIVATE_KEY` to the .env file.

::: warning

Be sure to see [private key best practices](../../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

The script deploys the factory, creates a new smart contract account, and funds it with some ETH.

```typescript
Expand Down Expand Up @@ -825,7 +831,7 @@ export default async function (hre: HardhatRuntimeEnvironment) {
}
```

3. Run the script.
1. Run the script.

```sh
yarn hardhat deploy-zksync --script deployFactoryAccount.ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ contract Governance {
}
```

::: warning

Be sure to see [private key best practices](../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

2. Replace the code in `hardhat.config.ts` with the following:

```ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,12 @@ export default async function (hre: HardhatRuntimeEnvironment) {
}
```

:::info
Be sure to add your private key to the `.env` file.;
::: warning

Be sure to see [private key best practices](../../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

For this tutorial, we need to add your private key to a `.env` file. Please do not use a private key associated with live funds when your key is unencrypted.

:::

The provided script takes care of loading environment variables, setting up a deployment wallet with the private key specified in an `.env` file, contract deployment and funding the paymaster. You can adjust the amount of ETH to fund the paymaster to your needs.;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ describe.only("ERC20fixedPaymaster", function () {
});
```

::: warning

Be sure to see [private key best practices](../../../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

This particular script assesses the paymaster's ability to cover gas expenses for accounts, provided they hold a balance in the designated ERC20 token.

To execute test:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ export default async function (hre: HardhatRuntimeEnvironment) {
}
```

::: warning

Be sure to see [private key best practices](../../../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

:::info
Be sure to add your private key to the `.env` file.;
:::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ export default async function (hre: HardhatRuntimeEnvironment) {
}
```

::: warning

Be sure to see [private key best practices](../../../support/private-key-management.md) before working with private keys associated with real funds so you don't accidentally expose your private key.

:::

:::info
Be sure to add your private key to the `.env` file.
:::
Expand Down
Loading