> For the complete documentation index, see [llms.txt](https://docs.qms.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.qms.finance/for-developers/deploy-a-smart-contract.md).

# Deploy a smart contract

Deploying to QMS is deploying to any EVM chain: point your tool at the QMS RPC endpoint and pay the fee in QMS. This page walks through a first deployment with Foundry and with Hardhat, using each tool's sample project.

## Prerequisites

* An account with test QMS for the deployment fee. See [Make your first transaction](/onboarding/make-your-first-transaction.md) for the faucet.
* The private key of that account, kept in a `.env` file that is never committed. Use a throwaway account for the testnet.
* [Foundry](https://book.getfoundry.sh/getting-started/installation) or [Hardhat](https://hardhat.org/docs/getting-started) installed.

The network values you need are the RPC URL `https://rpc.testnet.qms.finance` and the chain ID `19480`; see [Network and RPC](/for-developers/network-and-rpc.md).

{% tabs %}
{% tab title="Foundry" %}
**Create a project**

```bash
forge init qms-tutorial
cd qms-tutorial
```

`forge init` sets up a sample contract, test, and script for `Counter.sol`.

**Store your private key**

Create a `.env` file, add it to `.gitignore`, and put your key in it:

```bash
PRIVATE_KEY=YOUR_PRIVATE_KEY
```

Then load it:

```bash
source .env
```

**Deploy**

```bash
forge create --rpc-url https://rpc.testnet.qms.finance \
  --private-key $PRIVATE_KEY \
  --broadcast \
  src/Counter.sol:Counter
```

Your output should look similar to:

```
Deployer: 0xYOUR_ADDRESS
Deployed to: 0xCONTRACT_ADDRESS
Transaction hash: 0xTRANSACTION_HASH
```

To avoid repeating the URL, add the endpoint to `foundry.toml`:

```toml
[rpc_endpoints]
qms_testnet = "https://rpc.testnet.qms.finance"
```

and deploy with `--rpc-url qms_testnet`.
{% endtab %}

{% tab title="Hardhat" %}
This is Hardhat 3. Hardhat 2 uses a different configuration format and is documented at [v2.hardhat.org](https://v2.hardhat.org).

**Create a project**

```bash
mkdir qms-tutorial && cd qms-tutorial
npx hardhat --init
```

Accept the defaults. You get a sample `Counter.sol`, its tests, and a deployment module at `ignition/modules/Counter.ts`.

**Store your private key**

Hardhat 3 resolves secrets through configuration variables, backed by an encrypted keystore rather than a file in the project:

```bash
npx hardhat keystore set QMS_PRIVATE_KEY
```

**Add QMS Testnet to the configuration**

Add a `networks` entry to `hardhat.config.ts`, and a chain descriptor naming the explorer, which is what lets the same configuration verify the contract later:

```typescript
import { configVariable, defineConfig } from "hardhat/config";

export default defineConfig({
  // ...generated plugins and solidity settings
  networks: {
    qmsTestnet: {
      type: "http",
      chainType: "l1",
      url: "https://rpc.testnet.qms.finance",
      chainId: 19480,
      accounts: [configVariable("QMS_PRIVATE_KEY")],
    },
  },
  chainDescriptors: {
    19480: {
      name: "QMS Testnet",
      blockExplorers: {
        blockscout: {
          name: "QMSScan",
          url: "https://testnet.qmsscan.io",
          apiUrl: "https://testnet.qmsscan.io/api",
        },
      },
    },
  },
});
```

**Deploy**

```bash
npx hardhat ignition deploy ignition/modules/Counter.ts --network qmsTestnet
```

Ignition asks for the keystore password, then prints the deployed address when the deployment completes.
{% endtab %}
{% endtabs %}

## After deploying

Paste the contract address into the [block explorer](https://testnet.qmsscan.io) to see the creation transaction and the contract's code.

Verification goes through Blockscout's standard verifier, which needs no API key:

* **Foundry**: `forge verify-contract --verifier blockscout --verifier-url https://testnet.qmsscan.io/api <ADDRESS> src/Counter.sol:Counter`
* **Hardhat**: `npx hardhat verify blockscout --network qmsTestnet <ADDRESS>`, which reads the explorer from the `chainDescriptors` entry above. Passing `--verify` to `hardhat ignition deploy` verifies as part of the deployment instead.

Hardhat takes constructor arguments after the address, in order. Foundry takes them ABI-encoded through `--constructor-args`, for example `--constructor-args $(cast abi-encode "constructor(uint256)" 42)`.

Set the compiler's EVM target to the hard fork level listed on [EVM Compatibility](/for-developers/evm-compatibility.md).

*Parts of this page are adapted from the* [*Linea documentation*](https://docs.linea.build) *(Apache License 2.0).*
