From 503999eaf25e5db9d316b0b242c4ed87ae6ccba7 Mon Sep 17 00:00:00 2001 From: Developer Date: Sat, 29 Nov 2025 07:13:38 -0800 Subject: [PATCH] docs: Add detailed DDD + Hexagonal architecture documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add comprehensive DDD tactical patterns (Entity, Value Object, Aggregate, Repository, Domain Service) - Add Hexagonal Architecture details (Input/Output Ports, Adapters) - Include code examples for each pattern - Add dependency injection explanation - Update section numbering ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- backend/mpc-system/docs/01-architecture.md | 511 ++++++++++++++++++++- 1 file changed, 488 insertions(+), 23 deletions(-) diff --git a/backend/mpc-system/docs/01-architecture.md b/backend/mpc-system/docs/01-architecture.md index 46e7ba65..260bfb9f 100644 --- a/backend/mpc-system/docs/01-architecture.md +++ b/backend/mpc-system/docs/01-architecture.md @@ -2,7 +2,7 @@ ## 1. ็ณป็ปŸๆฆ‚่ฟฐ -ๆœฌ็ณป็ปŸๆ˜ฏไธ€ไธชๅŸบไบŽๅคšๆ–นๅฎ‰ๅ…จ่ฎก็ฎ— (MPC) ็š„ๅˆ†ๅธƒๅผ้—จ้™็ญพๅ็ณป็ปŸ๏ผŒๆ”ฏๆŒ t-of-n ้˜ˆๅ€ผ็ญพๅๆ–นๆกˆใ€‚็ณป็ปŸ้‡‡็”จๅพฎๆœๅŠกๆžถๆž„๏ผŒไฝฟ็”จ Go ่ฏญ่จ€ๅผ€ๅ‘๏ผŒๅŸบไบŽ bnb-chain/tss-lib ๅฎž็Žฐ TSS (Threshold Signature Scheme) ๅ่ฎฎใ€‚ +ๆœฌ็ณป็ปŸๆ˜ฏไธ€ไธชๅŸบไบŽๅคšๆ–นๅฎ‰ๅ…จ่ฎก็ฎ— (MPC) ็š„ๅˆ†ๅธƒๅผ้—จ้™็ญพๅ็ณป็ปŸ๏ผŒๆ”ฏๆŒ t-of-n ้˜ˆๅ€ผ็ญพๅๆ–นๆกˆใ€‚็ณป็ปŸ้‡‡็”จ **DDD (้ข†ๅŸŸ้ฉฑๅŠจ่ฎพ่ฎก) + ๅ…ญ่พนๅฝขๆžถๆž„ (Hexagonal Architecture) + ๅพฎๆœๅŠก** ็š„ๆžถๆž„ๆจกๅผ๏ผŒไฝฟ็”จ Go ่ฏญ่จ€ๅผ€ๅ‘๏ผŒๅŸบไบŽ bnb-chain/tss-lib ๅฎž็Žฐ TSS (Threshold Signature Scheme) ๅ่ฎฎใ€‚ ### 1.1 ๆ ธๅฟƒ็‰นๆ€ง @@ -11,6 +11,7 @@ - **ECDSA secp256k1**: ไธŽไปฅๅคชๅŠ/ๆฏ”็‰นๅธๅ…ผๅฎน็š„็ญพๅ็ฎ—ๆณ• - **้ซ˜ๅฎ‰ๅ…จๆ€ง**: ๅฏ†้’ฅๅˆ†็‰‡ๅŠ ๅฏ†ๅญ˜ๅ‚จ๏ผŒๅ•็‚นๆณ„้œฒไธๅฝฑๅ“ๅฎ‰ๅ…จๆ€ง - **ๅพฎๆœๅŠกๆžถๆž„**: ๅฏ็‹ฌ็ซ‹ๆ‰ฉๅฑ•ๅ’Œ้ƒจ็ฝฒ +- **Clean Architecture**: DDD + ๅ…ญ่พนๅฝขๆžถๆž„๏ผŒ้ข†ๅŸŸ้€ป่พ‘ไธŽๅŸบ็ก€่ฎพๆ–ฝ่งฃ่€ฆ ### 1.2 ๆŠ€ๆœฏๆ ˆ @@ -24,10 +25,474 @@ | ๆถˆๆฏ้˜Ÿๅˆ— | RabbitMQ | | ๆœๅŠกๅ‘็Žฐ | Consul | | ๅฎนๅ™จๅŒ– | Docker + Docker Compose | +| ๆžถๆž„ๆจกๅผ | DDD + Hexagonal + Microservices | -## 2. ็ณป็ปŸๆžถๆž„ +### 1.3 ๆžถๆž„่ฎพ่ฎกๅŽŸๅˆ™ -### 2.1 ๆ•ดไฝ“ๆžถๆž„ๅ›พ +| ๅŽŸๅˆ™ | ่ฏดๆ˜Ž | +|------|------| +| **ไพ่ต–ๅ€’็ฝฎ** | ๅ†…ๅฑ‚ๅฎšไน‰ๆŽฅๅฃ๏ผŒๅค–ๅฑ‚ๅฎž็Žฐ๏ผ›ไพ่ต–ๆŒ‡ๅ‘ๅ†…ๅฑ‚ | +| **้ข†ๅŸŸ้š”็ฆป** | Domain ๅฑ‚้›ถๅค–้ƒจไพ่ต–๏ผŒ็บฏไธšๅŠก้€ป่พ‘ | +| **็ซฏๅฃ้€‚้…** | ้€š่ฟ‡ Port/Adapter ๆจกๅผ่งฃ่€ฆ I/O | +| **ๆœๅŠก่‡ชๆฒป** | ๆฏไธชๅพฎๆœๅŠก็‹ฌ็ซ‹้ƒจ็ฝฒใ€็‹ฌ็ซ‹ๆ•ฐๆฎๅบ“ | +| **ๅ•ไธ€่Œ่ดฃ** | ๆฏไธชๆœๅŠกๅช่ดŸ่ดฃไธ€ไธชไธšๅŠก้ข†ๅŸŸ | + +## 2. ่ฝฏไปถๆžถๆž„ๆจกๅผ + +### 2.1 DDD + ๅ…ญ่พนๅฝขๆžถๆž„ + ๅพฎๆœๅŠก + +ๆœฌ็ณป็ปŸ้‡‡็”จไธ‰ๅฑ‚ๆžถๆž„ๆจกๅผ็š„็ป„ๅˆ๏ผš + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ ๅพฎๆœๅŠกๆžถๆž„ (Microservices) โ”‚ +โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ +โ”‚ โ”‚ Account Service โ”‚ โ”‚Session Coordinatorโ”‚ โ”‚ Message Router โ”‚ ... โ”‚ +โ”‚ โ”‚ (็‹ฌ็ซ‹้ƒจ็ฝฒ) โ”‚ โ”‚ (็‹ฌ็ซ‹้ƒจ็ฝฒ) โ”‚ โ”‚ (็‹ฌ็ซ‹้ƒจ็ฝฒ) โ”‚ โ”‚ +โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ–ผ โ–ผ โ–ผ โ”‚ +โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ +โ”‚ โ”‚ ๅ…ญ่พนๅฝขๆžถๆž„ (Hexagonal / Ports & Adapters) โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ Adapters (Input) โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚HTTP Handler โ”‚ โ”‚gRPC Handler โ”‚ โ”‚ ๆถˆๆฏๆถˆ่ดน่€… โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ–ผ โ–ผ โ–ผ โ”‚ โ”‚ +โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ Application Layer โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ Input Ports โ”‚ โ”‚ Use Cases โ”‚ โ”‚ Output Ports โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ (ๆŽฅๅฃๅฎšไน‰) โ”‚ โ”‚ (ไธšๅŠก็ผ–ๆŽ’) โ”‚ โ”‚ (ๆŽฅๅฃๅฎšไน‰) โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ–ผ โ–ผ โ–ผ โ”‚ โ”‚ +โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ Domain Layer (DDD) โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ Entities โ”‚ โ”‚Value Objects โ”‚ โ”‚Domain Servicesโ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ (ๅฎžไฝ“) โ”‚ โ”‚ (ๅ€ผๅฏน่ฑก) โ”‚ โ”‚ (้ข†ๅŸŸๆœๅŠก) โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ Repositories โ”‚ โ”‚ Aggregates โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ (ไป“ๅ‚จๆŽฅๅฃ) โ”‚ โ”‚ (่šๅˆๆ น) โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ–ผ โ–ผ โ–ผ โ”‚ โ”‚ +โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ Adapters (Output) โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ PostgreSQL โ”‚ โ”‚ Redis โ”‚ โ”‚ RabbitMQ โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ”‚ Repo โ”‚ โ”‚ Cache โ”‚ โ”‚ Publisher โ”‚ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ +โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ +โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### 2.2 ๅ•ไธชๅพฎๆœๅŠกๅ†…้ƒจ็ป“ๆž„ + +ๆฏไธชๅพฎๆœๅŠก้‡‡็”จๅ…ญ่พนๅฝขๆžถๆž„๏ผŒๅ†…้ƒจๅˆ†ไธบไธ‰ๅฑ‚๏ผš + +``` +service/ +โ”œโ”€โ”€ domain/ # ้ข†ๅŸŸๅฑ‚ (ๆœ€ๅ†…ๅฑ‚๏ผŒ้›ถๅค–้ƒจไพ่ต–) +โ”‚ โ”œโ”€โ”€ entities/ # ๅฎžไฝ“ - ๆœ‰ๅ”ฏไธ€ๆ ‡่ฏ†็š„้ข†ๅŸŸๅฏน่ฑก +โ”‚ โ”œโ”€โ”€ value_objects/ # ๅ€ผๅฏน่ฑก - ๆ— ๆ ‡่ฏ†็š„ไธๅฏๅ˜ๅฏน่ฑก +โ”‚ โ”œโ”€โ”€ repositories/ # ไป“ๅ‚จๆŽฅๅฃ - ้ข†ๅŸŸๅฎšไน‰๏ผŒ้€‚้…ๅ™จๅฎž็Žฐ +โ”‚ โ””โ”€โ”€ services/ # ้ข†ๅŸŸๆœๅŠก - ่ทจๅฎžไฝ“็š„ไธšๅŠก้€ป่พ‘ +โ”‚ +โ”œโ”€โ”€ application/ # ๅบ”็”จๅฑ‚ (ไธญ้—ดๅฑ‚๏ผŒ็ผ–ๆŽ’ไธšๅŠก็”จไพ‹) +โ”‚ โ”œโ”€โ”€ ports/ # ็ซฏๅฃๅฎšไน‰ +โ”‚ โ”‚ โ”œโ”€โ”€ input/ # ๅ…ฅ็ซ™็ซฏๅฃ - ๅฎšไน‰็”จไพ‹ๆŽฅๅฃ +โ”‚ โ”‚ โ””โ”€โ”€ output/ # ๅ‡บ็ซ™็ซฏๅฃ - ๅฎšไน‰ๅŸบ็ก€่ฎพๆ–ฝๆŽฅๅฃ +โ”‚ โ””โ”€โ”€ use_cases/ # ็”จไพ‹ๅฎž็Žฐ - ไธšๅŠกๆต็จ‹็ผ–ๆŽ’ +โ”‚ +โ”œโ”€โ”€ adapters/ # ้€‚้…ๅ™จๅฑ‚ (ๆœ€ๅค–ๅฑ‚๏ผŒๅค„็† I/O) +โ”‚ โ”œโ”€โ”€ input/ # ๅ…ฅ็ซ™้€‚้…ๅ™จ +โ”‚ โ”‚ โ”œโ”€โ”€ http/ # HTTP/REST ๅค„็†ๅ™จ +โ”‚ โ”‚ โ””โ”€โ”€ grpc/ # gRPC ๅค„็†ๅ™จ +โ”‚ โ””โ”€โ”€ output/ # ๅ‡บ็ซ™้€‚้…ๅ™จ +โ”‚ โ”œโ”€โ”€ postgres/ # PostgreSQL ไป“ๅ‚จๅฎž็Žฐ +โ”‚ โ”œโ”€โ”€ redis/ # Redis ็ผ“ๅญ˜ๅฎž็Žฐ +โ”‚ โ””โ”€โ”€ rabbitmq/ # RabbitMQ ๆถˆๆฏๅ‘ๅธƒ +โ”‚ +โ””โ”€โ”€ cmd/server/ # ๆœๅŠกๅ…ฅๅฃ - ไพ่ต–ๆณจๅ…ฅๅ’ŒๅฏๅŠจ + โ””โ”€โ”€ main.go +``` + +### 2.3 DDD ๆˆ˜ๆœฏๆจกๅผๅฎž็Žฐ + +#### 2.3.1 ๅฎžไฝ“ (Entity) + +ๆœ‰ๅ”ฏไธ€ๆ ‡่ฏ†็š„้ข†ๅŸŸๅฏน่ฑก๏ผŒๅฐ่ฃ…ไธšๅŠก่ง„ๅˆ™๏ผš + +```go +// services/account/domain/entities/account.go +type Account struct { + ID value_objects.AccountID // ๅ”ฏไธ€ๆ ‡่ฏ† + Username string + Email string + PublicKey []byte + Status value_objects.AccountStatus + ThresholdN int + ThresholdT int + CreatedAt time.Time + UpdatedAt time.Time +} + +// ไธšๅŠกๆ–นๆณ•ๅฐ่ฃ…ๅœจๅฎžไฝ“ๅ†… +func (a *Account) Suspend() error { + if a.Status == value_objects.AccountStatusRecovering { + return ErrAccountInRecovery + } + a.Status = value_objects.AccountStatusSuspended + a.UpdatedAt = time.Now().UTC() + return nil +} + +func (a *Account) CanLogin() bool { + return a.Status.CanLogin() +} +``` + +#### 2.3.2 ๅ€ผๅฏน่ฑก (Value Object) + +ๆ— ๆ ‡่ฏ†็š„ไธๅฏๅ˜ๅฏน่ฑก๏ผŒ้€š่ฟ‡ๅ€ผ็›ธ็ญ‰ๆ€งๆฏ”่พƒ๏ผš + +```go +// services/account/domain/value_objects/account_id.go +type AccountID struct { + value uuid.UUID +} + +func NewAccountID() AccountID { + return AccountID{value: uuid.New()} +} + +func (id AccountID) String() string { + return id.value.String() +} + +func (id AccountID) Equals(other AccountID) bool { + return id.value == other.value +} + +// services/session-coordinator/domain/value_objects/session_status.go +type SessionStatus string + +const ( + SessionStatusCreated SessionStatus = "created" + SessionStatusWaiting SessionStatus = "waiting" + SessionStatusInProgress SessionStatus = "in_progress" + SessionStatusCompleted SessionStatus = "completed" + SessionStatusFailed SessionStatus = "failed" +) + +func (s SessionStatus) CanTransitionTo(target SessionStatus) bool { + // ็Šถๆ€่ฝฌๆข่ง„ๅˆ™ + transitions := map[SessionStatus][]SessionStatus{ + SessionStatusCreated: {SessionStatusWaiting, SessionStatusFailed}, + SessionStatusWaiting: {SessionStatusInProgress, SessionStatusFailed}, + SessionStatusInProgress: {SessionStatusCompleted, SessionStatusFailed}, + } + for _, allowed := range transitions[s] { + if allowed == target { + return true + } + } + return false +} +``` + +#### 2.3.3 ่šๅˆ (Aggregate) + +่šๅˆๆ น็ฎก็†ไธ€็ป„็›ธๅ…ณๅฎžไฝ“็š„ไธ€่‡ดๆ€ง่พน็•Œ๏ผš + +```go +// services/session-coordinator/domain/entities/mpc_session.go +// MPCSession ๆ˜ฏ่šๅˆๆ น๏ผŒ็ฎก็† Participants +type MPCSession struct { + ID uuid.UUID + Type SessionType + Status SessionStatus + ThresholdT int + ThresholdN int + Participants []Participant // ๅญๅฎžไฝ“ + CreatedAt time.Time +} + +// ่šๅˆๆ น่ดŸ่ดฃ็ปดๆŠคๅ†…้ƒจไธ€่‡ดๆ€ง +func (s *MPCSession) AddParticipant(p Participant) error { + if len(s.Participants) >= s.ThresholdN { + return ErrSessionFull + } + if s.Status != SessionStatusWaiting { + return ErrInvalidSessionStatus + } + s.Participants = append(s.Participants, p) + return nil +} + +func (s *MPCSession) AllParticipantsReady() bool { + if len(s.Participants) < s.ThresholdN { + return false + } + for _, p := range s.Participants { + if p.Status != ParticipantStatusReady { + return false + } + } + return true +} +``` + +#### 2.3.4 ไป“ๅ‚จๆŽฅๅฃ (Repository) + +้ข†ๅŸŸๅฑ‚ๅฎšไน‰ๆŽฅๅฃ๏ผŒ้€‚้…ๅ™จๅฑ‚ๅฎž็Žฐ๏ผš + +```go +// services/account/domain/repositories/account_repository.go +type AccountRepository interface { + Save(ctx context.Context, account *entities.Account) error + FindByID(ctx context.Context, id value_objects.AccountID) (*entities.Account, error) + FindByUsername(ctx context.Context, username string) (*entities.Account, error) + FindByEmail(ctx context.Context, email string) (*entities.Account, error) + Update(ctx context.Context, account *entities.Account) error + Delete(ctx context.Context, id value_objects.AccountID) error +} +``` + +#### 2.3.5 ้ข†ๅŸŸๆœๅŠก (Domain Service) + +่ทจๅฎžไฝ“็š„ไธšๅŠก้€ป่พ‘๏ผš + +```go +// services/session-coordinator/domain/services/session_coordinator.go +type SessionCoordinatorService struct { + sessionRepo repositories.SessionRepository +} + +func (s *SessionCoordinatorService) ValidateThreshold(t, n int) error { + if t < 1 || t > n { + return ErrInvalidThreshold + } + if n < 2 { + return ErrInvalidPartyCount + } + return nil +} +``` + +### 2.4 ๅ…ญ่พนๅฝขๆžถๆž„็ซฏๅฃไธŽ้€‚้…ๅ™จ + +#### 2.4.1 ๅ…ฅ็ซ™็ซฏๅฃ (Input Port) + +ๅฎšไน‰็”จไพ‹ๆŽฅๅฃ๏ผš + +```go +// services/account/application/ports/input_ports.go +type CreateAccountInput struct { + Username string + Email string + PublicKey []byte + ThresholdN int + ThresholdT int +} + +type CreateAccountOutput struct { + Account *entities.Account +} + +// ็”จไพ‹ๆŽฅๅฃ +type CreateAccountPort interface { + Execute(ctx context.Context, input CreateAccountInput) (*CreateAccountOutput, error) +} +``` + +#### 2.4.2 ๅ‡บ็ซ™็ซฏๅฃ (Output Port) + +ๅฎšไน‰ๅŸบ็ก€่ฎพๆ–ฝๆŽฅๅฃ๏ผš + +```go +// services/session-coordinator/application/ports/output/session_storage_port.go +type SessionStoragePort interface { + Save(ctx context.Context, session *entities.MPCSession) error + FindByID(ctx context.Context, id uuid.UUID) (*entities.MPCSession, error) + Update(ctx context.Context, session *entities.MPCSession) error +} + +// services/session-coordinator/application/ports/output/message_broker_port.go +type MessageBrokerPort interface { + PublishSessionEvent(ctx context.Context, event SessionEvent) error + PublishPartyNotification(ctx context.Context, partyID string, msg []byte) error +} +``` + +#### 2.4.3 ็”จไพ‹ๅฎž็Žฐ (Use Case) + +็ผ–ๆŽ’ไธšๅŠกๆต็จ‹๏ผš + +```go +// services/account/application/use_cases/create_account.go +type CreateAccountUseCase struct { + accountRepo repositories.AccountRepository + eventPub ports.EventPublisherPort +} + +func (uc *CreateAccountUseCase) Execute( + ctx context.Context, + input ports.CreateAccountInput, +) (*ports.CreateAccountOutput, error) { + // 1. ๅˆ›ๅปบ้ข†ๅŸŸๅฎžไฝ“ + account := entities.NewAccount( + input.Username, + input.Email, + input.PublicKey, + input.ThresholdN, + input.ThresholdT, + ) + + // 2. ้ชŒ่ฏไธšๅŠก่ง„ๅˆ™ + if err := account.Validate(); err != nil { + return nil, err + } + + // 3. ๆŒไน…ๅŒ– + if err := uc.accountRepo.Save(ctx, account); err != nil { + return nil, err + } + + // 4. ๅ‘ๅธƒ้ข†ๅŸŸไบ‹ไปถ + uc.eventPub.Publish(ctx, events.AccountCreated{AccountID: account.ID}) + + return &ports.CreateAccountOutput{Account: account}, nil +} +``` + +#### 2.4.4 ๅ…ฅ็ซ™้€‚้…ๅ™จ (Input Adapter) + +HTTP/gRPC ๅค„็†ๅ™จ๏ผš + +```go +// services/account/adapters/input/http/account_handler.go +type AccountHandler struct { + createAccountUC ports.CreateAccountPort + loginUC ports.LoginPort +} + +func (h *AccountHandler) CreateAccount(c *gin.Context) { + var req CreateAccountRequest + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(400, gin.H{"error": err.Error()}) + return + } + + output, err := h.createAccountUC.Execute(c.Request.Context(), ports.CreateAccountInput{ + Username: req.Username, + Email: req.Email, + PublicKey: req.PublicKey, + ThresholdN: req.ThresholdN, + ThresholdT: req.ThresholdT, + }) + if err != nil { + c.JSON(500, gin.H{"error": err.Error()}) + return + } + + c.JSON(201, output) +} +``` + +#### 2.4.5 ๅ‡บ็ซ™้€‚้…ๅ™จ (Output Adapter) + +ๆ•ฐๆฎๅบ“/็ผ“ๅญ˜ๅฎž็Žฐ๏ผš + +```go +// services/account/adapters/output/postgres/account_repo.go +type PostgresAccountRepository struct { + db *sql.DB +} + +func (r *PostgresAccountRepository) Save(ctx context.Context, account *entities.Account) error { + query := `INSERT INTO accounts (id, username, email, public_key, status, threshold_n, threshold_t, created_at) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8)` + _, err := r.db.ExecContext(ctx, query, + account.ID.String(), + account.Username, + account.Email, + account.PublicKey, + account.Status, + account.ThresholdN, + account.ThresholdT, + account.CreatedAt, + ) + return err +} + +func (r *PostgresAccountRepository) FindByID(ctx context.Context, id value_objects.AccountID) (*entities.Account, error) { + query := `SELECT id, username, email, public_key, status, threshold_n, threshold_t, created_at, updated_at + FROM accounts WHERE id = $1` + row := r.db.QueryRowContext(ctx, query, id.String()) + // ... scan and return +} +``` + +### 2.5 ไพ่ต–ๆณจๅ…ฅ (Dependency Injection) + +ๅœจ main.go ไธญ็ป„่ฃ…ไพ่ต–๏ผš + +```go +// services/account/cmd/server/main.go +func main() { + // ๅŸบ็ก€่ฎพๆ–ฝ + db := connectDatabase() + redisClient := connectRedis() + rabbitConn := connectRabbitMQ() + + // ๅ‡บ็ซ™้€‚้…ๅ™จ (ๅฎž็Žฐ็ซฏๅฃ) + accountRepo := postgres.NewAccountRepository(db) + cacheAdapter := redis.NewCacheAdapter(redisClient) + eventPublisher := rabbitmq.NewEventPublisher(rabbitConn) + + // ็”จไพ‹ (ๆณจๅ…ฅไพ่ต–) + createAccountUC := use_cases.NewCreateAccountUseCase(accountRepo, eventPublisher) + loginUC := use_cases.NewLoginUseCase(accountRepo, cacheAdapter) + + // ๅ…ฅ็ซ™้€‚้…ๅ™จ (ไฝฟ็”จ็”จไพ‹) + handler := http.NewAccountHandler(createAccountUC, loginUC) + + // ๅฏๅŠจๆœๅŠกๅ™จ + router := gin.Default() + handler.RegisterRoutes(router) + router.Run(":8080") +} +``` + +### 2.6 DDD ๆˆ˜ๆœฏๆจกๅผๆ€ป่งˆ + +| DDD ๆฆ‚ๅฟต | ๆœฌ็ณป็ปŸๅฎž็Žฐ | ไฝ็ฝฎ | +|---------|-----------|------| +| **Entity** | Account, MPCSession, Participant | `domain/entities/` | +| **Value Object** | AccountID, SessionStatus, Threshold | `domain/value_objects/` | +| **Aggregate** | Account (ๅซ AccountShare), MPCSession (ๅซ Participant) | `domain/entities/` | +| **Repository** | AccountRepository, SessionRepository (ๆŽฅๅฃ) | `domain/repositories/` | +| **Domain Service** | SessionCoordinatorService, AccountService | `domain/services/` | +| **Application Service** | CreateAccountUseCase, JoinSessionUseCase | `application/use_cases/` | +| **Input Port** | CreateAccountPort, LoginPort | `application/ports/input/` | +| **Output Port** | SessionStoragePort, MessageBrokerPort | `application/ports/output/` | +| **Input Adapter** | AccountHandler (HTTP), SessionGrpcHandler | `adapters/input/` | +| **Output Adapter** | PostgresRepo, RedisCache, RabbitMQPublisher | `adapters/output/` | + +## 3. ็ณป็ปŸ้ƒจ็ฝฒๆžถๆž„ + +### 3.1 ๆ•ดไฝ“ๆžถๆž„ๅ›พ ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” @@ -75,35 +540,35 @@ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` -### 2.2 ๆœๅŠก่Œ่ดฃ +### 3.2 ๆœๅŠก่Œ่ดฃ -#### 2.2.1 Session Coordinator (ไผš่ฏๅ่ฐƒๅ™จ) +#### 3.2.1 Session Coordinator (ไผš่ฏๅ่ฐƒๅ™จ) - ๅˆ›ๅปบๅ’Œ็ฎก็† MPC ไผš่ฏ - ๅ่ฐƒๅ‚ไธŽๆ–นๅŠ ๅ…ฅไผš่ฏ - ่ทŸ่ธชไผš่ฏ็Šถๆ€ๅ’Œ่ฟ›ๅบฆ - ็ฎก็†ๅ‚ไธŽๆ–นๅฐฑ็ปช็Šถๆ€ -#### 2.2.2 Message Router (ๆถˆๆฏ่ทฏ็”ฑๅ™จ) +#### 3.2.2 Message Router (ๆถˆๆฏ่ทฏ็”ฑๅ™จ) - ่ทฏ็”ฑ TSS ๅ่ฎฎๆถˆๆฏ - ๆ”ฏๆŒ็‚นๅฏน็‚นๅ’Œๅนฟๆ’ญๆถˆๆฏ - ๆถˆๆฏ็ผ“ๅญ˜ๅ’Œ้‡ไผ  - WebSocket ๅฎžๆ—ถ้€šไฟก -#### 2.2.3 Server Party (ๆœๅŠก็ซฏๅ‚ไธŽๆ–น) +#### 3.2.3 Server Party (ๆœๅŠก็ซฏๅ‚ไธŽๆ–น) - ไฝœไธบ MPC ๅ่ฎฎ็š„ๆœๅŠก็ซฏๅ‚ไธŽๆ–น - ๆ‰ง่กŒ DKG ๅ’Œ็ญพๅๅ่ฎฎ - ๅฎ‰ๅ…จๅญ˜ๅ‚จๅŠ ๅฏ†็š„ๅฏ†้’ฅๅˆ†็‰‡ - ๆ”ฏๆŒๅคšๅฎžไพ‹้ƒจ็ฝฒ -#### 2.2.4 Account Service (่ดฆๆˆทๆœๅŠก) +#### 3.2.4 Account Service (่ดฆๆˆทๆœๅŠก) - ็”จๆˆทๆณจๅ†Œๅ’Œ่ฎค่ฏ - ่ดฆๆˆท็ฎก็† - MPC ไผš่ฏๅ…ฅๅฃ API - ่ดฆๆˆทๆขๅคๆต็จ‹ -## 3. ๆ ธๅฟƒๆต็จ‹ +## 4. ๆ ธๅฟƒๆต็จ‹ -### 3.1 ๅฏ†้’ฅ็”Ÿๆˆๆต็จ‹ (Keygen) +### 4.1 ๅฏ†้’ฅ็”Ÿๆˆๆต็จ‹ (Keygen) ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” @@ -139,7 +604,7 @@ โ”‚ โ”‚ โ”‚ โ”‚ ``` -### 3.2 ็ญพๅๆต็จ‹ (Signing) +### 4.2 ็ญพๅๆต็จ‹ (Signing) ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” @@ -170,9 +635,9 @@ โ”‚ โ”‚ โ”‚ โ”‚ ``` -## 4. ๆ•ฐๆฎๆจกๅž‹ +## 5. ๆ•ฐๆฎๆจกๅž‹ -### 4.1 Session (ไผš่ฏ) +### 5.1 Session (ไผš่ฏ) ```go type Session struct { @@ -188,7 +653,7 @@ type Session struct { } ``` -### 4.2 Participant (ๅ‚ไธŽๆ–น) +### 5.2 Participant (ๅ‚ไธŽๆ–น) ```go type Participant struct { @@ -200,7 +665,7 @@ type Participant struct { } ``` -### 4.3 KeyShare (ๅฏ†้’ฅๅˆ†็‰‡) +### 5.3 KeyShare (ๅฏ†้’ฅๅˆ†็‰‡) ```go type KeyShare struct { @@ -213,21 +678,21 @@ type KeyShare struct { } ``` -## 5. ๅฎ‰ๅ…จ่ฎพ่ฎก +## 6. ๅฎ‰ๅ…จ่ฎพ่ฎก -### 5.1 ๅฏ†้’ฅๅฎ‰ๅ…จ +### 6.1 ๅฏ†้’ฅๅฎ‰ๅ…จ - **ๅฏ†้’ฅๅˆ†็‰‡ๅญ˜ๅ‚จ**: ไฝฟ็”จ AES-256-GCM ๅŠ ๅฏ†ๅญ˜ๅ‚จ - **ไธปๅฏ†้’ฅ็ฎก็†**: ไปŽ็Žฏๅขƒๅ˜้‡ๆˆ– KMS ๅŠ ่ฝฝ - **ๆ— ๅ•็‚นๆ•…้šœ**: ไปปๆ„ t ไธช่Š‚็‚น่ขซๆ”ป็ ดไธๅฝฑๅ“ๅฎ‰ๅ…จๆ€ง -### 5.2 ้€šไฟกๅฎ‰ๅ…จ +### 6.2 ้€šไฟกๅฎ‰ๅ…จ - **TLS ๅŠ ๅฏ†**: ๆ‰€ๆœ‰ gRPC/HTTP ้€šไฟกไฝฟ็”จ TLS - **ๆถˆๆฏ่ฎค่ฏ**: TSS ๆถˆๆฏๅŒ…ๅซๅ‚ไธŽๆ–น็ญพๅ - **ไผš่ฏไปค็‰Œ**: ไฝฟ็”จ UUID v4 ็”Ÿๆˆไธ€ๆฌกๆ€งไปค็‰Œ -### 5.3 ๅฎ‰ๅ…จๅฑžๆ€ง +### 6.3 ๅฎ‰ๅ…จๅฑžๆ€ง | ๅฑžๆ€ง | ๆ่ฟฐ | |------|------| @@ -236,9 +701,9 @@ type KeyShare struct { | ๅ‰ๅ‘ๅฎ‰ๅ…จ | ไผš่ฏๅฏ†้’ฅ็‹ฌ็ซ‹๏ผŒๅކๅฒๆณ„้œฒไธๅฝฑๅ“ๆœชๆฅ | | ๆŠ—ๅˆ่ฐ‹ | t ไธชๆถๆ„ๆ–นๆ— ๆณ•ไผช้€ ็ญพๅ | -## 6. ้ƒจ็ฝฒๆžถๆž„ +## 7. ้ƒจ็ฝฒๆžถๆž„ -### 6.1 ๆœ€ๅฐ้ƒจ็ฝฒ (2-of-3) +### 7.1 ๆœ€ๅฐ้ƒจ็ฝฒ (2-of-3) ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” @@ -259,14 +724,14 @@ type KeyShare struct { โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` -### 6.2 ็”Ÿไบง็Žฏๅขƒ้ƒจ็ฝฒ +### 7.2 ็”Ÿไบง็Žฏๅขƒ้ƒจ็ฝฒ - **้ซ˜ๅฏ็”จ**: ๆฏไธชๆœๅŠก่‡ณๅฐ‘ 2 ๅ‰ฏๆœฌ - **่ดŸ่ฝฝๅ‡่กก**: Nginx/Traefik ๅๅ‘ไปฃ็† - **ๆœๅŠกๅ‘็Žฐ**: Consul ้›†็พค - **็›‘ๆŽง**: Prometheus + Grafana -## 7. ็›ฎๅฝ•็ป“ๆž„ +## 8. ็›ฎๅฝ•็ป“ๆž„ ``` mpc-system/