# 使用 Foundry 或 Hardhat 部署合约

> 原文地址: https://docs.blockvectra.com/zh/guides/deploy-contract/

## 选择网络

按目标链的接入指南（从[支持的链](https://docs.blockvectra.com/zh/chains/)进入）创建 `network.mjs` 并导出 `RPC_URL` 与 `CHAIN_ID`。链指南从 [GET /v1/chains](https://api.blockvectra.com/v1/chains) 读取 chain ID 与方法策略，并说明 gas 代币、是否需要另用支持广播的 RPC 以及链特有的部署设置。

选择下方一种工具。两者部署同一个无构造参数的小合约。

部署地址需要所选网络的原生 gas 代币。在本地环境安全设置 `DEPLOYER_PRIVATE_KEY`，不要提交私钥。以下命令会广播交易并花费 gas。

创建无构造参数的 `Hello.sol`：

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract Hello {
    event Ping(address indexed sender);
    function ping() external { emit Ping(msg.sender); }
    function hello() external pure returns (string memory) {
        return "hello";
    }
}
```

### Foundry

在已初始化的 Foundry 项目中，将合约放到 `src/Hello.sol`，使用以下 `foundry.toml`：

```toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.24"
evm_version = "paris"

[rpc_endpoints]
target = "${RPC_URL}"
```

```bash
: "${RPC_URL:?Set RPC_URL}" "${CHAIN_ID:?Set CHAIN_ID}" "${DEPLOYER_PRIVATE_KEY:?Set deployer key}"
test "$(cast chain-id --rpc-url "$RPC_URL")" = "$CHAIN_ID" || exit 1
forge build
forge create src/Hello.sol:Hello --rpc-url target \
  --chain "$CHAIN_ID" --private-key "$DEPLOYER_PRIVATE_KEY" --broadcast
```

记录交易哈希与部署地址。从部署输出设置 `TX_HASH` 和 `CONTRACT_ADDRESS`，用 `cast receipt "$TX_HASH" --rpc-url "$RPC_URL"` 检查上链与状态，再用 `cast call "$CONTRACT_ADDRESS" "hello()(string)" --rpc-url "$RPC_URL"` 读取合约。

### Hardhat 2 与 ethers 6

在独立的 CommonJS 项目中运行 `npm init -y`，安装 `npm install --save-dev hardhat@2 @nomicfoundation/hardhat-ethers@3 ethers@6`。将同一份合约放到 `contracts/Hello.sol`，参数保存为 `hardhat.config.cjs`：

```js
require('@nomicfoundation/hardhat-ethers');
const { RPC_URL, CHAIN_ID, DEPLOYER_PRIVATE_KEY } = process.env;
if (!RPC_URL || !/^[1-9][0-9]*$/.test(CHAIN_ID ?? '') || !DEPLOYER_PRIVATE_KEY) {
  throw new Error('Set RPC_URL, CHAIN_ID and DEPLOYER_PRIVATE_KEY');
}
module.exports = {
  solidity: { version: '0.8.24', settings: { evmVersion: 'paris' } },
  networks: {
    target: { url: RPC_URL, chainId: Number(CHAIN_ID), accounts: [DEPLOYER_PRIVATE_KEY] },
  },
};
```

创建 `scripts` 目录，保存为 `scripts/deploy.cjs`：

```js
const { ethers } = require('hardhat');
async function main() {
  const contract = await ethers.deployContract('Hello');
  console.log(contract.deploymentTransaction().hash);
  await contract.waitForDeployment();
  console.log(await contract.getAddress());
}
main().catch(error => { console.error(error); process.exitCode = 1; });
```

```bash
npx hardhat compile
npx hardhat run scripts/deploy.cjs --network target
```

网络参数中的 `chainId` 用于校验 RPC。参数参考 [Hardhat 2 网络参数](https://v2.hardhat.org/hardhat-runner/docs/config)与 [Foundry 参数](https://www.getfoundry.sh/config/index.html)（访问日期：2026-10-07）。

## 读取事件

将 `LOG_ADDRESS` 设为部署地址。调用 `ping()` 后，按目标链指南里的事件读取方式（WebSocket 订阅或 HTTP 分段轮询，取决于该链 `/v1/chains` 的 `ws` 字段）读取 `Ping` 事件。
