> For the complete documentation index, see [llms.txt](https://docs.goassay.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.goassay.ai/developers/zh/can-kao/smart-contracts.md).

# 智能合约

查阅 Assay 托管、质押和配置合约的角色、事件及限制。

Assay 合约在 **Robinhood Chain** 上持有客户资金和提供方质押，并规定谁能支出、收款、退款或罚没这些资金。结果检查在链下完成；合约执行其接受的已签名付款和罚没指令。

**地址：请查看 Assay 应用。** 付款和质押使用 **USDG**。准备交易前，请读取已部署合约的当前设置。

## 合约

| 合约            | 职责                                 | 常用读取函数                                                                                                                 |
| ------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `AssayEscrow` | 客户充值、账户上限、支付密钥权限、签名付款、付款暂扣和提取。     | `escrowOf`、`held`、`delegationOf`、`delegatesOf`、`effectiveCapsOf`、`DOMAIN_SEPARATOR`                                    |
| `AssayStake`  | 提供方存入质押、解除质押、罚没预留、争议和罚没执行。         | `stakeOf`、`bondedOf`、`withdrawableOf`、`slashRecordOf`、`DOMAIN_SEPARATOR`                                               |
| `AssayConfig` | 共享参数、暂停状态、被阻止账户、验证方注册表和角色分配。不持有代币。 | `params`、`owner`、`admin`、`arbiter`、`paused`、`blocked`、`verifierKey`、`canSign`、`slashDelaySeconds`、`collectHoldSeconds` |

三个合约都使用可升级 UUPS 代理。配置合约所有者授权升级并任命管理员。升级权与日常管理权限相互独立。

## 主要函数和事件

### 客户资金和支付密钥

委托密钥是钱包授权的支付密钥，可在上限和有效期内为付款签名。它不能提取资金，也不能修改账户权限。

| 函数                                                     | 使用者及作用                               | 主要事件                                                   |
| ------------------------------------------------------ | ------------------------------------ | ------------------------------------------------------ |
| `deposit(amount)`、`depositFor(...)`                    | 出资方将已批准的代币转入自己或其他客户的托管余额。            | `Deposited`                                            |
| `setLimits(maxVoucherAmount, maxPerWindow)`            | 客户设置账户上限。上限为零会拒绝付款。                  | `EscrowLimitsSet`；保留先前上限时还有 `CapsHeld`                 |
| `setLimitsBySig(...)`                                  | 任何人均可转发客户签署的上限变更。                    | 与 `setLimits` 相同                                       |
| `authorizeDelegate(...)`、`authorizeDelegateBySig(...)` | 客户授权或更新密钥；任何人均可转发签名形式。               | `DelegateAuthorized`、`DelegateUpdated`，可能还有 `CapsHeld` |
| `revokeDelegate(delegate)`、`revokeDelegateBySig(...)`  | 客户直接撤销密钥，或通过任何人可转发的签名消息撤销。先前权限有收紧延迟。 | `DelegateRevoked`、`CapsHeld`                           |
| `requestWithdraw(amount)`、`requestWithdrawBySig(...)`  | 客户直接或通过任何人可转发的签名消息，开始提取等待。           | 带 `availableAt` 的 `WithdrawRequested`                  |
| `withdraw()`                                           | 客户将到期待领取金额提取到自己钱包，最多为剩余余额。           | `EscrowWithdrawn`                                      |

### 等待收款的暂扣付款

Solidity 付款指令名为 `Voucher`。它绑定付款方、提供方、金额、资源哈希、请求哈希、序号和签发 / 到期时间。其 EIP-712 域绑定网络和托管合约。通常由 `assay-mcp` 构建并签名。

| 函数                                                               | 权限和作用                                               | 主要事件                                                               |
| ---------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------ |
| `redeemVoucher(v, sig)`                                          | 仅限兑付方。检查签名、序号、时间窗口、账户和密钥上限、提供方质押及客户余额。创建暂扣付款。       | `VoucherRedeemed`、`PaymentHeld`；密钥签名付款还有 `DelegateVoucherRedeemed` |
| `redeemVoucherBatch(vs, sigs)`                                   | 同样的检查，以原子方式应用于整批。                                   | 每笔付款发出相同事件                                                         |
| `collectHeld(payer, seq)`                                        | 兑付方可在 `collectableAt` 后调用；额外超时后任何人可调用。支付提供方份额和金库费用。 | `HeldCollected`                                                    |
| `refundHeld(payer, seq)`                                         | 仅限兑付方，且必须在退款截止时间前。将全额恢复到客户托管余额。                     | `HeldRefunded`                                                     |
| `collectHeldBatch(payers, seqs)`、`refundHeldBatch(payers, seqs)` | 原子批量形式，权限和时间规则相同。                                   | 每笔付款发出相同事件                                                         |

`VoucherRedeemed` 记录兑付进入暂扣。用 `HeldCollected` 确认向提供方付款，用 `HeldRefunded` 确认退回客户托管余额。退款不会补回链上支出窗口额度。

### 提供方质押和罚没

罚没是从提供方质押中扣除的处罚。提出罚没会预留质押；执行才会转移资金。提议需要已注册验证方的签名。

| 函数                                                         | 权限和作用                                               | 主要事件                  |
| ---------------------------------------------------------- | --------------------------------------------------- | --------------------- |
| `depositStake(amount)`、`depositStakeFor(provider, amount)` | 为自己或其他提供方的质押注资。                                     | `StakeDeposited`      |
| `requestUnstake(amount)`                                   | 提供方将已绑定质押移入等待池，并重新开始解绑计时。                           | `UnstakeRequested`    |
| `withdrawStake(amount)`                                    | 提供方将已到期且未预留的质押提取到自己钱包。                              | `StakeWithdrawn`      |
| `proposeSlash(attestation, sig)`                           | 任何人均可提交有效的、由验证方签署的数据失败证明。检查罚没上限并预留可用质押。             | `SlashProposed`       |
| `executeSlash(requestId)`                                  | 保存的延迟结束后，记录待处理且仍在执行窗口内时，任何人可调用。重新检查验证方，并应用提供方和密钥上限。 | `SlashExecuted`       |
| `disputeSlash(requestId)`                                  | 指定提供方可在 `executableAt` 前调用一次。冻结执行。                  | `SlashDisputed`       |
| `upholdSlash(requestId)`                                   | 仲裁人将争议记录恢复为待处理。执行仍需单独调用。                            | `SlashUpheld`         |
| `cancelSlash(requestId)`                                   | 管理员或仲裁人释放预留。                                        | `SlashCancelled`      |
| `expireSlash(requestId)`                                   | 任何人可释放已过期、争议超时未决或验证方已无法签名的记录。                       | 带原因的 `SlashCancelled` |
| `disputeSlashBatch`、`upholdSlashBatch`、`cancelSlashBatch`  | 这些操作的原子批量形式，调用方规则相同。                                | 每条记录发出相同事件            |

计算和钱包步骤见[链上质押与处罚](/developers/zh/shang-jia-ni-de-api-jin-jie/staking-and-penalties.md)和[在链上申诉质押处罚](/developers/zh/shang-jia-ni-de-api-jin-jie/dispute-a-stake-penalty.md)。

### 配置和角色

| 角色或函数                                             | 权力                         | 主要事件                                          |
| ------------------------------------------------- | -------------------------- | --------------------------------------------- |
| 所有者：`setAdmin`、代理升级                               | 任命管理员并授权升级。                | `AdminSet`、代理的 `Upgraded`                     |
| 管理员：`updateConfig`                                | 在合约边界内设置金库、兑付方、费用、质押和罚没参数。 | `ConfigUpdated`                               |
| 管理员：`setPaused`                                   | 暂停或恢复受保护操作。                | `PauseToggled`                                |
| 管理员：`registerVerifier`、`revokeVerifier`           | 管理其罚没证明可被接受的密钥。            | `VerifierRegistered`、`VerifierRevokedEvent`   |
| 管理员：`setArbiter`、`setSlashDelay`、`setCollectHold` | 选择争议仲裁人，设置新记录的时间参数。        | `ArbiterSet`、`SlashDelaySet`、`CollectHoldSet` |
| `setBlocked`                                      | 管理员可阻止或解除阻止；仲裁人只能阻止。       | `BlockedSet`                                  |

管理员不能是未撤销的验证方。仲裁人不能是管理员、兑付方或未撤销的验证方。验证方签署罚没证据；兑付方提交付款和暂扣退款；仲裁人裁决质押争议。

## 暂停和被阻止账户

暂停会停止托管充值、上限变更、提取请求和领取、新密钥授权、付款兑付及收款。质押存入、解除质押、提取、罚没提议和执行也会停止。受保护的托管和质押资金操作还会检查相关账户是否被阻止。

暂停期间，密钥撤销、暂扣退款、质押争议、裁决、取消和过期处理仍可用。这些操作降低权限或改变预留，不会向外支付资金。暂停和阻止本身不会转移资金。

## 限额和时间

以下是合约边界和默认值，并非部署选用的费用或质押要求。一个基点（bps）是一个百分点的百分之一。

| 设置             | 边界或默认值                                                 |
| -------------- | ------------------------------------------------------ |
| 收款暂扣期          | 默认 3,600 秒；可配置为 60–86,400 秒；逐笔付款冻结。                    |
| 公开收款和退款截止时间    | `collectableAt` 加 7 天。退款在该时刻关闭。                        |
| 客户提取等待         | 3,600 秒。                                               |
| 降低上限或撤销的收紧延迟   | 3,600 秒；密钥权限绝不会延续到原有效期之后。                              |
| 付款指令有效期        | 最多 300 秒；允许最多 120 秒未来时钟容差；到期后兑付宽限为 1,800 秒。            |
| 序号             | 非零，严格大于上次兑付值；最大跳跃为 1,000,000。允许跳号。                     |
| 托管和密钥上限        | 单次调用和窗口上限同时适用。窗口计数器在 24 小时内逐步回落；不是固定午夜重置，也不是精确的过去时段总额。 |
| 密钥权限           | 最多 365 天；每个付款方最多列出 16 个密钥。                             |
| 兑付、暂扣付款和质押操作批次 | 1–64 项；需要时数组必须对应。一个无效项会回滚整批。                           |
| 平台抽成比例         | 最多 3,000 bps（30%）。实际比例请读取 `params()`。                  |
| 解绑期            | 可配置为 11–30 天。                                          |
| 罚没提议延迟         | 默认 72 小时；可配置为 10 分钟至 22 天；逐条记录冻结。                      |
| 罚没执行宽限         | 从 `executableAt` 起 7 天。                                |
| 未决质押争议超时       | 从 `disputedAt` 起 30 天。                                 |
| 罚没证明有效期        | 最多 7 天。                                                |
| 验证方密钥有效期       | 最多 365 天。                                              |
| 提供方罚没上限        | 可配置，非零，最多为承担风险的质押基数的 5,000 bps（50%）；执行时也必须符合验证方当前每日上限。 |

<details>

<summary>可选：签名和计数器详情</summary>

EIP-712 域名为 `Assay Settlement`，版本为 `2`。托管和质押使用不同验证合约。从相关代理读取 `DOMAIN_SEPARATOR`。转发的客户权限变更共享授权随机数，并带有截止时间；这些与付款序号分开。

链上窗口计数器线性衰减，并向上取整。在任意 24 小时间隔内，它可能允许达到名义窗口上限两倍的支出。本地 MCP 的滚动支出记录是独立防护。`effectiveCapsOf` 包含临时保留的先前上限权限；新调用准入必须改用当前权限和撤销状态。

</details>

## 错误

| 合约错误                                                                  | 含义                | 下一步处理                     |
| --------------------------------------------------------------------- | ----------------- | ------------------------- |
| `ProgramPaused`、`AddressBlocked`                                      | 受保护操作已冻结。         | 读取当前配置和账户状态。              |
| `NotRedeemer`                                                         | 调用方不能提交该付款操作。     | 使用指定兑付方流程。                |
| `VoucherSeqNotIncreasing`、`VoucherExpired`                            | 付款序号或时间不再符合要求。    | 签署替代付款前，先核对现有调用。          |
| `VoucherExceedsPerCallLimit`、`EscrowWindowLimitExceeded`              | 账户上限拒绝兑付。         | 读取当前和保留的上限，以及支出计数器。       |
| `DelegateVoucherExceedsPerCallLimit`、`DelegateWindowLimitExceeded`    | 密钥上限拒绝兑付。         | 检查获授权密钥的上限。               |
| `ProviderBelowMinimumStake`、`EscrowInsufficient`                      | 质押或余额过低。          | 补足所需质押或客户余额。              |
| `HeldNotYetCollectable`、`HeldRefundWindowClosed`、`HeldPaymentNotHeld` | 时间或暂扣付款状态不符合操作要求。 | 重试前读取 `held(payer, seq)`。 |
| `SlashNotYetExecutable`、`DisputeWindowClosed`、`SlashNotPending`       | 罚没时间或状态不符合要求。     | 读取 `slashRecordOf`。       |
| `SlashWindowNotDrained`                                               | 整笔预留罚没尚不能符合执行上限。  | 等待额度恢复；不要拆分记录。            |
| `EmptyBatch`、`BatchTooLarge`、`BatchLengthMismatch`                    | 批量大小或数组对应关系无效。    | 修正批次后重新提交。                |

## 延伸阅读

* [结算与保留期](/developers/zh/di-ceng-yuan-li/settlement.md)
* [安全模型](/developers/zh/shi-yong-gong-ju-jin-jie/security-model.md)

## 下一步

* [MCP 工具](/developers/zh/can-kao/mcp-tools.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.goassay.ai/developers/zh/can-kao/smart-contracts.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
