# @eth-optimism/smock 中文文档

规范地址：https://npmcn.com/package/%40eth-optimism/smock/

版本：1\.1\.10
npm 元数据更新时间：2026-07-24T15:35:20.148Z
中文译文更新时间：2026-11-14T15:34:29.698Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40eth-optimism/smock
原文对照：https://npmcn.com/package/%40eth-optimism/smock/?lang=original

弃用说明：Smock v1 is being deprecated\. Please migrate to Smock v2: https://github\.com/defi-wonderland/smock

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：72.2 kB，46 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- 运行依赖：2 个
- peer 依赖：ethers ^5，hardhat ^2，@ethersproject/abi ^5，@nomiclabs/ethereumjs-vm ^4，@nomiclabs/hardhat-ethers ^2，@ethersproject/abstract-signer ^5，@ethersproject/abstract-provider ^5
- 首次发布：2020-09-29T17:11:19.562Z
- 最新版本发布：2021-07-27T20:40:39.050Z
- 近 30 天下载量：2003（2026-10-14 至 2026-11-12，npm 官方下载统计）
- 已发布版本数：38（近 12 个月 0 个）

## 中文简介

`smock` 是一种可以生成模拟固态合同(用于测试)的通用软件包. `smock` 钩入一 `ethereumjs-vm` 实例,以便模拟合同函数可以完全用 JavaScript 写入. `smock` 目前只支持\[Hardhat\](http://har)

## 安装

```sh
npm install @eth-optimism/smock
```

也可以使用：`pnpm add @eth-optimism/smock`、`yarn add @eth-optimism/smock`、`bun add @eth-optimism/smock`

## README

# @eth-乐观主义/smock

`smock` 是一种可以生成模拟固态合同(用于测试)的通用软件包. `smock` 钩入一 `ethereumjs-vm` 实例,以便模拟合同函数可以完全用 JavaScript 写入. `smock` 目前仅支持 [哈达特](http://hardhat.org/),但将扩展用于支持其他测试框架.

在VM一级钩入的一些好处:

-   不需要因为嘲笑而部署任何特别合同!
-   所有通话都是同步的.
-   在返回值(返回一个函数)中执行任意的javascript逻辑.
-   这听起来很酷.

`smock` 还载有 `smoddit`,可以修改合同的内部存储。 我们发现这在单个合同内发生许多相互作用(通常是为了节省气体)的情况下相当有用.

## 安装

你可以轻松安装 `smock` 通过 `npm`数字 :

```sh
npm install @eth-optimism/smock
```

或者通过 `yarn`数字 :

```sh
yarn add @eth-optimism/smock
```

## 关于使用的说明 `smoddit`

`smoddit` 需要访问智能合同的内部存储布局。 团结编译器通过 `storageLayout` 旗帜,您需要启用 您的硬帽子配置.

这里有个例子 `hardhat.config.ts` 显示如何导入插件 :

```typescript
// hardhat.config.ts
import { HardhatUserConfig } from 'hardhat/config'

const config: HardhatUserConfig = {
  ...,
  solidity: {
    version: '0.7.0',
    settings: {
      outputSelection: {
        "*": {
            "*": ["storageLayout"],
        },
      },
    }
  },
}

export default config
```

## API 密码

### 职能

#### `smockit`

##### 导入

```typescript
import { smockit } from '@eth-optimism/smock'
```

##### 签署

```typescript
const smockit = async (
  spec: ContractInterface | Contract | ContractFactory,
  opts: {
    provider?: any,
    address?: string,
  },
): Promise<MockContract>
```

#### `smoddit`

##### 导入

```typescript
import { smoddit } from '@eth-optimism/smock'
```

##### 签署

```typescript
const smoddit = async (
  name: string,
  signer?: any
): Promise<ModifiableContractFactory>
```

### 类型

#### `smockit`

##### `MockContract`

```typescript
interface MockContract extends ethers.Contract {
  smocked: {
    [functionName: string]: MockContractFunction
  }

  // A wallet you can use to send transactions *from* a smocked contract
  wallet: ethers.Signer
}
```

##### `MockContractFunction`

```typescript
interface MockContractFunction {
  calls: string[]
  will: {
    return: {
      (): void
      with: (returnValue?: MockReturnValue) => void
    }
    revert: {
      (): void
      with: (revertValue?: string) => void
    }
    resolve: 'return' | 'revert'
  }
}
```

##### `MockReturnValue`

```typescript
export type MockReturnValue =
  | string
  | Object
  | any[]
  | ((...params: any[]) => MockReturnValue)
```

#### `smoddit`

##### `ModifiableContractFactory`

```typescript
interface ModifiableContractFactory extends ethers.ContractFactory {
  deploy: (...args: any[]) => Promise<ModifiableContract>
}
```

##### `ModifiableContract`

```typescript
interface ModifiableContract extends ethers.Contract {
  smodify: {
    put: (storage: any) => Promise<void>
  }
}
```

## 实例(嘲笑)

### 通过 `ethers.Contract`

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.return.with('Some return value!')

console.log(await MyMockContract.myFunction()) // 'Some return value!'
```

### 请求数

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

const MyOtherContractFactory = await ethers.getContractFactory('MyOtherContract')
const MyOtherContract = await MyOtherContract.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.return.with('Some return value!')

// Assuming that MyOtherContract.myOtherFunction calls MyContract.myFunction.
await MyOtherContract.myOtherFunction()

console.log(MyMockContract.smocked.myFunction.calls.length) // 1
```

### 调用数据

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

const MyOtherContractFactory = await ethers.getContractFactory('MyOtherContract')
const MyOtherContract = await MyOtherContract.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.return.with('Some return value!')

// Assuming that MyOtherContract.myOtherFunction calls MyContract.myFunction with 'Hello World!'.
await MyOtherContract.myOtherFunction()

console.log(MyMockContract.smocked.myFunction.calls[0]) // 'Hello World!'
```

### 返回(w/o数据)

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.return()

console.log(await MyMockContract.myFunction()) // []
```

### 正在返回 Struct

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.return.with({
    valueA: 'Some value',
    valueB: 1234,
    valueC: true
})

console.log(await MyMockContract.myFunction()) // ['Some value', 1234, true]
```

### 返回多阵列

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.return.with([
  [1234, 5678],
  [4321, 8765]
])

console.log(await MyMockContract.myFunction()) // [ [1234, 5678], [4321, 8765] ]
```

### 返回函数

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.return.with(() => {
  return 'Some return value!'
})

console.log(await MyMockContract.myFunction()) // 'Some return value!'
```

### 返回函数(w/参数)

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.return.with((myFunctionArgument: string) => {
  return myFunctionArgument
})

console.log(await MyMockContract.myFunction('Some return value!')) // 'Some return value!'
```

### 还原(w/o数据)

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.revert()

console.log(await MyMockContract.myFunction()) // Revert!
```

### 还原(w/数据)

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const MyContractFactory = await ethers.getContractFactory('MyContract')
const MyContract = await MyContractFactory.deploy(...)

// Smockit!
const MyMockContract = await smockit(MyContract)

MyMockContract.smocked.myFunction.will.revert.with('0x1234')

console.log(await MyMockContract.myFunction('Some return value!')) // Revert!
```

### B. 从毁损的合同发送交易

```typescript
import { ethers } from 'hardhat'
import { smockit } from '@eth-optimism/smock'

const myContractFactory = await ethers.getContractFactory('MyContract')
const myContract = await myContractFactory.deploy(...)

// Smockit!
const mock = await smockit('AnotherContract')

await myContract.connect(mock.wallet).doSomeFunction() // msg.sender == mock.address
```

## 实例( smoddit)

### 创建可修改的合同

```typescript
import { ethers } from 'hardhat'
import { smoddit } from '@eth-optimism/smock'

// Smoddit!
const MyModifiableContractFactory = await smoddit('MyContract')
const MyModifiableContract = await MyModifiableContractFactory.deploy(...)
```

### 正在修改 a `uint256`

```typescript
import { ethers } from 'hardhat'
import { smoddit } from '@eth-optimism/smock'

// Smoddit!
const MyModifiableContractFactory = await smoddit('MyContract')
const MyModifiableContract = await MyModifiableContractFactory.deploy(...)

await MyModifiableContract.smodify.put({
  myInternalUint256: 1234
})

console.log(await MyMockContract.getMyInternalUint256()) // 1234
```

### 修改字符串

```typescript
import { ethers } from 'hardhat'
import { smoddit } from '@eth-optimism/smock'

// Smoddit!
const MyModifiableContractFactory = await smoddit('MyContract')
const MyModifiableContract = await MyModifiableContractFactory.deploy(...)

await MyModifiableContract.smodify.put({
  myInternalStruct: {
    valueA: 1234,
    valueB: true
  }
})

console.log(await MyMockContract.getMyInternalStruct()) // { valueA: 1234, valueB: true }
```

### 修改绘图

```typescript
import { ethers } from 'hardhat'
import { smoddit } from '@eth-optimism/smock'

// Smoddit!
const MyModifiableContractFactory = await smoddit('MyContract')
const MyModifiableContract = await MyModifiableContractFactory.deploy(...)

await MyModifiableContract.smodify.put({
  myInternalMapping: {
    1234: 5678
  }
})

console.log(await MyMockContract.getMyInternalMappingValue(1234)) // 5678
```

### 修改嵌入式映射

```typescript
import { ethers } from 'hardhat'
import { smoddit } from '@eth-optimism/smock'

// Smoddit!
const MyModifiableContractFactory = await smoddit('MyContract')
const MyModifiableContract = await MyModifiableContractFactory.deploy(...)

await MyModifiableContract.smodify.put({
  myInternalNestedMapping: {
    1234: {
      4321: 5678
    }
  }
})

console.log(await MyMockContract.getMyInternalNestedMappingValue(1234, 4321)) // 5678
```

## 常见问题

### @eth-optimism/smock 是什么？

smock 是一种可以生成模拟固态合同\(用于测试\)的通用软件包\. smock 钩入一 ethereumjs-vm 实例,以便模拟合同函数可以完全用 JavaScript 写入\. smock 目前只支持\[Hardhat\]\(http://har\)注意：该包已被作者标记为弃用——Smock v1 is being deprecated\. Please migrate to Smock v2: https://github\.com/defi-wonderland/smock

### 如何安装 @eth-optimism/smock？

在项目目录运行 npm install @eth-optimism/smock，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：ethers（^5）、hardhat（^2）、@ethersproject/abi（^5）、@nomiclabs/ethereumjs-vm（^4）、@nomiclabs/hardhat-ethers（^2）、@ethersproject/abstract-signer（^5）、@ethersproject/abstract-provider（^5）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @eth-optimism/smock 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @eth-optimism/smock 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @eth-optimism/smock 可以商用吗？

@eth-optimism/smock 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @eth-optimism/smock 的下载量有多少？

根据 npm 官方下载统计，@eth-optimism/smock 在 2026/10/14 – 2026/11/12 这 30 天内被下载 2,003 次，日均约 67 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @eth-optimism/smock 还在维护吗？

最新版本 1\.1\.10 发布于 2021/07/28（5 年前）；至今共发布 38 个版本，其中过去 12 个月发布了 0 个；首次发布于 2020/09/30。作者已将其标记为弃用，新项目建议寻找替代方案。

