# sBTC 签名者

### 概述

该 [sBTC 签名者合约](https://github.com/stacks-network/sbtc/blob/main/contracts/contracts/sbtc-bootstrap-signers.clar) (`sbtc-bootstrap-signers.clar`) 管理 sBTC 系统的签名者集合。它处理签名者密钥的轮换，并提供生成多签地址的工具。

**常量**

* `key-size`：公钥所需的长度（33 字节）。

**错误常量**

* `ERR_KEY_SIZE_PREFIX`：批处理过程中密钥大小错误的前缀。
* `ERR_KEY_SIZE` （u200）：表示提供的密钥长度不正确。
* `ERR_INVALID_CALLER` （u201）：表示函数调用者不是当前签名者主体。
* `ERR_SIGNATURE_THRESHOLD` （u202）：表示签名阈值无效（必须大于总签名者密钥的 50%，且小于或等于 100%）。

#### 公共函数

**`rotate-keys-wrapper`**

轮换签名者的密钥。在签名者集合更新时调用。

* 参数：
  * `new-keys`: `(list 128 (buff 33))` - 新签名者公钥列表
  * `new-aggregate-pubkey`: `(buff 33)` - 新的聚合公钥
  * `new-signature-threshold`: `uint` - 新的签名阈值
* 返回： `(response (buff 33) uint)`

函数流程：

{% stepper %}
{% step %}
**验证签名阈值**

确保新的签名阈值有效（必须大于总签名者密钥的 50%，且小于或等于 100%）。
{% endstep %}

{% step %}
**验证调用者**

验证调用者是否为当前签名者主体。
{% endstep %}

{% step %}
**验证密钥**

检查每个新密钥和聚合公钥的长度（必须为 33 字节）。
{% endstep %}

{% step %}
**更新注册表**

调用 sBTC Registry 合约更新密钥和地址。
{% endstep %}
{% endstepper %}

#### 只读函数

**`pubkeys-to-spend-script`**

为多签生成 p2sh 赎回脚本。

* 参数：
  * `pubkeys`: `(list 128 (buff 33))` - 公钥列表
  * `m`: `uint` - 所需签名数量
* 返回： `(buff 1024)` - p2sh 赎回脚本

**`pubkeys-to-hash`**

计算 p2sh 赎回脚本的 hash160。

* 参数：
  * `pubkeys`: `(list 128 (buff 33))` - 公钥列表
  * `m`: `uint` - 所需签名数量
* 返回： `(buff 20)` - 赎回脚本的 hash160

**`pubkeys-to-principal`**

根据一组公钥和 m-of-n 阈值生成一个主体（Stacks 地址）。

* 参数：
  * `pubkeys`: `(list 128 (buff 33))` - 公钥列表
  * `m`: `uint` - 所需签名数量
* 返回： `principal` - 生成的 Stacks 地址

**`pubkeys-to-bytes`**

将公钥列表连接成带长度前缀的缓冲区。

* 参数：
  * `pubkeys`: `(list 128 (buff 33))` - 公钥列表
* 返回： `(buff 510)` - 带长度前缀的连接公钥

**`concat-pubkeys-fold`**

将公钥缓冲区与长度前缀连接。

* 参数：
  * `pubkey`: `(buff 33)` - 单个公钥
  * `iterator`: `(buff 510)` - 用于连接的累加器
* 返回： `(buff 510)` - 更新后的连接缓冲区

**`bytes-len`**

以单个字节返回字节缓冲区的长度。

* 参数：
  * `bytes`: `(buff 33)` - 输入字节缓冲区
* 返回： `(buff 1)` - 以单个字节表示的长度

**`uint-to-byte`**

将一个 uint 转换为单个字节。

* 参数：
  * `n`: `uint` - 输入数字
* 返回： `(buff 1)` - 以单个字节表示的数字

#### 私有函数

**`signer-key-length-check`**

检查每个密钥的长度是否正好为 33 字节。

* 参数：
  * `current-key`: `(buff 33)` - 要检查的公钥
  * `helper-response`: `(response uint uint)` - 用于错误处理的累加器
* 返回： `(response uint uint)` - 更新后的累加器或错误

#### 常量

**`BUFF_TO_BYTE`**

一个常量列表，将 uint 值（0-255）映射到其对应的字节表示。

与其他合约的交互

* `.sbtc-registry`：调用 `get-current-signer-data` 和 `rotate-keys` 来管理签名者数据。

安全考虑

{% hint style="warning" %}

* 访问控制：只有当前签名者主体可以调用密钥轮换函数。
* 密钥验证：确保所有提供的密钥长度正确。
* 签名阈值：强制要求签名者最低阈值超过 50%，最高为 100%。
* 多签生成：提供安全生成多签地址的工具。
  {% endhint %}


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.stacks.co/learn/zh/sbtc/clarity-contracts/sbtc-signers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
