---
type: explanation
title: Proof of work
summary: 为什么 Caputchin 在签发一个令牌之前让浏览器做一点计算，以及那如何抬高滥用的成本。
---

每次验证都在 Caputchin 签发一个令牌之前，请访客的浏览器解一个小小的计算谜题。那个谜题就是 proof of work。

## 它如何运作

Caputchin 递给浏览器一个挑战，并请它找一个数（一个 nonce），使得当它和挑战一起被哈希时，产生一个以所要求数量的前导零开头的哈希。没有捷径：浏览器只能一个 nonce 接一个 nonce 地试，直到碰巧有一个管用。找到一个有效的 nonce 要试许多次；检查一个则是单次哈希。所以这份工作做起来难、核验起来却便宜，而 Caputchin 确认这个答案通过了所要求的难度。

## Content-Security-Policy

求解器跑在一个 Web Worker 里，组件用一个 `blob:` URL 创建它，所以嵌入页的 Content-Security-Policy 必须为 worker 允许 `blob:`（`worker-src blob:`，或作为回退链的 `child-src` / `default-src`）。这一部分是必需的：没有主线程回退，所以一个挡住 worker 的策略会挡住验证。另外，求解器为速度编译一个 WebAssembly 例程，那需要 `script-src` 里的 `'wasm-unsafe-eval'`。那一部分是可选的：没有它，同一个求解器在 Worker 里以纯 JavaScript 跑得更慢。完整的宿主页策略见 [游戏沙箱](/docs/understanding-caputchin/game-sandboxing#the-csp-you-set-on-your-own-page)。

## 为什么它阻止滥用

要点不是让任何单次求解不可能。而是让大规模的滥用不划算。

一位真实访客在零点几秒内解一个谜题，根本察觉不到。一个想发数千个请求的机器人要把那份算力成本付上数千遍。如果通过挑战的成本超过了垃圾信息的价值，这次攻击就不再有经济意义。Proof of work 把目标从“无法攻破”转向“不值得”。

## 那些旋钮

一个密钥 [安全](/docs/site-keys/security) 页上的两项设置调这个成本：

- **难度** 设定哈希必须有多少个前导零，这抬高每次求解的成本。
- **每请求挑战数** 通过一次要求好几次求解，把那个成本翻倍。

## 一个诚实的局限

没有挑战是无法攻破的；只要钱够多，任何东西都能被解。Proof of work 接受这一点，转而在成本上竞争。它也只证明了 *耗费* 了努力，而非一个真实的浏览器耗费了它，这正是 Caputchin 把它和 [探测](/docs/understanding-caputchin/instrumentation) 配对、好把环境也检查一遍的原因。
