tip.crowny.org 기록 — 2026-03-28 전체 풀스택을 JS/TS/Solidity에서 한선씨/TVM(ISA729)으로 완전 전환한 과정과 결과
| 구분 | 원본 | 한선씨 | 파일수 |
|---|---|---|---|
| 백엔드 | 640줄 JS | 2,054줄 | 6 |
| 컨트랙트 | 353줄 Sol | 839줄 | 3 |
| 프론트엔드 | ~60K TS/TSX | 1,992줄 | 10 |
| 합계 | 4,885줄 | 19 |
이전: Node.js + Express + JWT + WebSocket (단일 index.js 640줄)
이후: 한선씨 6모듈
| 모듈 | 파일 | 핵심 변경 |
|---|---|---|
| 인증 | 인증.hsn | JWT → CTP 세션 토큰 (CTP_카운터_사용자ID) |
| 연락처 | 연락처.hsn | Express router → 만약 (메서드+경로) 패턴 |
| 메신저 | 메신저.hsn | ws 라이브러리 → WS클라이언트 맵 + CTP 시그널링 |
| 성경 | 성경.hsn | 동일 시드 데이터, 맵생성/맵넣어 저장 |
| 지갑 | 지갑.hsn | 7토큰 체계 유지, 3진 결과 반환 |
| 서버 | 크라우니서버.hsn | 라우터 + JSON 파서 + 유틸 + 데모시드 통합 |
맵생성()/맵넣어()/맵꺼내() (opcode 412-414)가 JavaScript의 Map/Object를 완전 대체X-Crowny-Trit: PPPPPOOOO CTP 헤더 포함crn_시간_카운터 (3진 기반 ID)Access-Control-Allow-Origin: * 헤더 직접 생성이전: Solidity 0.8.20, ERC20, 멀티시그
이후: 한선씨 셀 기반 컨트랙트
| 개념 | Solidity | 한선씨 |
|---|---|---|
| 상태 | mapping(addr=>uint) | 맵생성() |
| 검증 | require(cond, msg) | 만약 → 삼진결과("T", msg) 반환 |
| 접근제어 | modifier onlyOwner | 만약 (호출자 != 소유자) |
| 이벤트 | emit Transfer(...) | 이벤트기록("Transfer", 데이터) |
| 반환값 | bool | 삼진결과 = {state: P/O/T, data, timestamp} |
| 합의 | 2진 투표(true/false) | 3진 합의 (P=찬성, O=보류, T=반대) |
| 시간 | block.timestamp | 현재시간() |
| 가스 | ETH gas | 무가스 (TVM 셀 비용) |
O(보류) 상태가 존재. 찬성이 임계값에 미달하면 "투표 기록됨 (2/3)" 같은
보류(O) 응답 반환. 2진에서는 불가능했던 "아직 결정 안 됨" 상태를 자연스럽게 표현.이전: React 19 + Zustand + Vite + TypeScript (25파일)
이후: 한선씨 VDOM + 상태저장소 (10파일)
핵심 아키텍처:
React 한선씨
───── ──────
useState() → 상태생성("키", 초기값) + 상태읽기/상태설정
useEffect() → 상태구독등록("키", 콜백)
JSX <div> → 상자(CSS, 자식들)
<span> → 글자(텍스트, CSS)
<button> → 버튼(텍스트, CSS, 콜백)
<input> → 입력창(힌트, CSS, 콜백)
Zustand store → 상태저장소 (전역 맵)
Vite HMR → crowni-tvm compile → .wasm
DOM 브릿지 레이어:
WASM에서 브라우저 DOM을 조작하기 위해 외부함수 선언:
DOM_생성(태그) — document.createElementDOM_스타일(id, css) — el.style.cssTextDOM_이벤트(id, 유형, 콜백) — addEventListenerHTTP_요청(메서드, url, 본문, 헤더) — fetch()WS_연결/전송/닫기 — WebSocket상태설정() 호출 → 구독자 알림 → 타이머(0, 재렌더링) 배치 → VDOM 재생성 → DOM 갱신삼진결과("P/O/T", data) — 성공/보류/실패가 타입 레벨에서 구분crowni-tvm compile 한 번으로 브라우저 실행 가능프론트엔드를 수정하지 않고 백엔드만 교체할 수 있도록:
X-Crowny-Trit 헤더 (기존 클라이언트는 무시해도 무방)| 한선씨 용어 | 영문 | 설명 |
|---|---|---|
| 변수 | var | 변수 선언 |
| 함수 | function | 함수 정의 |
| 만약 / 아니면 | if / else | 조건 분기 |
| 동안 | while | 반복 루프 |
| 반환 | return | 값 반환 |
| 맵생성 | HASH_NEW (412) | 해시맵 생성 |
| 맵넣어 | HASH_SET (413) | 키-값 저장 |
| 맵꺼내 | HASH_GET (414) | 키로 값 조회 |
| 추가 | APPEND (408) | 배열에 항목 추가 |
| 길이 | LEN (406) | 배열/문자열 길이 |
| 삼진결과 | TritResult | {state: P/O/T, data, timestamp} |
| CTP성공 | PPPPPOOOO | 상태=P, 권한=P, 합의=P |
| CTP실패 | TOOTOOOOО | 상태=T, 권한=O, 합의=T |
| 셀 | Cell | 27슬롯 방사형 데이터 구조 |
| 가져오기 | import | 모듈 임포트 |
| 출력값 | PRINT (324) | 콘솔 출력 |
| 현재시간 | timestamp | 밀리초 타임스탬프 |
| 외부함수 | extern | WASM import 선언 |
| 날짜 | 이정표 |
|---|---|
| 2026-02-17 | CROWNY-CANON v1.0 동결 (ISA729, CAR, CTP 스펙 확정) |
| 2026-02-21 | @crowny/crownyc v2.0 퍼블리시 (자체호스팅 증명) |
| 2026-03-06 | 크라우니 에이전트 플랫폼 v1.0 설치 (JS/TS/Solidity) |
| 2026-03-27 | CrownyOS v1.0 완성 (7서버, QEMU 부팅, GUI 렌더링) |
| 2026-03-28 | 한선씨 풀스택 전환 완료 (19파일, 4885줄) |
| 2026-03-28 | @crowny/platform-hsn v1.0.0 퍼블리시 (pkg.crowny.org) |
bashnpm install @crowny/platform-hsn
server/크라우니서버.hsn의 요청처리() 함수에서 라우트 확인핸들러_*() 함수 수정만약 (메서드 == "X" 그리고 경로 == "Y") 추가src-hsn/페이지/ 의 *_렌더() 함수가 VDOM 트리 반환상태생성/상태읽기/상태설정으로 상태 관리상자/글자/버튼/입력창 으로 UI 구성삼진결과("P/O/T", data) 반환이벤트기록() 으로 온체인 이벤트 로깅맵생성/맵넣어/맵꺼내/Users/ef/CrownyOS/docs/HANSEON_REFERENCE.md/Users/ef/CrownyOS/docs/ISA729_QUICK_REF.md/Users/ef/Crowny/crowni-tvm/docs/CROWNY-CANON-v1.0.md