원래 제목: "Having a safe CEX: proof of solvency and beyond》
원래 제목: "
원작자: 비탈릭 부테린
원문 편집: Double Spending (@doublespending)
Balaji Srinivasan과 Coinbase, Kraken 및 Binance 팀의 토론에 특별히 감사드립니다.
대규모 중앙 집중식 거래소가 충돌할 때마다 자주 묻는 질문은 이 문제를 해결하기 위해 암호화를 사용할 수 있는지 여부입니다. 거래소는 정부 라이센스, 감사자, 기업 지배 구조 조사 및 법인 역추적과 같은 "법적 통화" 프로그램에만 의존하기보다는 암호화 증명을 생성하여 사용자에게 상환하기에 충분하다는 것을 체인에 보유하고 있음을 증명할 수 있습니다.
보다 야심차게, 거래소는 예금자 자금이 동의 없이 인출될 수 없는 시스템을 만들 수 있습니다. 우리는 "악을 행하지 않는" 전문 CEX와 "악을 행할 수 없지만" 프라이버시를 유출하는 비효율적인 온체인 DEX 사이의 경계를 탐구할 수 있습니다. 이 게시물에서는 CEX를 더 신뢰할 수 없게 만들려는 역사적 시도, 기술의 한계, ZK-SNARK와 같은 고급 기술에 의존하는 몇 가지 강력한 수단을 탐구합니다.
대차대조표와 머클 트리: 전통적인 상환 증명
사용자를 속이지 않았다는 것을 증명하기 위해 암호화를 사용하려는 거래소의 초기 시도는 오래 전으로 거슬러 올라갑니다. 2011년 당시 최대 규모의 비트코인 거래소인 마운트곡스(MtGox)는 미리 공개된 주소로 424,242 BTC를 이동시킨 트랜잭션을 보내 자금을 소유하고 있음을 증명했다. 2013년에 문제의 다른 측면인 사용자 예금의 총 크기를 증명하는 방법에 대한 논의가 시작되었습니다. 사용자의 보증금이 X(부채 증명)와 같다는 것을 증명하고 X 토큰(자산 증명)에 대한 개인 키가 있음을 증명하면 지급 능력 증명을 제공합니다. 예금자.
예금 증빙을 제공하는 가장 쉬운 방법은 목록을 게시하는 것입니다. 모든 사용자는 목록에서 자신의 잔액을 확인할 수 있으며 누구나 전체 목록을 확인할 수 있습니다: (i) 각 잔액은 마이너스가 아니며, (ii) 총액은 신고된 금액입니다.
사용자에게 개인적으로 솔트 값을 나열하고 보냅니다. 그러나 이것조차도 균형과 분배를 누설합니다. 개인 정보 보호를 위해 후속 기술인 Merkle 트리 기술을 채택했습니다.
녹색: 찰리의 노드. 파란색: Charlie는 증명을 위해 노드를 받았습니다. 노란색: 루트 노드, 모두에게 공지됨
머클 트리 기술은 사용자 밸런스 테이블을 머클 합계 트리에 넣습니다. Merkle sum 트리에서 각 노드는 쌍입니다. 기본 리프 노드는 개별 사용자 잔액과 사용자 이름의 소금에 절인 해시를 나타냅니다. 각 상위 노드에서 잔액은 아래 두 노드의 잔액의 합이고 해시는 아래 두 노드의 해시입니다. 머클 증명과 마찬가지로 머클 합계 증명은 리프 노드에서 루트 노드까지의 경로에 있는 모든 자매 노드로 구성된 "가지"입니다.
# The function for computing a parent node given two child nodes
def combine_tree_nodes(L, R):
L_hash, L_balance = L
R_hash, R_balance = R
assert L_balance >= 0 and R_balance >= 0
new_node_hash = hash(
L_hash + L_balance.to_bytes( 32, 'big') +
R_hash + R_balance.to_bytes( 32, 'big')
)
return (new_node_hash, L_balance + R_balance)
# Builds a full Merkle tree. Stored in flattened form where
# node i is the parent of nodes 2 i and 2 i+ 1
def build_merkle_sum_tree(user_table: "List[(username, salt, balance)]"):
tree_size = get_next_power_of_ 2(len(user_table))
tree = (
[None] * tree_size +
[userdata_to_leaf(*user) for user in user_table] +
[EMPTY_LEAF for _ in range(tree_size - len(user_table))]
)
for i in range(tree_size - 1, 0, -1):
tree[i] = combine_tree_nodes(tree[i* 2 ], tree[i* 2+ 1 ])
return tree
# Root of a tree is stored at index 1 in the flattened form
def get_root(tree):
return tree[ 1 ]
# Gets a proof for a node at a particular index
def get_proof(tree, index):
branch_length = log 2(len(tree)) - 1
# ^ = bitwise xor, x ^ 1 = sister node of x
index_in_tree = index + len(tree) // 2
return [tree[(index_in_tree // 2**i) ^ 1 ] for i in range(branch_length)]
# Verifies a proof (duh)
def verify_proof(username, salt, balance, index, user_table_size, root, proof):
leaf = userdata_to_leaf(username, salt, balance)
branch_length = log 2(get_next_power_of_ 2(user_table_size)) - 1
for i in range(branch_length):
if index & ( 2**i):
leaf = combine_tree_nodes(proof[i], leaf)
else:
leaf = combine_tree_nodes(leaf, proof[i])
return leaf == root
첫째, 거래소는 각 사용자에게 잔액에 대한 Merkle sum 증명을 보냅니다. 그러면 사용자는 자신의 잔액이 총액의 일부로 올바르게 포함되었는지 확인할 수 있습니다. 간단한 샘플 코드는 여기에서 찾을 수 있습니다.
이 설계에서 개인정보 유출은 전체 대차대조표 공개보다 훨씬 낮고 Merkle 루트가 공개될 때마다 각 분기가 중단되어 개인정보 유출 위험을 더욱 줄일 수 있지만 여전히 일부 개인정보 유출 문제가 있습니다. Charlie는 알고 있습니다. 특정 한 사람의 잔액이 164 ETH이고 두 사용자 잔액의 합이 70 ETH인 등입니다. 여러 계정을 제어하는 공격자는 여전히 교환 사용자에 대해 많은 정보를 얻을 수 있습니다.
이 체계의 중요한 미묘함은 마이너스 잔액의 가능성입니다. 사용자 잔액이 1390 ETH이지만 준비금이 890 ETH인 교환이 트리의 어딘가에 있는 가짜 계정에 -500 ETH의 잔액을 추가하여 보충하려고 하면 차이점, 어떻게 해야 합니까? 이 가능성은 실제로 계획을 깨뜨리지 않으며, 이것이 우리가 일반 Merkle 트리 대신 의도적으로 Merkle sum 트리를 사용하는 이유입니다. Henry가 거래소에서 관리하는 가짜 계정이고 거래소에서 -500 ETH를 넣었다고 가정해 보겠습니다.
Greta의 확인은 통과하지 못할 것입니다. 교환이 -500 ETH의 잔액으로 Henry의 노드를 제공해야 할 때 잘못된 노드를 거부합니다. Eve와 Fred도 확인에 실패할 것입니다. Henry 위의 중간 노드의 잔액이 -230 ETH이므로 이 노드도 유효하지 않습니다! 남용이 감지되지 않도록 하기 위해 거래소는 트리의 오른쪽 절반이 잔액 증명을 위해 확인되지 않기를 바랄 뿐입니다.
거래소가 500 ETH를 가지고 잔고 증명을 확인하지 않거나 잔고 증명을 받지 못했다고 불평할 때 믿지 않는 사용자를 선별할 수 있다면 거래소는 이를 피할 수 있습니다. 그러나 교환은 Merkle sum 트리에서 이러한 사용자를 제외하여 동일한 효과를 얻을 수도 있습니다. 따라서 책임 증명 측면에서만 머클 트리 기술은 기본적으로 요구 사항을 충족합니다. 그러나 프라이버시 기능은 여전히 이상적이지 않습니다. satoshi나 wei를 독립 리프 노드로 사용하는 등 Merkle 트리를 더 미묘하게 사용하여 개선할 수 있습니다. 그러나 더 발전된 기술을 사용하면 훨씬 더 잘할 수 있습니다.
ZK-SNARK를 사용하여 개인 정보 보호 및 견고성 향상
ZK-SNARK는 강력한 기술입니다. ZK-SNARK가 암호화에 수행하는 작업은 인공 지능과 유사합니다. 즉, 다양한 문제를 해결하기 위해 수십 년 전에 개발된 다양한 전문 기술을 압도할 수 있는 범용 기술입니다. 물론 우리는 ZK-SNARK를 사용하여 부채 증명 프로토콜에서 프라이버시를 크게 단순화하고 개선할 수 있습니다.
우리는 단순히 모든 사용자의 예치금을 Merkle 트리(또는 더 간단한 KZG 약속)에 넣고 ZK-SNARK를 사용하여 트리의 모든 잔고가 음수가 아님을 증명하고 청구된 가치를 더할 수 있습니다. 프라이버시를 위해 해싱 레이어를 추가하면 각 사용자에게 전송되는 Merkle 포크(또는 KZG 증명)는 다른 사용자의 잔액을 공개하지 않습니다.
KZG 약정을 사용하는 것은 "자매 노드"를 증거로 제공할 필요가 없고 간단한 ZK-SNARK를 사용하여 잔액 합계를 증명할 수 있고 각 잔액이 음수가 아니므로 개인 정보 유출을 방지하는 방법입니다.
전용 ZK-SNARK를 통해 위 KZG의 잔액 합계와 음수가 아님을 증명할 수 있습니다. 다음은 간단한 예입니다. 우리는 "사용자 잔고의 모든 비트를 구성"하는 보조 다항식 I(x)를 도입합니다(예를 들어 잔고가 2 15 미만이라고 가정). 여기서 모든 16번째 위치는 실제 total is equal to the total is equal to the value will be 0. z가 차수 128의 원시근이면 방정식이 유지됨을 증명할 수 있습니다.
[ 1 ] 번역가의 주: 이 다항 방정식의 해석.
이 방정식을 다항식 보정으로 변환한 다음 ZK-SNARK로 변환하는 방법은 여기 및 다른 곳에서 ZK-SNARK에 대한 내 기사를 참조할 수 있습니다. 이것은 최적의 프로토콜은 아니지만 이러한 암호화 증명을 이해할 수 있게 만듭니다!
몇 가지 추가 방정식만으로 구속 시스템을 보다 복잡한 설정에 적용할 수 있습니다. 예를 들어, 레버리지 거래 시스템에서 개별 사용자가 마이너스 잔액을 갖는 것은 허용되지만 부채를 충당할 수 있는 충분한 담보 자산이 있는 경우에만 가능합니다. SNARK는 이 복잡한 제약을 증명하는 데 사용될 수 있으며, 사용자에게 교환이 특정 사용자를 규칙에서 비밀리에 면제할 수 없음을 보장하여 사용자 자산을 위험에 빠뜨릴 수 있습니다.장기적으로 이 ZK 책임 증명의 유용성은 거래소의 사용자 예금에 국한되지 않고 더 넓은 범위의 대출 시나리오에서도 사용될 수 있습니다. 대출을 받는 사람은 기록을 다항식이나 해당 대출이 포함된 트리에 입력하고 루트는 온체인에 게시됩니다. 이를 통해 대출을 원하는 사람은 대출 기관이 다른 대출을 너무 많이 받지 않았다는 영지식 증명을 제공할 수 있습니다. 결국 법적 혁신을 통해 이러한 방식으로 약정된 대출이 약정되지 않은 대출보다 더 높은 우선 순위를 가질 수 있습니다. 이것은 우리와 함께"분권화된 사회: Web3의 영혼을 찾아서"
논의된 것과 일치하는 아이디어: 온체인 부정적인 평판의 개념은 어떤 형태의 "영혼에 묶인 토큰"을 통해 가능합니다.
자산 증명
자산 증명의 가장 간단한 버전은 위에서 본 프로토콜입니다. X 토큰을 보유하고 있음을 증명하기 위해 미리 결정된 시간에 X 토큰을 이동하거나 트랜잭션에서 "이 자금은 Binance에 속합니다"라는 메시지를 전달합니다. 거래 수수료 지불을 피하기 위해 오프 체인 메시지에 서명할 수 있습니다. 비트코인과 이더리움 모두 오프체인 서명 메시지 표준을 가지고 있습니다.
이 간단한 자산 증명 기술에는 두 가지 실질적인 문제가 있습니다.
차가운 지갑 취급
담보 재사용
보안상의 이유로 대부분의 거래소는 대부분의 사용자 자금을 콜드 월렛에 저장합니다. 오프라인 컴퓨터에서는 트랜잭션을 수동으로 서명하고 인터넷으로 전송해야 합니다. 이 접근 방식은 일반적입니다. 영구 오프라인 컴퓨터에 개인 자금을 저장하는 데 사용한 콜드 월렛은 서명된 거래가 포함된 QR 코드를 생성한 다음 휴대폰으로 스캔합니다. 막대한 양의 자금으로 인해 거래소에서 사용하는 보안 프로토콜은 더 복잡해지며 단일 장치가 해킹되어 키 유출 가능성을 더욱 줄이기 위해 여러 장치 간의 다자간 계산이 포함되는 경우가 많습니다. 이러한 맥락에서 주소 제어를 증명하기 위해 추가 메시지를 생성하는 것조차 비용이 많이 드는 작업입니다!
교환은 다음 방법을 사용할 수 있습니다.
● 일부 장기 공용 주소를 유지합니다. 거래소는 여러 개의 주소를 생성하고 각 주소의 소유권 증명을 한 번만 발행하고 이 주소를 재사용합니다. 이것은 보안 및 개인 정보 보호 측면에서 몇 가지 제한 사항을 추가하지만 가장 쉬운 솔루션입니다.
● 많은 주소를 보유하고 몇 개의 주소를 무작위로 증명합니다. 거래소는 많은 주소를 보유하고 있으며 각 주소를 한 번만 사용하고 단일 거래 후에는 사용하지 않을 수도 있습니다. 이 경우 거래소는 때때로 일부 주소가 무작위로 선택된다는 합의가 필요하며, 거래소는 소유권을 증명하기 위해 "개방"해야 합니다. 일부 거래소는 유사한 작업에 이미 감사자를 사용하고 있지만 원칙적으로 이 기술은 완전히 자동화된 절차로 전환될 수 있습니다.
● 보다 복잡한 ZKP 접근 방식. 예를 들어, 거래소는 모든 주소에 대해 1/2 다중 서명을 설정할 수 있습니다. 이 주소 중 하나는 다른 키를 갖고 다른 하나는 복잡하지만 안전한 방식으로 동일한 키를 가집니다(예: 12/16 다중 서명). 중요한 비상 백업 블라인드 버전을 저장합니다. 프라이버시를 보호하고 전체 주소 공개를 피하기 위해 거래소는 블록체인에서 영지식 증명을 실행하여 해당 형식으로 온체인 주소의 총 잔액을 증명할 수도 있습니다.
또 다른 주요 관심사는 담보 재사용을 방지하는 것입니다. 준비금을 증명하기 위해 서로 간에 담보를 앞뒤로 이전하는 것은 종종 교환이 쉬우므로 사실상 지급 불능 상태에서 벗어날 수 있습니다. 이상적으로는 각 블록 후에 업데이트된 증명과 함께 실시간으로 지급 가능성 증명을 수행해야 합니다. 그것이 실용적이지 않다면 다음으로 가장 좋은 방법은 매주 화요일 오후 2시(UTC)에 매장량을 증명하는 것과 같이 증명을 위한 교환 사이에 고정된 시간을 조정하는 것입니다.
마지막 질문입니다. 자산을 법정화폐로 인증할 수 있습니까? 거래소는 암호화폐를 보유할 뿐만 아니라 은행 시스템 내 법정 화폐도 보유합니다. 이와 관련하여 대답은 '예'이지만 그러한 프로그램은 필연적으로 "명목 화폐" 신뢰 모델에 의존합니다. 은행 자체가 잔액을 인증할 수 있고 감사인이 대차대조표 등을 인증할 수 있습니다. 명목 화폐는 암호화 방식으로 검증할 수 없다는 점을 감안할 때 이것이 이 프레임워크 내에서 가장 좋은 솔루션이며 여전히 가치가 있습니다.
또 다른 접근 방식은 Entity A를 Entity B에서 분리하여 A가 거래소를 운영하고 자산이 지원하는 스테이블 코인인 USDC를 처리하는 것입니다. 이 경우 B는 USDC 자체입니다. USDC의 "책임"은 체인의 ERC 20 토큰뿐이므로 책임 증명은 "쉽게" 얻을 수 있으며 자산 증명 문제만 처리하면 됩니다.
플라즈마 및 유효성 검사: 관리되지 않는 CEX를 달성할 수 있습니까?
우리가 한 단계 더 나아가고 싶다고 가정해 보겠습니다. 우리는 거래소가 사용자에게 갚을 만큼 충분한 자금을 가지고 있다는 것을 증명하고 싶지 않습니다. 대신 거래가 사용자의 자금을 훔치는 것을 완전히 방지하고자 합니다.
최초의 얼리 어답터 중 하나는 2017년과 2018년에 Ethereum 연구 커뮤니티에서 인기를 얻은 확장 솔루션인 Plasma입니다. 플라즈마는 균형을 독립적인 "토큰" 세트로 분할하여 작동하며, 각각 인덱스를 할당하고 플라즈마 블록의 머클 트리에서 특정 위치에 배치합니다. 유효한 토큰 전송이 발생하려면 트랜잭션이 트리의 올바른 위치에 배치되어야 하며 트리의 루트가 체인에 게시됩니다.
Plasma 버전의 미니멀한 다이어그램. 토큰은 철회 시 플라즈마 프로토콜의 규칙을 시행하는 스마트 계약에 보관됩니다.
OmiseGo는 이 프로토콜을 기반으로 분산형 교환을 만들려고 시도했지만 그 이후로 그들은 낙관적 롤업 프로젝트 Optimism과 함께 Plasma Group과 같은 다른 것들로 이동했습니다.
2018년 플라즈마의 한계(예: 증거 토큰 조각 모음)에 대한 논의는 플라즈마의 생존 가능성에 근본적인 의문을 제기했습니다. 2018년 플라즈마에 대한 논의가 절정에 달한 이후 ZK-SNARK는 확장 관련 사용 사례에 점점 더 적합해졌습니다. 위에서 말했듯이 ZK-SNARK는 모든 것을 변경했습니다.
Plasma의 최신 버전은 Starkware가 validium이라고 부르는 것입니다. 데이터가 오프체인에 보관된다는 점을 제외하면 기본적으로 ZK-rollup과 동일합니다. 이 구성은 많은 사용 사례에 적용할 수 있으며 중앙 집중식 서버가 코드를 올바르게 실행했음을 증명해야 하는 모든 시나리오에 적용할 수 있습니다. 발리디움에서 운영자는 자금을 훔칠 수 없지만 구체적인 구현 세부 사항에 따라 운영자가 사라지면 일부 사용자 자금이 멈출 수 있습니다.
이제는 멋져 보입니다. CEX와 DEX는 둘 중 하나가 아닙니다. 효율성과 같은 몇 가지 이점을 얻을 수 있는 다양한 형태의 하이브리드 중앙화를 포함하여 다양한 옵션이 있음이 밝혀졌지만 여전히 많은 암호화폐가 있습니다. 중앙 집중식 운영자에 의한 대부분의 악의적인 행동을 방지합니다.
그러나 남아 있는 근본적인 질문인 사용자 오류를 처리하는 방법에 대해서도 생각해 볼 가치가 있습니다. 지금까지 가장 중요한 오류 유형은 다음과 같습니다. 사용자가 비밀번호를 잊어버리거나 기기를 분실하거나 해킹당하거나 계정에 대한 액세스 권한을 잃으면 어떻게 됩니까?
거래소는 먼저 이메일 복구를 활용하고 실패할 경우 KYC를 통해 더 복잡한 복구를 활용하여 이 문제를 해결할 수 있습니다. 그러나 이러한 문제를 해결하기 위해서는 거래소에서 이러한 토큰을 실제로 제어해야 합니다. 사용자 자금을 합리적으로 회수할 수 있으려면 거래소는 이유 없이 사용자 자금을 훔치는 데 사용할 수 있는 것과 동일한 권한을 가져야 합니다. 이것은 피할 수 없는 절충안입니다.
이상적인 장기 솔루션은 자체 보관에 의존하는 것이며 사용자는 향후 다중 서명 및 소셜 복구 지갑과 같은 기술을 사용하여 긴급 상황에 대처할 수 있습니다. 단기적으로는 비용과 이점이 다른 두 가지 확실한 대안이 있습니다.
또 다른 중요한 문제는 크로스 체인 지원입니다. 거래소는 다양한 체인을 지원해야 하고 플라즈마 및 발리디움과 같은 시스템은 다양한 플랫폼을 지원하기 위해 다양한 언어로 코딩되어야 하며 현재 형식은 일부 플랫폼에서 사용할 수 없습니다(특히 기술 업그레이드와 표준화를 통해 해결될 것으로 예상되지만, 단기적으로는 수탁 거래소가 오늘날에도 계속 유지되는 또 다른 이유입니다.
결론: 앞으로 더 나은 거래소를 기대합니다
단기적으로 교환에는 보관 교환과 비 보관 교환의 두 가지 명확한 범주가 있습니다. 오늘날 후자의 범주는 Uniswap과 같은 DEX이며, 미래에는 사용자 자금이 validium 스마트 계약과 유사한 방식으로 유지되는 암호화에 의해 제한되는 CEX를 볼 수도 있습니다. 우리는 또한 암호 화폐가 아닌 명목 화폐 취급을 신뢰하는 세미 커스터디 거래소를 볼 수 있습니다.
두 가지 유형의 교환이 여기에 있으며 보관 교환의 보안을 위해 이전 버전과의 호환성을 개선하는 가장 쉬운 방법은 보유 증명을 추가하는 것입니다. 여기에는 자산 증명과 부채 증명의 조합이 포함됩니다. 두 가지 모두를 위한 좋은 프로토콜을 설계하는 데는 여전히 몇 가지 과제가 있지만, 우리는 모든 교환이 이익을 얻을 수 있도록 두 기술을 함께 사용하고 오픈 소스 소프트웨어 및 프로그램을 최대한 많이 추진할 수 있고 추진해야 합니다.
장기적으로는 적어도 암호화폐에 관해서는 모든 교환이 비수탁적인 방향으로 나아가기를 바랍니다. 지갑 복구가 존재할 것이며 적은 자금을 가진 신규 사용자 및 법적인 이유로 그러한 조치가 필요한 기관을 위해 고도로 중앙 집중식 복구 옵션이 필요할 수 있지만 이는 거래소 내에서가 아니라 지갑 계층에서 수행될 수 있습니다. 법정화폐 측면에서는 USDC와 같은 자산유동화 스테이블코인의 네이티브 펀드 입출금 과정을 통해 전통적인 은행 시스템과 암호화폐 생태계 간의 이동을 완성할 수 있다. 그러나 아직 갈 길이 멀다.
[1] 번역가의 메모:
➤ 16자리마다 사용자를 나타냅니다(처음 15자리는 사용자의 잔액을 나타내고 마지막 숫자는 사용자의 잔액 합계와 지금까지의 명세서의 차액을 나타냄). 위의 예는 두 명의 사용자를 나타냅니다(독자는 여기에서 통찰력이 필요함).
➤ 청구된 평균 사용자 잔액: 185
➤ 사용자 1의 잔액: 20 -> 000 0000 0001 0100
차이: 20 - 185 = -165
➤ 사용자 2의 잔액: 50 -> 000 0101 0011 0010
차이: -165 + 50 -185 = -300
➤ 모든 사용자를 통과한 후 마지막 사용자의 잔액 요구 사항은 0입니다.
➤ 4개의 방정식에 대한 설명
방정식 1: 재귀의 초기 값은 0입니다.
방정식 2: 각 사용자 잔액은 KZG 약정과 일치해야 합니다.방정식 3: 각 사용자의 잔액에 대한 재귀 공식, 제약 잔액은 >= 0이고< 2 14 ,
< 2 · 14 (수식 3에 따르면 재귀 공식은 14개의 값 I(zi)
원본 링크
