Skip to content

Repository files navigation

옥새 앱 아이콘

옥새 (OKSAE)

전세사기 사전 예방을 위한 계약 경험 기록 플랫폼

실거주가 검증된 세입자의 경험을 다음 세입자에게 전달하는
GIWA Chain 기반 임대차 신뢰 인프라

옥새 데모 영상      옥새 프로젝트 문서      GIWA Sepolia 컨트랙트
Demo Video  ·  Project Docs  ·  GIWA Contract


Blockchain as Trust Infrastructure for the Public — GIWA Chain 액셀러레이팅 프로젝트

정말 중요한 위험 신호는 등기부에 기록되지 않고, 이전 세입자의 경험은 계약 종료와 함께 사라집니다. 옥새는 실거주가 검증된 세입자에게만 기록 권한(SBT)을 부여하고, 그 경험을 신뢰 가능한 형태로 축적해 다음 세입자가 계약 전에 확인할 수 있게 합니다.

왜 블록체인인가

주장 뒷받침
실제 계약 당사자만 기록 가능 계약 검증 후 발급되는 SBT(ReviewAuthority) 가 리뷰 권한
기록·삭제를 운영자도 몰래 못 함 발급·소각·리뷰 앵커가 전부 체인에 공개 (모더레이션 삭제조차 공개 소각으로 기록)
개인정보는 영구 기록되지 않음 온체인에는 salted commitment만 — 본문·PII·동호수는 전부 오프체인, 삭제 = nonce 폐기
Web2 수준의 사용성 ERC-4337 스마트 계정 가스 대납 anchor는 별도 PoC에서 실증 완료. 현재 RN 앱은 개인 지갑 연결 방식

아키텍처

 React Native 앱 ──────────► Spring Boot 백엔드 ──────────► PostgreSQL + PostGIS
      │                        │  지도/계약/리뷰/메신저          ▲
      │ 지갑 서명               │  SBT 발급(issuer)              │ projection (주소+tokenId 조인)
      ▼                        ▼                               │
 anchorReview tx ────────► GIWA Sepolia ◄───────────── Go 인덱서 (reorg-safe)
 (또는 4337 UserOp)         ReviewAuthority SBT
  • 온체인 경계 원칙: "운영자조차 사후 부인·조작 못 해야 가치 있는 것"만 체인에 — SBT 라이프사이클 + 리뷰 커밋먼트. 나머지(본문·PII·위험 점수·메신저)는 전부 오프체인.
  • 인덱서 projection(onchain_review_authority)은 reorg 시 재구성되므로 백엔드 원장(review_authority)과 분리하고 (contract_address, onchain_id)로 조인합니다. 재배포 전 토큰도 발급 당시 컨트랙트 주소에 묶여 조회·철회됩니다.

저장소 구성

디렉토리 내용 상태
contracts/ ReviewAuthority 비양도성 리뷰 권한 (Foundry) — Dojang 검증 후 발급/소각/앵커 ✅ TESTNET FAUCET 프로필 배포
indexer/ Go 인덱서 — 이벤트→DB 동기화, reorg 롤백, 재시작 멱등 ✅ Track 1 완료 (기록)
backend/ Spring Boot 3.5 / Java 21 / PostGIS — 서비스 전체 ✅ 전 기능 런타임 검증 (README)
aa-poc/ ERC-4337 가스 대납 anchor PoC ✅ 실증 완료 (README)
frontend/ React Native 앱 ✅ 로그인·지갑·계약 제출·권한 상태·리뷰 앵커 API 연결
docs/ 검증 정책 공개 문서 — SBT가 보증하는 것/않는 것 ✅

백엔드 주요 기능

  • 지도: bbox 마커(리뷰 수·평균·위험도), 클릭 좌표 → 건물 매칭(도로명>지번>근접 30m, 네이버 지오코딩), 지역 단위 위험 히트맵(PostGIS 격자 집계)
  • 계약 인증 → SBT 발급: 계약서 이미지(AES-256-GCM 암호화 저장, 열람 감사로그, 심사 후 즉시 파기) → 관리자 심사(검증 수준 L1~L3) → issuer가 GIWA에 발급 tx. 동일 계약서 중복 발급 차단(지문 해시)
  • 관리자 계약 심사 도구: 백엔드 실행 후 http://localhost:8080/admin에서 개인 관리자 키를 입력하면 대기 목록, 계약서 열람, 계약 정보 확정, 승인·반려를 처리할 수 있습니다. ADMIN_API_KEYS=name:key,name:key 형식의 복수 키를 지원하며 키는 페이지 코드에 포함되지 않습니다.
  • 리뷰: 활성 SBT 필수, 점수+체크리스트(구조화), 자유 텍스트는 공개 응답에서 제외(명예훼손 리스크) — salted commitment를 계산해 회원 지갑이 직접 앵커
  • 모더레이션: 신고 → 리뷰 원본+nonce 폐기 + SBT 공개 소각 + 작성자 정지
  • 익명 메신저: 예비 세입자 ↔ 리뷰 작성자, 역할만 노출
  • 인증: MetaMask EIP-191 서명으로 지갑 소유권을 먼저 확인하고, 기존 지갑은 즉시 JWT 로그인·신규 지갑은 프로필 등록. DB가 대소문자 무관 지갑 1개 = 계정 1개를 강제

