보호된 풀을 통한 불량 자금 추적
가능한 한 비밀을 유지하면서 보호된 풀을 통해 불량 자금을 추적하는 엉뚱한 아이디어를 설명하고 싶습니다.
로그라인
이블 박사는 1천억 달러를 훔쳐 개인정보 보호 프로토콜에 넣었습니다.
어떻게 된 일인지, 도난 사건과 입금은 한동안 눈에 띄지 않았고, 입금 지연 기간은 이제 끝났습니다. 돈은 시스템에 있습니다. 개인 이체가 이어지고 있습니다. 아무도 좋은 지폐와 나쁜 지폐를 구별하지 못합니다. 시대가 좋지 않습니다.
결국 누군가가 도난 사실을 알아차리고 경보를 울립니다.
사용자는 잔액에서 오염된 지폐를 어떻게 식별하나요? 개인정보 보호를 극대화하려면 어떻게 해야 하나요? 오염된 인출 내역을 어떻게 식별할 수 있나요(그리고 식별해야 하나요)?
헤드라인 목표: 다른 사람 에게 아무것도 누설하지 않고도 채권 소유자가 자신의 채권 중 얼마나 많은 부분이 "불량" 예금에서 유래했는지 파악할 수 있도록 합니다.
매우 높은 수준
사용자에게 메모가 있습니다. 메모에는 사용자가 해독할 수 없는 암호화된 정보가 포함되어 있으며, 메모에 기여한 입금 내역에 대한 정보가 포함되어 있습니다.
notes[i][j] = {owner,amount,randomness,deposits: [{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},...],}모든 것이 훌륭하고 사적입니다.
만약 얼마 후에 예금이 블랙리스트에 오르고 이 수표가 그 "불량" 예금의 후손이라면 사용자는 갑자기 다음 정보를 알게 될 것입니다.
notes[i][j] = {owner,amount,randomness,deposits: [{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},{The bad deposit_id,Some fraction to deduce how much of that 'bad' depositis contained within this note,},{ < unintelligible ciphertext > , < unintelligible ciphertext > ,},...],}그런 다음 사용자는 "오염 제거 회로"라는 극적인 이름의 명령을 실행하여 이 불량 deposit_id를 포함하지 않는 새로운 지폐를 생성할 수 있습니다.
주의 사항
아직 아무도 이 글을 읽지 않았습니다.
저는 이런 접근 방식을 옹호하는 것은 아니지만, 지금까지 해결된 적이 없는 문제를 해결하려는 재밌는 디자인입니다.
이 문서 전반에 걸쳐 (그리고 마지막에 요약되어 있는) 강력한 비판이 몇 가지 떠오릅니다.
후손들에게 참고자료로 남겨두는 게 좋을 듯합니다.
흥미로운 글이 되기를 바랍니다. 
소개
이 주제에 대한 정말 설득력 있는 소개를 원하시면 Privacy Pools 논문 의 섹션 I과 II를 읽어보세요.
제 요약은 다음과 같습니다.
일부 사람들은 블록체인 거래 시 프라이버시를 중시하기 때문에, 여러 팀이 프라이빗 블록체인 거래를 활성화하는 방법을 모색하고 있습니다. 일반적인 패턴은 다음과 같습니다.
사용자는 소위 "차폐형 토큰 풀"에 토큰을 입금할 수 있습니다. 이후 다른 주소로 토큰을 출금할 수 있습니다. 이러한 프로토콜의 목적은 입금 주소와 출금 주소 사이의 가시적인 연결을 끊는 것입니다.
일부 프로토콜은 풀에 예치된 토큰을 비공개로 전송하는 기능을 제공하기도 하는데, 이를 통해 관찰자는 누가 누구에게 무엇을 보냈는지 알 수 없습니다. 제가 가장 흥미롭게 생각하는 것은 바로 이러한 입금-송금-출금 프로토콜입니다.
이러한 모든 풀의 문제점은 악의적인 행위자들도 이를 악용할 수 있다는 점이며, 실제로 악의적인 행위자들이 이러한 풀에 불법적으로 자금을 보내는 사례가 있었습니다. 일단 자금이 입금되면 악의적인 입금을 추적하기가 더 어려워지고, 정상적인 출금과 악의적인 출금을 구분하기도 더 어려워집니다.
그래서 다양한 프로젝트가 이 문제를 해결하기 위해 노력해 왔습니다.
접근 방식은 다음과 같습니다.
- 입금 지연을 도입하여 풀에 들어가기 전에 불량 입금을 식별합니다.
- 일정 기간 동안 풀에 입금할 수 있는 금액의 제한.
- 평판이 좋은 배우의 입금만 허용합니다.
- 사용자가 나쁜 행위자와의 연관성을 끊었다는 증거나, 좋은 행위자와만 연관되었다는 증거를 제공할 수 있도록 합니다.
- 모든 거래 세부 정보를 제3자(규제 기관, 감사원, 회계사 등)에게 암호화하거나, 제3자와 열람 키를 공유합니다.
- 풀을 통한 모든 자금의 추적 가능성을 어느 정도 확보하기 위해 일부 개인정보 보호 보장을 완화합니다.
이러한 접근 방식에는 모두 흥미로운 상충 관계가 있으며, 아래에서 이에 대해 살펴보겠습니다.
제가 생각해 온 아이디어는 다음과 같습니다.
사용자에게 메모가 전송되면 메모에는 해당 메모에 가치를 기여한 모든 상위 deposit_id의 재정의된 암호화 목록과 각 입금이 메모에 기여한 가치에 대한 암호화가 포함됩니다.
이상적인 상황에서는 사용자의 메모가 " 불량 " 예금의 후손이 되지 않을 것이고, 그런 경우에는 zcash와 비슷한 수준의 개인 정보 보호가 보장되어야 합니다. 즉, 사용자는 자신의 메모에 어떤 예금이 기여했는지 알 수 없습니다.
그러나 예금이 공개적으로 "불량"으로 간주되는 경우, 이 설계는 모든 하위 채권 소유자가 해당 부실 예금 중 얼마가 자신의 채권으로 유입되었는지 확인할 수 있도록 합니다. 중요한 것은 "내 채권 중 X 금액이 이 부실 예금 ID에서 발생한 것으로 간주됨"이라는 정보 외에는 채권 소유자에게 추가 정보가 유출되지 않는다는 것입니다. 풀 관찰자는 어떠한 정보도 알 수 없습니다.
이상적으로는 불량 입금이 시스템에 유입되기 전에, 예를 들어 일정 지연 기간을 거쳐 "불량"으로 식별되고 플래그가 지정되어야 합니다. 이렇게 하면 정직한 사용자의 자금을 "손상"시킬 기회가 없어집니다. 하지만 지연 기간이 충분하지 않다면 어떨까요? 또는 실사 과정에서 뭔가를 놓쳤다면 어떨까요? 사용자 거래 내역을 유출하지 않고 이러한 입금-지연 네트워크를 통과하는 불량 자금을 식별하는 방법을 탐구하는 것이 흥미로울 것이라고 생각했습니다.
작성 후 편집: Railgun은 실제로 최근에 이 문제를 겪었습니다: https://x.com/dethective/status/1994397800847589736?s=20
우리는 이 과정에서 몇 가지 확장성 문제에 직면하게 될 것이고, 이를 완화하는 방법을 살펴볼 것입니다.
배경
용어에 맞춰서라도 UTXO 기반 개인정보 보호 프로토콜에 대해 간단히 알려드리겠습니다.
원하시면 다음 섹션인 "선행 기술"로 넘어가실 수 있습니다.
매장
개념적으로 보증금은 다음과 같습니다.
사용자가 공개 토큰을 시스템에 예치하면 예치 금액과 소유자(주소 또는 공개 키)가 포함된 노트가 생성됩니다. 이 노트는 사용자가 해당 토큰을 소유하고 있음을 나타내는 지표 역할을 하며, 시스템은 최종 소유자가 잔액을 인출하거나 이체할 때까지 해당 토큰을 풀에 보관합니다.
더 자세한 내용을 원하시면 입금 절차를 보여주는 더 자세한 다이어그램을 참조하세요. 구현 방식마다 여러 면에서 차이가 있지만, 핵심은 다음과 같습니다.
전송
개념적으로, 전송은 다음과 같습니다.
발신자가 자신의 노트 두 개를 소비(또는 "무효화")하고, 이체 수신자를 위한 노트를 생성하고, 자신을 위한 변경 노트를 생성합니다. 노트 두 개가 파기되고, 무효화 노트 두 개가 발행되고, 새로운 노트 두 개가 생성되어 발행됩니다.
무효화기가 뭔지 설명 안 할 만큼 대담해질 수 있을까? 그럴 것 같아!
아, 사실 무효화자에 대해 다음 내용을 말해야 할 것 같아요. 그러면 다음 섹션에서 접근 방식을 비판하는 데 도움이 될 거예요.
무효화(nullifier)는 개인 결제 프로토콜에서 어음을 생성한 거래와 해당 어음을 나중에 사용하는 거래 간의 연결을 끊는 데 사용됩니다. 무효화(nullifier)가 제공하는 이러한 "거래 연결 해제" 속성이 없으면 전체 거래 그래프가 관찰자에게 노출되고, 사용자는 유출되어서는 안 될 정보를 얻을 수 있습니다.
이 문서의 나머지 부분에서는 다이어그램의 무효화(nullifier)는 무시하겠습니다. 오히려 혼란만 가중시키기 때문입니다. 회로에 메모가 입력되는 것을 보면 무효화되었다고 가정해 보겠습니다.
또한, 혼란을 줄이기 위해 다이어그램의 변경 사항을 무시하겠습니다.
깔끔하게 정리: 무효화 요소가 표시되지 않으며, 변경 사항도 표시되지 않습니다.
인출
개념적으로 인출은 다음과 같습니다.
사용자가 어떤 가치가 담긴 지폐를 태우면, 시스템은(사용자가 시스템 내에서 비공개적으로 거래하는 동안 모든 공개적으로 예치된 자금을 보관함) 해당 가치를 사용자가 지정한 주소로 전송합니다.
선행 기술
논문에서 전통적으로 그렇듯이, 새로운 아이디어의 세부 사항을 탐구하기 전에 이 문서의 존재를 정당화하기 위해 기존의 모든 아이디어를 잔인하게 비판해야 합니다.
하지만 나는 부드럽게 말할 것이다. 왜냐하면:
- 기존 아이디어는 사실 꽤 괜찮았고, 실제 PMF를 통해 실제로 작동하는 제품으로 만들어졌어요. 정말 대단하네요.
- 앞으로 언제 누군가와 함께 일하게 될지 알 수 없습니다.
- 제 아이디어에는 버그가 있을 수 있습니다.
- 아이디어에 버그가 없더라도, 진행하면서 공유할 몇 가지 가혹한 비판이 생각납니다. 여러분도 이미 생각하고 있을지도 모릅니다.
나와 함께 있어.
모든 제품은 어떤 형태로든 규정을 준수하는 개인 토큰을 추구합니다. 일부는 간단한 입금-출금 방식이고, 일부는 입금-송금-출금 방식입니다. 모두 기본적으로 "배경" 섹션에 설명된 접근 방식을 따르지만, 악의적인 행위자에 대처하는 방식은 서로 다릅니다.
페이
이 제품 이름을 말로 표현할 때는 "Pay with two y"라고 해야 합니다. 안 그러면 상대방이 멍하니 쳐다볼 거예요. 아니면 "Payyyyyyy"라고 발음하면서 발음을 강조해야 합니다.
Payy는 입금-송금-출금 프로토콜입니다.
Payy는 악의적인 행위자에 대처하기 위해 매우 실용적이고 간단한 접근 방식을 취합니다. 즉, 프로토콜에서 무효화기를 제거합니다 .
차폐 프로토콜의 기본 원리를 다시 살펴보면, 무효화(nullifier)는 "거래 연결 해제(tx unlinkability)"를 제공합니다. 무효화(nullifier)가 없으면 전송 거래(tx)에 대한 입력 정보는 공개적으로 표시됩니다. 즉, 모든 거래의 출력 정보는 나중에 다른 거래의 입력 정보로 확인할 수 있습니다. 즉, Payy에서는 전체 거래 그래프를 확인할 수 있습니다.
부실 예금이 시스템에 유입되면 해당 자금의 정확한 흐름을 추적하고, 시스템에서 어떤 인출이 부실 예금에서 비롯되었는지 확인할 수 있습니다. 어음 수취인은 해당 어음이 부실 예금의 하위 항목이라는 사실을 즉시 알 수 있지만, 해당 예금이 자신의 어음에 얼마나 기여했는지는 알 수 없습니다.
따라서 Payy는 악의적인 행위자의 추적을 가능하게 하기 위해 개인정보 보호의 일부를 희생합니다. 개인정보 보호 희생의 정도에 대해 이야기해 보겠습니다.
제가 생각하기에 Payy의 디자인이 초래하는 개인정보 유출 문제는 다음과 같습니다.
입금 후 첫 번째 이체는 입금자로부터 온 것으로 공개적으로 식별 가능합니다. 즉, 송금인이 유출됩니다.
출금 전 마지막 이체가 출금자에게 전달된 것으로 공개적으로 식별되는 경우. 즉, 수신자가 유출되는 경우입니다.
A가 입금하면 A → B가 됩니다(즉, "A가 B에게 이체"). 그런 다음 B가 출금하면 세상은 A가 B와 거래했다는 것을 알게 됩니다. 해당 하위 그래프에 다른 거래가 없다면 세상은 A가 B에게 보낸 정확한 금액을 알게 될 수도 있습니다.
E → B → C → E라면, E는 B와 C가 거래를 했다는 사실을 알게 됩니다. E는 B가 C를 알고 있다는 사실도 알게 됩니다. 이는 예상치 못하게 큰 유출입니다. 아마도 그 정도의 유출로 인해 연애 사건도 드러났을 것입니다.
E가 거래소처럼 규모가 큰 기관이라면, 이러한 종류의 누출을 통해 상당한 양의 거래 그래프를 유추할 수 있을 것입니다. 누가 누구를 알고 있는지 조각조각 모아 참가자 간에 지불되는 금액을 잠재적으로 추론할 수 있을 것입니다.
5분만 생각해 봐도 알 수 있는 누출이에요. 좀 더 유능한 괴짜 팀이 있다면 더 많은 걸 유추해낼 수 있을지도 몰라요.
레일건
레일건은 입금-송금-출금 프로토콜입니다. 정말 좋네요.
시스템에 입금하는 모든 건에는 1시간의 지연이 발생하며, 이로 인해 '불량' 입금은 거부될 수 있습니다.
시스템 에 들어가면 사용자 간에 개인적으로 돈을 이체할 수 있습니다.
문제는, 그리고 제가 이 글을 쓰게 된 가장 큰 이유이기도 한데, 한 시간이 그렇게 긴 시간이 아니라는 것입니다. 게다가 기술적으로 악의적인 행위자가 '그물망을 빠져나가' '불량' 자금을 풀에 입금할 가능성도 있습니다. 일단 풀에 들어가면 그들을 잡을 방법이 없습니다.
이 글을 다 쓴 후 편집: 그 일이 일어났어요!!!
https://x.com/dethective/status/1994397800847589736?s=20
이 일이 일어나기 전에 다큐를 끝냈더라면, 선견지명이 있는 사람으로 여겨졌을 텐데.
어쨌든, 저는 풀을 통해 '불량' 자금을 추적하는 문제를 해결하고자 했습니다. 풀에 자금이 유입될 때 '불량' 자금인지 알지 못하더라도, 모든 사용자의 프라이버시를 최대한 보호하면서 비공개 전송이 가능하도록 하는 풀을 구축했습니다. 몇 가지 프로젝트를 더 언급하고 나면 요건에 대해 좀 더 엄격하게 적용할 예정입니다.
EY블록체인
2019년에 저는 이 문제를 탐구하는 소규모 연구팀에 속해 있었습니다. 불량 예금을 추적할 수 있는 프라이버시 풀을 설계하는 방법과 동시에 우수한 프라이버시를 보장하는 방법에 대한 연구였습니다.
한동안 새로 예치된 모든 지폐에 deposit_id를 부여하는, 당연하고 오늘날 널리 알려진 막다른 골목에 빠져 있었던 기억이 납니다. 그러면 매번 이체될 때마다 출력 지폐에는 모든 입력 지폐의 deposit_id를 합친 합집합이 포함됩니다. 이로 인해 목록이 기하급수적으로 늘어나고, 이체될 때마다 크기가 약 두 배로 늘어납니다. 지속 가능한 방식이 아닙니다. 아무것도 공개하지 않은 것 같습니다.
사실, 2019년에 몇 차례 공개 강연을 했는데, 그 강연을 통해 도난당한 NFT를 보호된 NFT 풀을 통해 추적하는 더 쉬운 문제를 해결했습니다. NFT 전송의 대체 불가능성 덕분에 기하급수적으로 증가하는 목록 문제가 발생하지 않습니다.
그 작은 팀에서 시대를 앞서가는 연구가 많이 있었지만, 엉성한 아이디어를 공개하지 않았는데, 지금 돌이켜보면 부끄러운 일입니다.
하지만... 이 문서의 뒷부분에서 가끔씩 해당 목록을 부트스트래핑(재설정)하여 문제를 해결하려고 시도하는 부분을 살펴보겠습니다.
deposit_id를 추적하는 모든 접근 방식에 대한 일반적인 비판은 지폐의 대체성이 사라진다는 것입니다. deposit_id는 지폐의 표시 역할을 하기 때문입니다. 사람들은 주고받는 지폐에서 패턴을 확인할 수 있게 됩니다.
사소한 유출은 Eve->Bob->Eve, 또는 Eve->Bob->Charlie->Eve입니다. 심지어 Eve->…->Eve일 수도 있습니다. Eve는 자신이 보낸 지폐와 받은 지폐에서 공통된 deposit_id를 찾아낼 수 있으며, 이를 통해 정보를 추론할 수도 있습니다. 예를 들어 E->B->C->E의 경우, Eve는 Bob이 Charlie를 알고 있으며, Bob이 Charlie에게 돈을 보냈다는 것을 추론할 수 있습니다.
이 문서는 매 이체 시마다 deposit_id 목록을 무작위로 재지정하여 deposit_id가 마커 역할을 하는 문제를 해결하고자 합니다. 이렇게 하면 Eve는 자신이 보낸 지폐와 나중에 받는 지폐 사이의 공통점을 식별할 수 없게 됩니다.
프라이버시 풀
Privacy Pools 제품은 입금-출금 프로토콜입니다.
제가 가장 먼저 비판하고 싶은 점은 "전송을 지원하지 않는다"는 것입니다. 하지만 Privacy Pools 논문에서는 개인 전송을 가능하게 하는 접근 방식에 대해 언급하고 있습니다.
devconnect에서 그들과 채팅 후 수정: 프라이버시 풀 v2에서는 비공개 전송을 활성화 할 예정 이지만, 프라이버시 풀 문서에 설명된 접근 방식과는 다릅니다. v2를 위해 개발 중인 내용에 대한 제 생각은 다음과 같습니다.
모든 입금에 대해, 생성된 수표에는 deposit_id가 포함됩니다. 시스템 내에서 이체가 발생할 수 있지만, 모든 입력 수표에는 동일한 deposit_id가 있어야 하며 , 모든 출력 수표에도 동일한 deposit_id가 부여됩니다.
이는 "기하급수적으로 증가하는 목록" 문제를 피하는 깔끔한 방법입니다. 즉, 메모에는 항상 1개의 deposit_id가 포함됩니다.
이 접근 방식의 문제점은 다음과 같습니다. 사용자가 100 ETH를 보내야 하는 경우, 두 개의 동일한 deposit_id를 가진 두 개의 지폐가 필요하며, 두 지폐의 값의 합은 100 이상입니다. 하지만 두 개의 동일한 deposit_id를 가진 지폐가 없다면 어떻게 될까요? 사용하려는 지폐의 각 deposit_id에 대해 하나씩, 여러 개의 거래를 보내야 합니다.
입금 활동이 충분해지면 사용자가 동일한 deposit_id를 포함하는 노트를 받는 경우가 드물어질 것으로 예상됩니다. 만약 그렇다면, 사용자가 두 노트를 합치는 것도 드물어질 것입니다(두 노트는 동일한 deposit_id를 공유해야 하기 때문입니다). 그리고 이로 인해 "분할" 작업이 "합치기" 작업보다 훨씬 많아져서, 노트에 아주 작고 비실용적인 값이 포함되는 "먼지"가 발생하는 시스템이 생길 수 있다고 생각합니다.
사용자끼리 상호 작용할 수도 있을 겁니다. 수신자가 특정 deposit_id가 포함된 메모를 발신자에게 요청할 수 있죠. 카드 게임인 고피쉬에서 "deposit_id가 1234인 게 있나요?"와 비슷합니다.
이 게시물의 제안은 deposit_id를 섞어 사용할 수 있도록 하는 것입니다.
이 v2 방식에 대한 또 다른 비판은 (이전 하위 섹션에서도 언급했듯이) deposit_id가 대체성을 저해하는 마커 역할을 한다는 것입니다. 이 문서에서는 모든 이체 시 deposit_id를 다시 무작위로 지정하여 이 문제를 해결하고자 합니다.
프라이버시 풀에 대한 두 번째 (약한) 비판은 입금이 풀에 수용되기 전에 가변적인 지연 시간이 있다는 것입니다. 괜찮을 수도 있지만, 불량 자금이 풀에 유입되면 어떻게 되는지 알아보고 싶었기 때문에 "더 많은 실사를 위해 더 기다려라"라는 답은 원하지 않습니다. 실사 과정에서 실수가 발생할 수 있다는 점을 지적하고, 실수로 유입된 불량 입금을 소급하여 불량으로 표시할 수 있는 기능이 필요하다고 생각합니다.
개인정보 풀 논문에 설명된 접근 방식은 다음과 같습니다.
한 가지 비판은 정보 유출이 너무 많다는 것입니다. 보호된 풀에서는 전통적으로 비공개로 유지하려는 정보입니다. 여기에서는 입금 내역이 허용 목록에 추가될 때까지 사용자 간에 많은 개인 정보가 공유됩니다.
블랭크스퀘어
아마 믿지 못하시겠지만, 이 글의 아이디어를 쓰기 시작한 건 9월/10월쯤이었어요. 본업, 즐거운 가족 휴가, 그리고 개발자와의 소통 등 다른 일들로 좀 바빴거든요.
그러다가 토요일(11월 말)에 결혼식에 +1으로 갔을 때 Signal 그룹에서 이 링크를 받았습니다.
deposit_id를 암호화하는 것을 제안하는데, 이 문서에도 이 아이디어가 나와 있습니다. 정말 대단하세요!
어쨌든, 저는 베끼는 게 아니에요. 둘 다 같은 걸 독립적으로 구현한 거예요. 영수증에 타임스탬프를 찍었어요!
이 문서는 그 아이디어를 훨씬 더 확장해서 설명하고 있으니, 흥미롭게 읽어주셨으면 좋겠습니다. 또한, 그 아이디어에 대한 몇 가지 비판점도 다루고 있는데, 이제 그 부분을 살펴보겠습니다.
간단히 말해, 어떤 개체가 시스템에 입금될 때마다 새로운 키 쌍을 생성하는 것이었습니다. 각 deposit_id는 해당 공개 키로 암호화될 수 있습니다. 이후 시스템에서 해당 출금이 발생할 때마다 동일한 암호화된 deposit_id를 시그널링해야 합니다(출금 신호가 입금과 무관해 보이도록 salted 처리됩니다). 이상적인 경로에서는 관찰자는 출금이 입금과 관련이 있다는 사실을 결코 알 수 없습니다. 하지만 나중에 입금이 '불량'으로 간주되면, 복호화 키 보유자가 비밀 키를 공개할 수 있으며, 이를 통해 모든 관찰자는 입금 및 출금 거래의 암호화된 deposit_id를 복호화하여 궁극적으로 출금을 입금과 연결할 수 있습니다.
이 접근 방식의 문제점:
복호화 키 보유자는 시스템 장애의 원인이 될 수 있습니다. 키가 유출되면 (의도적이든 아니든) 모든 사용자의 입출금을 연결할 수 있게 됩니다. TEE를 사용하거나 MPC 노드들을 통해 복호화 키를 비밀리에 공유하는 방안이 있습니다. 물론 복호화 키(및 기타 비밀)를 비밀리에 공유하는 방식은 FHE 및 CoSnark 설정에서 흔히 볼 수 있는 방식이기 때문에, 일부에서는 이를 허용 가능한 방식으로 간주할 수도 있습니다.
비탈릭은 "개인정보 침해"라는 개념을 전혀 좋아하지 않습니다.
제가 이 글에서 제안하는 접근 방식은 여전히 논란의 여지가 있는 키를 생성하는 MPC 집단이 있지만, 모든 복호화 키가 어떻게든 유출되는 경우 최악의 유출을 최대한 막으려고 노력합니다.
Blanksquare 접근 방식을 사용하면:
- 최악의 경우 무엇이 유출되나요?
- 모든 출금은 모든 입금과 연결됩니다.
- 누구에게 유출되었나요?
- 전 세계의 모든 사람(모든 블록체인 관찰자).
이 문서의 접근 방식은 다음과 같습니다.
- 최악의 경우 무엇이 유출되나요?
- 특정 사용자의 메모에 기여한 deposit_id입니다.
- 각 deposit_id가 해당 수표에 "기여"한 금액입니다.
- 누구에게 유출되었나요?
- 해당 수표의 소유자에게만.
누출은 국한되어 있습니다.
나쁘지 않죠?
적어도 비탈릭이 슬퍼할 정도로(그럴 수 있기를 바라지만) 우리는 사생활을 침해하지는 않을 겁니다.
최악의 경우, 이 문서의 프로토콜은 채권 소유자가 자신의 채권에 기여한 deposit_id를 확인할 수 있는 방식으로 축소됩니다. 이는 이상적인 방식은 아니지만(이전 섹션에서 deposit_id가 채권에서 대체 불가능한 "표시" 역할을 한다는 점을 지적한 부분 참조), 여러분 모두에게 설명할 가치가 있는 발전이라고 생각했습니다.
행복한 경우에는 프라이버시가 실제로 매우 좋습니다.
아이디어
마지막으로 우리는 아이디어에 대해 논의할 수 있습니다.
요구 사항
어떤 기능을 찾고 있나요?
- 개인 전송을 지원하는 보호된 풀입니다.
- 행복한 길에서는 deposit_id(지폐 내)가 무작위로 지정되어, 고급 지폐 소유자가 이를 "마커"로 사용하여 활동 패턴을 파악하는 것을 방지합니다.
- 부실 예금이 실수로 풀에 유입되면 나중에 '부실'로 표시될 수 있으며, 풀의 모든 사용자는 자신의 지폐에 '부실' 값이 포함되어 있는지, 지폐 가치 중 얼마만큼이 '부실'로 간주되는지 확인할 수 있습니다.
- 최악의 경우(이 프로토콜의 암호 해독 키가 유출되는 경우)에도 블록체인 관찰자는 누구의 노트에 '나쁜' 값이 들어 있는지 알 수 없습니다.
- 과거 인출에 대한 소급적 개인정보 보호 위협 방지: 이 시스템은 최악의 경우 시스템의 암호 해독 키가 유출되더라도 이미 발생한 인출에 대한 정보가 유출되지 않도록 설계할 수 있습니다.
- 이체나 출금을 수행할 때 사용자는 자신이 입력한 금액이 '불량' 입금에서 나온 것이 아니라는 것을 증명할 수 있습니다.
- 사용자의 지폐가 불량 예금에서 유래 된 경우, 사용자는 지폐를 '양호' 지폐와 '불량' 지폐로 나누어 '오염 제거'할 수 있습니다.
- 나는 제약 조건 수와 관련하여 어떠한 약속도 하지 않습니다.

