> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tenderly.co/llms.txt
> Use this file to discover all available pages before exploring further.

# 常见问题：Virtual Environments

> 关于创建、fork 和管理 Virtual Environments 的常见问题解答，包括链 ID、时间戳、State Sync 和团队工作流。

<div className="flex flex-col gap-4 mt-8">
  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="do-i-need-a-paid-plan-to-use-virtual-environments" className="text-xl font-semibold">使用 Virtual Environments 需要付费套餐吗？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        是的。Virtual Environments 在付费套餐中提供。要为您的账户启用此功能，请[联系我们的销售团队](https://tenderly.co/contact-us)以安排通话并商讨升级方案。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-can-i-create-virtual-environments" className="text-xl font-semibold">如何创建 Virtual Environments？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        您可以通过两种方式创建 Virtual Environment：

        * 通过 [Dashboard UI](/virtual-environments/overview#quickstart)
        * 使用 [Virtual Environment REST API](/api-reference#/operations/createVnet)。
        * 通过 [fork 现有的 Virtual Environment](/virtual-environments/develop/fork-testnet)。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="why-should-i-set-a-unique-chain-id" className="text-xl font-semibold">为什么应该设置唯一的链 ID？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        请设置一个与父网络的链 ID 不同的自定义链 ID。

        建议：在原始网络的链 ID 前加上前缀 **`7357`**（*test*）。例如，如果
        您通过 fork Ethereum Mainnet（链 ID: 1）来创建 Virtual Environment，请将您的 Virtual
        Environment 链 ID 设置为类似 `73571` 的值。

        推荐此做法的原因有以下几点：

        * 由于 Virtual Environment 链独立于 Mainnet 链，因此它应具有独立且唯一的链 ID。
        * 使用唯一的链 ID 是一种**安全措施**，可保护您的 dapp 免受
          [**交易重放攻击**](https://quantstamp.com/blog/preventing-replay-attacks-post-ethereum-merge)。
        * 钱包（例如 MetaMask）会识别出**原始链 ID 已被占用**，并可能将您的 Virtual Environment 误认为
          父网络，除非它使用唯一的链 ID。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-virtual-environments-resolve-timestamps" className="text-xl font-semibold">Virtual Environments 如何解析时间戳？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        当合约中的交易或 `eth_call` 访问 **`block.timestamp`** 时，其值取决于交易目标是 `latest` 还是 `pending` 区块。

        * 对于 `pending` 区块，值为当前时间加上调整偏移量：`block.timestamp == time.now() + adjustment_offset`。
        * 对于 `latest` 区块，值为最新区块的时间戳：`block.timestamp == latest_block.timestamp`

        `adjustment_offset` 来自时间调整方法 [`evm_setNextBlockTimestamp`](/virtual-environments/admin-rpc/#evm_setnextblocktimestamp) 和 [`evm_increaseTime`](/virtual-environments/admin-rpc/#evm_increasetime)。

        [了解更多 →](/virtual-environments/develop/timestamps)
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-mining-works" className="text-xl font-semibold">挖矿如何工作？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        每当您通过 `eth_sendRawTransaction` 和 `eth_sendRawTransaction` 向 Virtual Environment 发送一笔交易时，就会挖出一个区块，区块高度增加 1。**初始区块高度**取自创建时原始链上的最新区块。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-does-state-sync-work" className="text-xl font-semibold">State Sync 如何工作？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        [State Sync](/virtual-environments/state-sync) 使 Virtual Environment 能够跟踪原始网络的实时状态。

        * 在 Virtual Environment 中的交易修改某个存储槽之前，Virtual Environment 会跟踪
          原始网络中的当前值。
        * 当 Virtual Environment 中的一笔交易修改了合约 `C` 中的存储槽 `X` 后，任何后续读取都将返回该
          值。未被修改的 `C.Y` 将反映原始网络中的值。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="why-can-t-i-see-mainnet-transactions-with-state-sy" className="text-xl font-semibold">为什么我在 State Sync 中看不到主网交易？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        State Sync 会跟踪状态，但不会同步或显示原始网络的

        * 交易
        * 事件日志
        * 区块
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="are-there-issues-with-state-sync" className="text-xl font-semibold">State Sync 是否存在问题？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        在运行 Virtual Environment 交易时，那些缓存 `block.number` 的主网合约行为难以预测，
        因为主网和 Virtual Environment 上的[区块号增长速率不同](/virtual-environments/state-sync#how-state-sync-works)。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-can-i-speed-up-passage-of-time" className="text-xl font-semibold">如何加快时间流逝？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        要更快地测试依赖当前时间戳的代码（例如收益和奖励计算），您可以使用 [`tenderly_increaseTime`](/virtual-environments/admin-rpc#evm_increasetime)。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="do-testnets-support-websockets" className="text-xl font-semibold">Virtual Environments 支持 WebSockets 吗？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        是的，Virtual Environments 支持 WebSockets。只需在 URL 中使用 `wss://` 而不是 `https://`。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="when-would-i-fork-a-testnet" className="text-xl font-semibold">我什么时候会 fork 一个 Virtual Environment？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        在部署合约并通过[为账户注资](/virtual-environments/unlimited-faucet)、[发送交易](/virtual-environments/interact/send-transactions)或使用 [Admin RPC](/virtual-environments/admin-rpc)
        设置 Virtual Environment 状态后，您可以 [fork 现有的 Virtual Environment](/virtual-environments/develop/fork-testnet)。

        * **保持起始状态完整**：通过使用 fork 出来的 Virtual Environment 进行开发或实验，您的起始点
          不会受到变更的影响。
        * **为每位团队成员提供工作副本**：在[暂存智能合约](/virtual-environments/ci-cd/stage-contracts)后，
          您的团队成员可以在自己的网络工作副本上开展工作。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-testnets-help-team-collaboration" className="text-xl font-semibold">Virtual Environments 如何帮助团队协作？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        使用 Virtual Environments 部署智能合约时，您的 [**Tenderly
        组织**](/platform/account/organizations/overview)的成员将直接拥有对该 Virtual Environment 的访问权限。

        在部署到 Virtual Environment 后，您可以分发链和合约的配置，以便其他组件（如 UI、API 和数据索引）的开发人员
        可以连接到暂存的合约。

        以下是一些建议：

        <ol className="list-decimal ml-6">
          <li> 将[合约暂存](/virtual-environments/ci-cd/stage-contracts)到 Virtual Environment。</li>
          <li> 为每个团队（前端、
          后端等）[fork 暂存的 Virtual Environment](/virtual-environments/develop/fork-testnet)，以确保团队之间的边界，
          并减少开发中的测试数据噪声。</li>
          <li> 在所有相关的 git 仓库中更新 Virtual Environment 的配置和合约信息：</li>

          <ul className="list-disc ml-3">
            <li> 链配置：共享链 ID 和 Admin RPC（以便其他开发者可以控制链状态）</li>
            <li> 合约 ABI</li>
            <li> 合约部署地址</li>
          </ul>

          <li>在本地开发（UI、后端）时，切换到 Virtual Environment。</li>
          <li>将失败的交易分享给智能合约开发者</li>
        </ol>
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-to-stage-a-dapp-for-external-demos-and-communi" className="text-xl font-semibold">如何为外部演示和社区测试暂存 dapp？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        在为外部和演示测试暂存 dapp 时，请确保：

        * 将合约暂存到 Virtual Environment。
        * 暂存所有链下组件（后端、数据索引解决方案等），并让它们连接到 Virtual Environment。
        * 通过 [**Public RPC**](/virtual-environments/overview#admin-rpc)（而不是 Admin RPC）连接您暂存的 dapp，并将其连接到其他链下组件。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-can-i-revert-testnet-state" className="text-xl font-semibold">如何回滚 Virtual Environment 状态？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        推荐的做法不是回滚状态，而是[fork 现有的
        Virtual Environment](/virtual-environments/develop/fork-testnet)，并在一次性的工作副本上进行测试。

        如果测试步骤无法通过其他方式重复，您可以[回滚 Virtual Environment 状态](/virtual-environments/develop/revert-state)。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-should-i-name-my-testnet" className="text-xl font-semibold">应该如何为我的 Virtual Environment 命名？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        为便于区分，请为您的 Virtual Environments 添加前缀 **`virtual`**（例如 `virtualMainnet`）。这
        尤其有助于与 [Viem](/virtual-environments/libraries/viem)、
        [HardHat](/virtual-environments/develop/deploy-contracts) 及
        [其他](/virtual-environments/integrations)工具进行集成。

        或者，也可以在 Virtual Environment 的名称中包含**用途**：

        * **`internalTestingMainnet`**
        * **`demoMainnet`**
        * **`dataInsightsMainnet`**
        * **`ciMainnet`**
        * **`bugBountyBase`**
        * **`frontEndDevOptimism`**
        * **`communityTestingAvalanche`**
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="what-s-verification-visibility-in-testnets" className="text-xl font-semibold">Virtual Environments 中的验证可见性是什么？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        Virtual Environment 的[公共浏览器](/virtual-environments/explorer)遵循您在 Virtual Environment
        上部署和验证的**合约的验证可见性**：

        * **Full**：公共区块浏览器将显示所有函数的完整源代码
        * **ABI-only**：公共区块浏览器仅显示函数和事件的名称与签名，
          包括参数名称。这样，您的源代码在项目外仍然不可见。
        * **None**：仅显示交易的最终结果，不会显示源代码或方法
          名称。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-do-i-run-foundry-scripts-on-virtual-environments" className="text-xl font-semibold">如何在 Virtual Environments 上运行 Foundry 脚本？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        在运行 Foundry 脚本时使用 `--slow` 标志以避免交易批量处理。使用该标志后，只有在前一笔交易被确认之后，下一笔交易才会被发送。

        ```bash lines={2} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
        forge script script/Counter.s.sol:CounterScript \
        --slow
        --verify \
        --verifier-url $TENDERLY_VERIFIER_URL \
        --rpc-url $TENDERLY_VIRTUAL_TESTNET_RPC_URL \
        --private-key $PRIVATE_KEY  \
        --etherscan-api-key $TENDERLY_ACCESS_TOKEN \
        --broadcast \
        ```
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="when-i-fund-accounts-should-i-input-the-amount-in" className="text-xl font-semibold">在为账户注资时，我应该以 wei 为单位输入金额吗？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        在 Dashboard 中使用无限水龙头（Unlimited Faucet）时，无论**原生代币或 ERC-20
        余额**，`1` 都表示 `1 ETH`。
        对于 ERC-20 代币，Tenderly 会根据 ERC-20 的小数位数自动计算精确的 wei 数量。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="what-s-the-difference-between-the-admin-rpc-and-pu" className="text-xl font-semibold">Admin RPC 与 Public RPC 有什么区别？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        **Public RPC** 支持标准的 JSON-RPC 交互。当您准备好在外部演示您的 dapp 时，
        这就是您将用于集成到 dapp UI 或后端的 RPC。

        **Admin RPC** 支持[额外的 RPC 方法](/virtual-environments/admin-rpc)，允许对网络状态和存储以及
        账户余额进行更高级别的控制。这是您在部署脚本中用于以编程方式控制网络的 RPC。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="can-i-impersonate-a-sender-on-testnets" className="text-xl font-semibold">我可以在 Virtual Environments 上模拟发送者吗？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        您可以通过 [Dashboard](/virtual-environments/interact/send-transactions#sendnig-from-the-dashboard) 使用**任意发送者地址**成功
        发送交易。Tenderly 会在 Virtual Environments 上运行这些交易，而不会检查签名。
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="how-can-i-get-accurate-gas-estimations" className="text-xl font-semibold">如何获得准确的 gas 估算？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        gas 用量反映了来自原始网络的所有 OPCODE 的准确 gas 用量。您可以通过以下方式获取 gas 用量：

        * 在 Dashboard 的 Transaction Overview 中，
        * 通过 [**tenderly\_estimateGas**](/node-rpc/rpc-reference?network=ethereum-mainnet\&method=tenderly_estimateGas) 进行 100% 精确的单笔交易估算
        * 通过 [**tenderly\_estimateGasBundle**](/node-rpc/rpc-reference?network=ethereum-mainnet\&method=tenderly_estimateGasBundle) 进行 100% 精确的多笔交易估算
      </div>
    </div>
  </Card>

  <Card>
    <div className="flex flex-col gap-2">
      <h2 id="will-verification-work-if-i-use-tenderly-setcode" className="text-xl font-semibold">如果我使用 `tenderly_setcode`，验证还能生效吗？</h2>

      <hr className="dark:border-neutral-800" />

      <div>
        当向某个地址部署经过修改的字节码时，验证信息将不再匹配，也将无法访问该目标地址的调用追踪和调试器。
      </div>
    </div>
  </Card>
</div>
