ACN
dAppOffice
문서 목차 (2 / 16)

02. 아키텍처

구성도

┌──────────────────────── 모바일 지갑 앱 (TokenPocket / MetaMask ...) ────────────────────────┐
│  dApp 브라우저                                                                            │
│  ┌──────────────────────────────┐   window.ethereum (EIP-1193)   ┌────────────────────┐  │
│  │  Next.js 16 dApp (frontend/) │ ─────────────────────────────► │  지갑 서명 / 키 보관 │  │
│  │  wagmi + viem + Tailwind     │ ◄───────────────────────────── │                    │  │
│  └──────────────┬───────────────┘        tx hash / 계정          └────────────────────┘  │
└─────────────────┼─────────────────────────────────────────────────────────────────────────┘
                  │ REST (JSON)                       ▲ eth_call / eth_sendRawTransaction
                  ▼                                   │ (지갑이 자체 RPC로 직접 전송)
┌──────────────────────────────┐   web3.py (JSON-RPC)  │
│  FastAPI (backend/)          │ ──────────────────────┼──────► BSC 노드 (bsc-dataseed 등)
│  /api/token, /api/transfers  │                       │
│  + indexer (Transfer 이벤트) │ ◄─────────────────────┘ eth_getLogs / receipts
└──────────────┬───────────────┘
               ▼
        PostgreSQL (db: acn)

데이터 흐름

조회

  1. dApp이 지갑 provider(window.ethereum)를 통해 balanceOf, decimals, symbol을 직접 eth_call한다. 백엔드 장애와 무관하게 잔액은 항상 보인다.
  2. 거래 내역은 백엔드 GET /api/transfers?address= 로 조회한다(DB 인덱스).

전송

  1. 사용자가 받는 주소와 수량을 입력 → viem.parseUnits로 wei 변환.
  2. wagmi writeContract(transfer) → 지갑 앱이 서명 UI를 띄우고 사용자가 승인.
  3. 지갑이 트랜잭션을 브로드캐스트하고 tx hash 반환.
  4. dApp이 useWaitForTransactionReceipt로 채굴 확인.
  5. 채굴되면 dApp이 POST /api/transfers {txHash} 호출.
  6. 백엔드는 hash만 받아 영수증을 직접 조회하고 ACN Transfer 로그를 파싱해 DB에 저장한다.

인덱싱(선택)

python -m app.indexer 는 마지막 처리 블록부터 eth_getLogs로 ACN Transfer 이벤트를 배치 수집해 같은 테이블에 upsert 한다. 클라이언트가 기록하지 않은 전송(다른 dApp/거래소 출금 등)도 내역에 나타난다.

왜 이 구조인가

  • PostgreSQL: Office가 온체인에서 재구축할 수 없는 오프체인 원장을 들고 있어서, 파일 하나에 의존하지 않는 저장소와 검증 가능한 pg_dump 백업이 필요하다. 원래 SQLite로 시작했고 2026-09-08에 이전했다. 쓰기는 advisory lock으로 직렬화해 SQLite 단일 writer 시절의 보장을 유지한다 (05-database.md 참고).
  • FastAPI: 타입 기반 검증(pydantic)과 자동 OpenAPI 문서. web3.py와 같은 파이썬 생태계.
  • wagmi/viem: EIP-1193 provider 표준 위에서 Injected·WalletConnect를 하나의 API로 다룬다. 트리셰이킹 가능한 경량 라이브러리.