이 저장소의 ReviewAuthority는 ERC-721을 상속하는 지갑 표시용 NFT가 아니라, 양도 함수를 제공하지 않는 온체인 권한 레지스트리입니다. authEnd 이후에는 리뷰 작성·앵커가 거부되고 백엔드 상태는 EXPIRED로 전환되지만 자연 만료만으로 burn()이 자동 실행되지는 않습니다. 발급 기록은 보존하며 소각은 부정 권한 철회·모더레이션 때 별도 트랜잭션으로 수행합니다.

빠른 시작 (백엔드)

통합 개발 실행

PostGIS 준비, DB/Flyway, Dojang·체인 환경변수 주입, 백엔드와 인덱서 실행을 한 번에 처리합니다. issuer 원시 개인키는 저장하지 않으며 Foundry keystore 암호를 실행 시 숨김 입력합니다.

./scripts/dev-up.sh
./scripts/dev-status.sh
./scripts/dev-down.sh

DB 컨테이너까지 멈추려면 ./scripts/dev-down.sh --with-db를 사용합니다. 데이터는 삭제되지 않습니다. 기본값을 바꾸려면 .env.local.example을 .env.local로 복사해 수정하세요. 런타임 PID·로그·자동 생성 JWT/admin secret은 Git에서 제외되는 .run/에 저장됩니다.

팀원용 실제 DB + 온체인 데모 5건

백엔드와 인덱서를 먼저 실행한 뒤, GIWA Sepolia TESTNET FAUCET Dojang 인증을 받은 팀원 지갑으로 데모를 준비합니다.

cd ~/Oksae
./scripts/dev-up.sh
./scripts/demo-bootstrap.sh 0x팀원_지갑주소

스크립트는 지갑별 데모 로그인 계정과 건물 5개를 실제 DB에 만들고, 사진 신청 → 관리자 계약 정보 확정 → 관리자 승인 경로를 거쳐 GIWA Sepolia SBT 5개를 발급합니다. 마지막에는 건물별 /sbt-history에서 인덱서 반영 5/5까지 확인합니다.

사용자 지갑 개인키는 요구하지 않습니다. issuer 개인키는 이미 실행 중인 백엔드만 사용합니다. 다만 반복 테스트를 위해 전용 데모 회원과 지갑의 로컬 DB 연결에서는 personal_sign을 생략하므로 운영 환경에서는 실행하면 안 됩니다.

완료된 계정·tokenId·발급 트랜잭션은 .run/demo-bootstrap-<지갑끝8자리>.json에 기록됩니다. 앱에서는 스크립트에 지정한 같은 지갑으로 서명 로그인하면 되고 이메일 입력은 필요하지 않습니다. 같은 지갑으로 스크립트를 재실행하면 기존 ACTIVE SBT를 재사용합니다.

ReviewAuthority 재배포와 Dojang 발급자 전환도 대화형 스크립트로 처리합니다.

# 메뉴에서 TESTNET FAUCET / UPbit Korea / custom 선택
./scripts/deploy-review-authority.sh

# 프로필을 바로 지정할 수도 있음
./scripts/deploy-review-authority.sh testnet-faucet
./scripts/deploy-review-authority.sh upbit-korea

keystore가 없을 때만 개인키 import를 대화형으로 요청하며 원시 키는 파일이나 명령 인자에 저장하지 않습니다. 스크립트는 기존 DB의 최대 token ID를 읽어 새 컨트랙트 시작 ID를 제안하고, 배포 검증 후 .env.local의 컨트랙트 주소·배포 블록·attester ID를 갱신합니다. 직전 주소는 CHAIN_LEGACY_CONTRACTS에 자동 누적되어 인덱서가 구 토큰의 이후 소각 이벤트도 계속 추적합니다. UPbit 프로필 선택은 검증 대상만 바꾸며 UPbit KYC/Verified Address 자체를 발급해 주지는 않습니다.

별점 0 허용 컨트랙트 배포와 이후 재배포

각 별점에 0~5를 허용하는 현재 ReviewAuthority는 2026-07-29 0x430e...64A7에 initial token ID 4로 배포했습니다. 직전 0xC468...27cf의 tokenId 1~3은 레거시 주소에 연결해 보존합니다. 이후 컨트랙트 또는 attester를 다시 전환할 때는 다음 명령을 사용합니다.

cd ~/Oksae

# 재시작 시 DB/Flyway가 필요하므로 먼저 확인
docker ps

./scripts/deploy-review-authority.sh testnet-faucet