높은 수준
다음은 저수준 섹션입니다.
기본은 간단한 입금-송금-출금 프로토콜입니다.
불량 deposit_id의 블랙리스트는 블랙리스트 관리자에 의해 관리됩니다.
예치금이 세트에 들어오기 전에 지연 기간이 있을 수 있지만, 우리는 그러한 지연 기간을 통과하지 못하는 예치금을 포착하는 기계에 관심이 있습니다.
방대한 전처리 단계를 거쳐 deposit_id 키 쌍의 긴 목록이 생성됩니다. 이는 프로토콜에 대한 모든 미래 입금에 대한 것입니다.
[(x_1, Y_1), (x_2, Y_2), ..., (x_{1000000}, Y_{1000000})] [ ( x 1 , Y 1 ) , ( x 2 , Y 2 ) , . . . , ( x 1000000 , Y 1000000 ) ]
여기서 x_i x i 는 비밀 키이고 Y_i Y i 는 공개 키입니다.
목록은 부족할 때마다 주기적으로 보충될 수 있습니다.
이 목록은 단일 행위자에 의해 생성될 수도 있지만 , 아마 그 방식은 썩 마음에 들지 않을 것 같습니다. 따라서 대규모 MPC 집단에 의해 생성되었다고 가정해 보겠습니다. 이들을 키 보유자(들)라고 부르겠습니다. 키 보유자는 블랙리스트 관리자와 동일할 수도 있고, 다른 주체일 수도 있습니다. 이 걱정스러운 주제에 대해서는 곧 다시 다루겠습니다.
새로운 입금 i i 가 이루어지면 공개 키 Y_i Y i 와 공개적으로 연결됩니다.
미리 생성된 목록을 사용하면 사용자는 키 보유자가 새로운 공개 키를 생성하고 게시할 때까지 기다리지 않고도 프로토콜에 비대화형으로 입금할 수 있습니다.
이 공개 키 Y_i Y i 에 정보를 암호화합니다 . 구체적으로, 이 입금의 "하류"에 있는 모든 지폐에는 다음이 포함됩니다.
- deposit_id i i 의 암호화는 Y_i Y i 로 암호화됩니다.
- 이 지폐에 기여한 예금의 일부 를 암호화하여 Y_i Y i 로 암호화합니다.
이후 섹션에서 기술적인 세부 사항을 천천히 살펴보겠습니다.
이 시스템은 이체를 지원하므로, 하나의 어음이 여러 예금의 후손일 수 있습니다. 괜찮습니다. 어음에는 모든 상류 예금 목록이 포함됩니다. 눈치 빠른 독자라면 이러한 목록이 기하급수적으로, 그리고 지속 불가능하게 증가하여 이체될 때마다 두 배로 늘어난다는 것을 알아차릴 것입니다. 이 부분에 대해서는 나중에 다시 살펴보겠습니다.
정상적인 상황에서는 하류 채권 소유자는 자신의 채권에 포함된 암호화된 입금 정보를 복호화할 수 없습니다. 아무도 (바람직하게는 키 보유자 집단조차도) 복호화 키 x_i x i 를 알지 못하기 때문입니다. 따라서 어떤 입금이 자신의 채권으로 유입되었는지 알 수 없습니다. 시스템의 프라이버시를 최대한 zcash와 유사하게 유지하는 것이 목표입니다. 즉, 관찰자는 풀 내부에서 무슨 일이 일어나고 있는지 알 수 없고, 거래 내역 그래프도 알 수 없으며, 가치는 대체 가능하고, 채권 소유자는 채권의 계보를 추적할 수 없습니다.
deposit i i가 나중에 "불량"으로 간주되면 블랙리스트 관리자는 체인상에서 deposit i i 를 표시합니다. i i 가 블랙리스트에 등재되는 것을 확인한 키 보유자는 체인상에서 해당 비밀 키 x_i x i를 공개 해야 합니다. 키 보유자가 MPC 집단인 경우, 임계값 체계 등을 통해 x_i x i 의 실제 값을 파악하기 위해 협력해야 합니다.
i i 와 x_i x i 의 공개는 일련의 활동을 촉발할 것입니다. 전체 시스템의 모든 채권 소유자는 자신의 채권에 포함된 모든 암호화된 deposit_id를 복호화할 수 있습니다. 만약 해당 채권이 deposit i i 의 자손 인 경우 , 해당 채권의 암호화된 deposit_id 필드 중 하나를 성공적으로 복호화하여 i i 를 생성합니다.
해당 어음에 예금 i i 의 "불량" 자금이 포함되어 있다고 가정해 보겠습니다. 이런. 얼마나 많은 금액이 포함되어 있는지 알아보려면, 공개된 x_i x i 를 사용하여 어음에 존재하는 해당 "암호화된 부분"을 해독할 수도 있습니다. 이를 통해 원래 예금의 얼마만큼의 금액이 어음에 포함되어 있는지 알 수 있습니다.
새롭고 극적인 이름의 "오염 제거 회로"를 통해 사용자는 수표에서 불량 자금을 "제거"할 수 있습니다.
중요한 점은, 채권 소유자가 해당 채권의 다른 암호화된 deposit_id 필드를 해독할 수 없다는 것입니다. 채권 소유자에게 유출되는 정보는 다음과 같습니다.
"제 수표는 예금 i i 의 '하류'에 있습니다. 프로토콜에 따르면 제 수표에는 해당 불량 예금의 X 금액이 포함되어 있는 것으로 간주됩니다."
또는 더 간결하게 말하면:
"내 어음의 X 금액은 부실 예금 에서 발생한 것으로 간주됩니다."
노트 소유자는 노트가 누구에게 전달되었는지 등 노트의 계보에 대한 다른 정보를 알 수 없습니다.
외부 관찰자는 어떤 지폐가 오염되었는지 알 수 없고, 거래 그래프에 대한 의미 있는 정보를 얻을 수 없습니다.
이쯤 되면 아마 머릿속에는 뜨거운 비판이 가득할 겁니다. 몇 가지를 나열해 볼까요?
- 키 보유자들이 공모하면 x_i x i 를 알아낼 수 있습니다.
- 블랙리스트 관리자는 사람들을 블랙리스트에 추가하여 사악해지고 검열할 수도 있습니다.
- 키 보유자는 i i가 블랙리스트에 오르면 x_i x i를 공개하는 일을 하지 않을 수도 있습니다.
- 정직한 사용자가 입금 내역을 볼 수 없는 메모를 받고 나중에 블랙리스트에 올라간 후에 해당 메모가 실제로는 "나쁜" 가치로 오염되었다는 사실을 알게 되는 것은 공정하지 않은 것 같습니다.
- 프로토콜은 어떻게 예금의 얼마만큼의 비율이 각 지폐로 유입되는지를 결정합니까?
- 입금 목록을 추적하면 '송금' 거래가 발생할 때마다 두 배로 늘어납니다. 지속 가능하지 않습니다.
그 모든 것에 대해서는 곧 이야기하겠습니다.
단계별로
설정
방대한 전처리 단계를 거쳐 deposit_id 키 쌍의 긴 목록이 생성됩니다. 프로토콜에 대한 모든 미래 입금에 대해 하나씩 생성됩니다.
[(x_1, Y_1), (x_2, Y_2), ..., (x_{1000000}, Y_{1000000})] [ ( x 1 , Y 1 ) , ( x 2 , Y 2 ) , . . . , ( x 1000000 , Y 1000000 ) ]
여기서 x_i x i 는 비밀 키이고 Y_i Y i 는 공개 키입니다.
목록은 부족할 때마다 주기적으로 보충될 수 있습니다.
조금 더 공식적으로(하지만 표기법은 여전히 꽤 느슨함):
G \in \mathbb{G} G ∈ G 는 생성점입니다.
x_i \in \mathbb{F} x i ∈ F는 그룹 \mathbb{G} G 의 스칼라 필드에 있는 deposit_id i i 에 대한 비밀 키입니다.
Y_i := x_i \cdot G Y i : = x i ⋅ G deposit_id i i 에 해당하는 공개 키입니다.
보증금
사용자는 입금 i i 의 일부로 일정 금액을 입금합니다. 이 입금은 공개 키 Y_i Y i 와 연관되어 있습니다.
다음 데이터를 포함하는 새 메모가 생성됩니다.
notes[i][1] = {owner,amount,randomness,deposits: [{encrypted_deposit_id = "i" ,encrypted_fraction = "1" ,},{},...{}],}어디:
우리는 때때로 "x" 라는 표기법을 사용해서 " x 값의 암호화"를 느슨하게 의미하기도 합니다.
encrypted_deposit_id = "i" = \text{enc}_{Y_i}(i) enc Y i ( i ) , deposit_id i i 의 암호화로, 공개 키 Y_i Y i 로 암호화됩니다.
이 암호화 체계는 암호문의 재정렬을 지원해야 합니다. Elgamal이 좋은 선택입니다(부록 참조).
encrypted_fraction = "1" = \text{enc}_{Y_i}(1) enc Y i ( 1 ) , 이 지폐로 유입된 이 예금의 일부에 대한 암호화로, 처음에는 1 1 의 암호화입니다.
이 암호화 체계는 암호문에 알려진 스칼라를 스칼라 곱하는 것을 지원해야 합니다. 그 이유는 잠시 후에 설명하겠습니다. Paillier 암호화는 멋진 선택이지만, snark 회로에서는 매우 비효율적입니다(부록 참조).
다이어그램 시간입니다!
enc_dep_id_i_j입금에서jth홉(전송) 이후의 입금i의 "암호화된 deposit_id"입니다.
enc_frac_i_j는 이 수표에 기여한 예치금i의 가치의 "암호화된 분수"입니다(예치금에서jth홉(전송) 후).
실제로 사용자는j볼 수 없습니다. 이는 단지 다이어그램을 읽는 사람을 돕기 위한 것입니다.
파이에 암호화는 확고한 것은 아니지만, 알려진 스칼라로 암호문을 곱하는 데에는 훨씬 더 효율적인 대안이 있는 것으로 보입니다.
가독성과 게으름을 위해 따옴표를 사용했습니다."x"는 "x의 암호화"를 의미합니다.
옮기다
예
비공개 전송은 두 개의 메모를 파기하고, 수신자용 메모 하나와 발신자용 변경 메모 하나를 생성합니다. (간결성을 위해 변경 메모는 생략합니다.)
원래 5 ETH를 입금한 사람이 누군가에게 1.5 ETH를 보내고 싶어한다고 가정해 보겠습니다.
예를 들어, 5 ETH 지폐와 10 ETH 지폐를 가지고 있다고 가정해 보겠습니다.
그들은 두 개의 지폐(총 15 ETH 가치)를 무효화하고 1.5 ETH 가치의 새로운 지폐를 만들 수 있습니다.
5 ETH 예치금 중 얼마가, 10 ETH 예치금 중 얼마가 새로운 1.5 ETH 지폐에 들어갔나요?
돈의 유동성을 고려할 때, 예금이 하류 채권에 얼마나 기여하는지 실제로 파악하기는 어렵습니다. 마치 토마토 한 숟갈이 특정 수프 한 숟갈에 얼마나 기여했는지 알아내려는 것과 같습니다.
하지만 수학적으로 자연스러운 접근 방식이 있는데, 그것은 기여도가 입력 음표에 비례한다고 간주하는 것입니다.
우리의 예에서 우리는 5 * \frac{1.5}{15} = 0.5 5 ∗ 1.5 15 로 간주할 수 있습니다. = 0.5는 5-ETH 입금에서 나왔고 10 * \frac{1.5}{15} = 1 10 ∗ 1.5 15 = 1은 10 ETH 입금에서 나왔습니다. 즉, \frac{15}{150} 15 150 의 분수를 적용할 수 있습니다. 두 입력 예금 모두에.
이론상으로는 사용자가 기여도를 다르게 지정할 수 있습니다. 예를 들어, 특정 deposit_id 전체를 자신의 변경 노트에 할당하고, 의도한 수신자의 노트에는 아무것도 할당하지 않을 수 있습니다. 하지만 저희 프로토콜은 노트에 어떤 deposit_id가 포함되어 있는지 숨기기 때문에(deposit_id가 '유효'한 경우), 사실상 아무런 의미가 없습니다. 사용자는 자신이 어떤 deposit_id를 할당하는지조차 알 수 없기 때문입니다! 만약 deposit_id가 '불량'으로 확인될 경우, '불량' 값을 분리해낼 수 있는 별도의 오염 제거 회로가 있습니다.
이 다이어그램은 특정 지폐에 기여한 deposit_id에 분수를 적용하는 방법을 보여줍니다.
가독성과 게으름을 위해 따옴표를 사용했습니다.
"x"는 "x의 암호화"를 의미합니다.
이 1.5 ETH 지폐를 입력으로 받는 후속 이체를 고려해 보겠습니다. 20 ETH를 이체하고, 다른 입력 지폐의 가치가 100 ETH라고 가정해 보겠습니다.
그런 다음 20-ETH 출력 노트에 기여한 모든 입금에 적용할 다음 분수는 다음과 같습니다. \frac{200}{1015} 200 1015 .
다이어그램 내의 표기법은 항상 복잡합니다.
100-ETH 지폐에 표기법을 너무 게을리 한 게 보이시죠? 예를 들어
enc_frac_3_j = "prod(f_3_j)"는 "이 지폐에 기여한 예치금 3의 일부에 대한 암호화"를 의미합니다. 그리고 "예치금 3 이후 이 지폐에 도달하기 위해j이체가 있었다"라고 게으르게 표현해 보겠습니다.
20-ETH 지폐를 살펴보면 우리가 추적하고 있는 입금 데이터의 패턴이 나타나기 시작해야 합니다.
5-ETH 입금에 대해 추적되는 데이터는 다음과 같습니다.
deposits: [(enc_dep_id = "1" enc_frac_1_3 = "1 * (15/150) * (200/1015)" ,), 이제 이 20-ETH 지폐의 소유자는 실제로 암호문 enc_dep_id_1_3 과 enc_frac_1_3 을 해독할 수 없습니다. 해독 키 x_1 x 1 을 모르기 때문입니다.
하지만 블랙리스트 관리자가 갑자기 입금 1 1 을 블랙리스트에 추가하고 키 보유자가 x_1 x 1 을 도출하고 게시하는 작업을 수행했다면, 이 20-ETH 지폐 보유자는 암호문 enc_dep_id_1_3 과 enc_frac_1_3 복호화할 수 있게 됩니다. (참고: 지폐에 저장된 다른 암호문은 서로 다른 공개 키로 암호화되어 있으므로 여전히 복호화할 수 없습니다.)
영어: 노트 소유자는 "아, 보세요. 새로 게시된 x_1 x 1 을 사용하여 enc_dep_id_1_3 해독하여 1 1 을 얻을 수 있었습니다. 이는 제 노트가 예치금 1 1 의 일부 값으로 '오염'되었음을 의미합니다. 이제 enc_frac_1_3 해독하여 분수 1 * (15/150) * (200/1015) 를 얻을 것입니다. 예치금 1의 일부로 얼마가 예치되었는지 알고 있습니다(예치 금액은 공개되므로): 5 ETH입니다. 따라서 5 * (1 * (15/150) * (200/1015)) = 0.098522 ETH 계산합니다. 따라서 프로토콜은 제 노트의 0.098522 ETH '불량' 예치금 1 1 에서 나온 것으로 간주합니다."
머릿속의 어떤 비판도 무시하고: 꽤 멋지지 않나요? 네트워크의 수백 개의 지폐 안에는 이해할 수 없고 암호화된 데이터가 무더기로 존재할 수 있는데, 거래 그래프는 유출되지 않습니다. 그런데 갑자기 예금을 블랙리스트에 올리면 아주 작은 양의 유용한 정보만 드러나고, 그것도 하류 지폐 소유자에게만 공개될 수 있습니다.
파일리에
우리는 파일리어 암호화를 사용하여 분수를 암호화할 수 있으므로, 결과 암호문을 미래의 모든 이체 거래에서 새로운 분수로 반복해서 곱할 수 있으며, 결과 분수가 무엇인지 결코 알 수 없습니다.
즉, 제가 enc(m) en c ( m ) 을 주면, m m 이 무엇인지 배우지 않고도 알려진 스칼라 k k 에 대해 enc(km) en c ( km ) 을 계산할 수 있습니다.
Paillier 암호화에 대한 자세한 설명은 부록을 참조하세요. 이 문서의 나머지 부분과는 별개로, 정말 멋진 내용입니다. FHE 기법을 사용하여 스나크 내에서 이 "스칼라 곱셈" 속성을 달성하는 훨씬 더 효율적인 접근 방식이 있는 것 같습니다. 관심 있는 독자는 다음 내용을 살펴보세요. 
지금까지 진행해 온 예를 돌이켜보면, 우리는 다음과 같이 시작했습니다.
enc(1 ) en c ( 1 )
다음 전송 회로는 이 암호문을 알려진 스칼라 15/150 15 / 150 (6d.p.로 반올림한 정수로 표현됨, 15/150 * 10^6 = 100,000 15 / 150 ∗ 10 6 = 100 , 000 )으로 스칼라 곱했습니다. Paillier를 사용하는 경우 연산은 enc(1)^{100000} = enc(1 * 100000) en c ( 1 ) 100000 = en c ( 1 ∗ 100000 ) 입니다 . 수표 수신자는 어떤 deposit_id가 수표로 유입되었는지 알 수 없으며, 각 deposit_id의 몇 분율 이 수표에 기여했는지도 알 수 없습니다. 새로 계산된 암호문만 볼 수 있습니다.
다음 전송 회로는 이 암호문을 알려진 스칼라 200/1015 200 / 1015 (6d.p.로 반올림된 정수로 표현됨, 200/1015 * 10^6 = 197,044 200 / 1015 ∗ 10 6 = 197,044 . Paillier 를 사용하는 경우 연산은 enc(1 * 100000)^{197044} = enc(1 * 100000 * 197044) en c ( 1 ∗ 100000 ) 197044 = en c ( 1 ∗ 100000 ∗ 197044 ) 가 됩니다 .
복호화하면 실제 분수는 1 * 100000 * 197044 / (10^6)^2 = 0.0197044 1 ∗ 100000 ∗ 197044 / ( 10 6 ) 2 = 0.0197044 로 도출될 수 있습니다.
복호화 키가 공개되면 사용자는 이 부분을 복호화하여 원래 입금 금액(예시에서는 5 ETH)에 적용하면 해당 지폐에 0.0197044 * 5 = 0.098522 0.0197044 ∗ 5 = 0.098522 ETH가 들어 있는 것으로 간주된다는 것을 알 수 있습니다.
예제에 대한 몇 가지 의견
계속 진행하기 전에 몇 가지 의견을 말씀드리겠습니다.
분수 → 소수
다이어그램에서 우리는 암호화된 분수를 추적하고 있었지만 실제로는 두 가지 이유 때문에 그렇게 하고 싶지 않았습니다.
분수를 암호화하고 반복적으로 새로운 분수를 곱하려면 분자와 분모를 따로 암호화해야 합니다(적어도 제가 알고 있는 암호화 방식을 사용하면). 이는 제약 조건의 낭비입니다.
분수의 분자와 분모가 누출됩니다.
분자를 인수분해하면 예금 이후 각 '이체' 거래에서 이체된 금액을 추정할 수 있습니다. 분모를 인수분해하면 예금 이후 각 중간 채권 소유자가 보유한 채권의 규모를 추정할 수 있습니다.
대신, 각 분수를 소수로 변환할 수 있으며, 이는 ( 중요하고 필수적인 ) 소수점 이하 자릿수로 반올림될 수 있습니다. 반올림은 인수분해를 통해 추론할 수 있는 양을 줄여줍니다(특히 사용자가 변환량을 임의로 선택하여 결과 분수에 반올림이 발생하는 경우).
deposit_id가 암호화되는 이유는 무엇입니까?
이브가 밥에게 돈을 보내고, 밥이 이브에게 돈을 보낸다고 가정해 보겠습니다(E → B → E). deposit_id가 암호화되어 있지 않으면 이브는 자신이 보낸 돈과 받은 돈의 deposit_id가 같다는 것을 알게 됩니다.
더 나쁜 상황은 이브가 밥에게 돈을 보내고, 밥이 찰리에게 돈을 보내고, 찰리가 이브에게 돈을 보낸다고 가정해 보겠습니다(E → B → C → E). deposit_id가 암호화되지 않았다면 이브는 자신이 밥에게 보낸 편지와 찰리가 자신에게 보낸 편지의 공통 deposit_id를 알아차릴 것입니다. 이브는 "밥이 찰리를 알고 있다", "밥이 찰리에게 돈을 보냈다"와 같은 정보를 유추할 수 있으며, 심지어 서로에게 보낸 금액까지도 유추할 수 있습니다. deposit_id를 다시 암호화하면 이러한 정보 유출을 방지할 수 있습니다.
하지만 암호화된 deposit_id가 이체 간에 변경되지 않으면 해당 암호문은 사실상 입금에 대한 대체 식별자가 됩니다 .
그래서 저희는 매 송금 시 암호화된 deposit_id를 다시 무작위로 설정합니다 . 이렇게 하면 deposit_id 목록이 모든 지폐마다 다른 무작위 숫자 목록이 됩니다! Elgamal이 훌륭한 암호화 방식인 이유도 바로 여기에 있습니다. Elgamal과 무작위로 다시 설정하는 방식은 Appx를 참조하세요.
분수(또는 소수)가 암호화되는 이유는 무엇입니까?
이는 deposit_id가 암호화되는 이유와 비슷합니다.
거래 그래프에 여러 번 등장하는 개체는 자신의 노트에 포함된 분수에서 패턴을 발견하고 거래 그래프를 조각조각 이어붙이거나 위 섹션과 유사한 추론을 할 수 있습니다.
예시에서 사용자가 0.098522 ETH를 획득한 것은 나쁜 일입니다.
예시에서, 사용자 어음의 0.098522 ETH 일부가 사용자가 어음을 취득한 후 얼마 지나지 않아 '불량'으로 간주되었습니다. 사용자는 정직했으며, 어음을 받았을 당시에는 그 '불량' 상태를 인지하지 못했습니다.
이상적으로는 블랙리스트 등록은 시스템에서 이체가 발생하기 전, 예를 들어 입금 지연 기간 동안에 이루어지는 것이 좋습니다. 이 경우, 불량 입금의 비밀 키 x_i x i는 이체가 발생하기 전에 모든 사용자에게 이미 알려져 있을 것입니다. 불량 입금자가 정직한 사용자에게 돈을 이체하려고 시도했다면, 해당 사용자는 즉시 이를 알아챌 수 있을 것입니다.
또한 실제 세계 에서 무슨 일이 일어나야 하는지에 대한 흥미로운 토끼 구멍이 있습니다.













