Proof of work
모든 검증은 Caputchin이 토큰을 발급하기 전에 방문자의 브라우저에 작은 연산 퍼즐을 풀라고 청합니다. 그 퍼즐이 proof of work입니다.
동작 방식
Caputchin은 브라우저에 챌린지를 건네고, 그것과 함께 해시됐을 때 요구되는 수의 선행 0으로 시작하는 해시를 내는 숫자(nonce)를 찾으라고 청합니다. 지름길은 없습니다: 브라우저는 하나가 우연히 맞을 때까지 nonce를 하나씩 시도해야 합니다. 유효한 nonce를 찾는 데는 많은 시도가 들고; 하나를 확인하는 것은 한 번의 해시입니다. 그래서 그 일은 하기는 어렵지만 검증하기는 싸며, Caputchin은 답이 요구된 난이도를 통과하는지 확인합니다.
Content-Security-Policy
풀이기는 위젯이 blob: URL에서 만드는 Web Worker에서 도니, 임베드하는 페이지의 Content-Security-Policy는 워커를 위해 blob:을 허용해야 합니다(worker-src blob:, 또는 대체 연쇄로 child-src / default-src). 이 부분은 필수입니다: 메인 스레드 대체가 없으니, 워커를 차단하는 정책은 검증을 차단합니다. 별도로, 풀이기는 속도를 위해 WebAssembly 루틴을 컴파일하며, 그것은 script-src에서 'wasm-unsafe-eval'을 필요로 합니다. 그 부분은 선택입니다: 그것 없이 같은 풀이기가 Worker 안에서 순수 JavaScript로 더 느리게 돕니다. 전체 호스트 페이지 정책은 게임 샌드박싱을 보세요.
왜 남용을 막는가
요점은 어떤 단일 풀이를 불가능하게 만드는 것이 아닙니다. 대규모 남용을 비경제적으로 만드는 것입니다.
진짜 방문자는 1초도 안 되는 사이에 퍼즐 하나를 풀고 결코 알아채지 못합니다. 수천 개의 요청을 쏘려는 봇은 그 연산 비용을 수천 번 치릅니다. 챌린지를 통과하는 비용이 스팸의 가치보다 더 크면, 그 공격은 재정적으로 말이 되기를 멈춥니다. Proof of work는 목표를 "깰 수 없게"에서 "할 가치가 없게"로 옮깁니다.
손잡이
키의 보안 페이지의 두 설정이 비용을 조율합니다:
- 난이도는 해시가 가져야 하는 선행 0의 수를 정하며, 각 풀이의 비용을 올립니다.
- 요청당 챌린지는 여러 풀이를 한 번에 청해 그 비용을 곱합니다.
정직한 한계
어떤 챌린지도 깰 수 없지 않습니다; 충분한 돈이 주어지면 무엇이든 풀릴 수 있습니다. Proof of work는 그것을 받아들이고 대신 비용으로 경쟁합니다. 그것은 또한 노력이 들었다는 것만 증명하지, 진짜 브라우저가 그것을 들였다는 것은 증명하지 않으며, 그래서 Caputchin은 환경도 확인하려고 그것을 계측과 짝지웁니다.