대화형 입력 순서:

  1. issuer keystore 암호 입력
  2. 체인과 DB에서 계산한 Initial token ID [N]을 확인하고 그대로 Enter
  3. 배포 요약을 확인하고 DEPLOY 입력
  4. 백엔드·인덱서 재시작 질문에서 Docker가 정상이라면 Y

배포가 성공한 뒤 스크립트가 자동으로 처리하는 항목:

  • .env.local의 CHAIN_CONTRACT, CHAIN_START_BLOCK, attester ID 갱신
  • 직전 주소를 CHAIN_LEGACY_CONTRACTS에 중복 없이 추가
  • .run/deployments/<시각>.env에 새 주소·TX·블록·구주소 기록
  • 이 README와 backend/README.md의 현재 배포 표 갱신
  • 선택 시 새 환경으로 백엔드·인덱서 재시작

Flyway V22부터 SBT는 (contract_address, onchain_id)로 식별됩니다. 따라서 기존 test tokenId 1~3은 구 컨트랙트 0xC468...27cf에 연결된 상태로 이력 조회와 issuer 철회가 가능합니다. 이미 앵커된 토큰은 다시 앵커할 수 없으며, 구 컨트랙트 토큰에는 0점 앵커를 적용할 수 없습니다. tokenId 4부터는 현재 컨트랙트의 0~5 규칙을 사용합니다.

수동 실행

# 1) PostGIS
docker run -d --name oksae-pg-postgis -p 5432:5432 \
  -e POSTGRES_PASSWORD=oksae -e POSTGRES_DB=oksae postgis/postgis:16-3.4

# 2) 백엔드 — Flyway가 스키마 자동 생성. 기본은 Mock 체인(로컬 개발)
cd backend && ./gradlew bootRun

# 3) 실체인 발급 모드 (GIWA Sepolia)
CHAIN_ENABLED=true CHAIN_ISSUER_PK=<issuer 키> ./gradlew bootRun

# 4) 인덱서 (같은 DB 공유)
cd indexer && go run .

환경변수 상세·운영 주의사항은 backend/README.md 참고.

문서

온체인 정보 (GIWA Sepolia, chainId 91342)

현재 통합 개발 배포

항목 값
ReviewAuthority 0x430eBec0BCa390F8377a4d62bd70311289d964A7
배포 트랜잭션 0xc5a77f0a0850d2c16da372a33dafca1b59d3b90d489fc52bfeac3e3f8990ad5a
배포 블록 31961159
issuer 0xD21dE9470d8A0dbae0dE0b5f705001a6482Db580
DojangScroll 0xd5077b67dcb56caC8b270C7788FC3E6ee03F17B9
Dojang attester 0xaa92f8c143657dde575de430aecaea6ca91f2e6072339b16932d426895d8d678 — GIWA Sepolia TESTNET FAUCET
현재 발급 상태 배포 직후 nextId = 4
RPC / Explorer https://sepolia-rpc.giwa.io / https://sepolia-explorer.giwa.io

현재 attester는 PoC용 TESTNET FAUCET이며 실제 UPbit KYC가 아닙니다. 운영 전환 시 upbit-korea 프로필로 재배포하고, 실제 사용자 지갑에 해당 attestation이 발급되는 KYC 연계까지 별도로 완료해야 합니다.

현재 주소는 각 온체인 별점에 0~5를 허용하는 최신 배포본입니다.

레거시/PoC 배포

항목 값
anchorReview 추가 전 ReviewAuthority 0x7B2bEDE344dfA3E543812aCBbDAbBAB7d7eBd4fc
Dojang 연동 전 ReviewAuthority 0xd40b652aC5F19448FA2C09ec2c3188042fF427A4
SimpleAccountFactory (4337 PoC) 0x5DF1f9B881753A0E31f5C0DFCc08099fC5Ea0Aee
EntryPoint v0.7 0x0000000071727De22E5E9d8BAf0edAc6f37da032

레거시 주소는 과거 인덱서·4337 실증 기록 재현용이며 현재 dev-up.sh의 발급 대상으로 사용하지 않습니다.

로드맵

  • 프론트엔드 계약 인증·권한 상태·실제 anchorReview 트랜잭션 연동
  • 인덱서 Track 2 — 자체 노드 IPC 전환
  • 4337 프로덕션화 — Paymaster·passkey 소유자·번들러 상시 운영
  • Dojang Verified Address PoC — KYC 완료 지갑 배지 및 발급 게이트
  • 자연 만료 권한 EXPIRED 처리 — 발급 기록 보존 및 지갑 변경 차단 해소
  • 본인확인 연계(L3_IDENTITY) — 계약서 명의와 계정 소유자의 동일성 검증
  • issuer 키 분리 (setIssuer 추가 재배포)

About

전세사기 예방을 위해 세입자의 임대차 계약 경험을 검증하고 공유하는 신뢰 플랫폼

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages