🇰🇷 🇬🇧

UBMS 기술 분석 보고서

UTXO-Based Metadata Smart Chain

작성자: 한혁진 (bokkamsun@gmail.com)
작성일: 2026년 3월 1일


본 보고서에 대하여

UBMS는 2024년 11월에 개발을 시작하여 현재까지 활발히 개발이 진행 중인 프로젝트. 가운영 환경에서 실제 데이터를 축적하면서 그 피드백을 바탕으로 설계를 다듬고 코드를 개선하는, 살아 있는 프로젝트.

운영은 단계적으로 진행:

베타 테스트              2025년 6월 종료 됨, 외부 참여자 확대
가운영 (현재)           가운영 환경에서 실제 데이터 수집, 각종 장애 경험 축적
정식 운영               가운영 피드백 반영 소스코드 완성 후 전환

가운영 기간 동안 포럼을 운영하여 참여자와 직접 소통하며, 다양한 장애 상황을 의도적으로 경험하고 대응 코드를 작성하는 방식으로 안정성을 확보하고 있다. 가운영 중 발견되는 개선점은 즉시 수집되고, 이 과정에서 축적되는 실측 데이터가 경제 모델(Shifted Sigmoid, PoB, 동적 수수료)의 설계 검증 근거가 되고, 실제로 많은 피드백을 받고 코드에 지속적으로 반영되고 있다.

본 보고서가 분석한 코드는 브랜치 v5 기준으로, 전체 설계의 약 40%에 해당하는 골격 완성 단계. 핵심 아키텍처와 주요 모듈의 동작이 확인된 부분만을 대상으로 기술 분석을 수행했으며, 아직 구현 중이거나 내부 테스트 단계에 있는 기능은 본 보고서의 분석 범위에 포함되지 않는다. 다시 말해, 이 보고서에 담긴 것은 완성된 부분의 기술력이고, 이 프로젝트는 장기 프로젝트로, 본 보고서의 분석 범위를 넘어서는 규모로 계속 성장해 나갈 것이다.

완성된 제품의 기술 보고서는 결과물을 설명할 뿐이지만, 40% 시점의 보고서는 이 프로젝트가 어디를 향해 가고 있는지, 어떤 설계 철학과 기술적 지향점 위에 서 있는지를 보여 준다. 코드의 골격이 곧 설계자의 의도이며, 완성형의 윤곽은 충분히 알 수 있다. 현재는 1인 개발 체제이나, 프로젝트가 성장함에 따라 팀 확장을 통해 외부 코드 리뷰, 보안 감사, 자동화 테스트 체계를 보강할 계획이다.


1. 프로그램 개요

UBMS(UTXO-Based Metadata Smart Chain)는 100% 독자 개발된 한국형 블록체인 풀노드 시스템. C++20 표준으로 작성되었으며, UTXO 모델 위에 메타데이터 기반 스마트 컨트랙트를 구현.

핵심 특징:

총 발행량: ~21,000,000 UBMS, 소수점 8자리 (mensch 단위 = 100,000,000)
블록 보상 분배: 채굴자(Miner) 5% + 스테이커(Staker) 95% 온체인 자동 분배


2. 모듈 구조

ubmscoin/
  src/
    libubmstype.so       타입 정의, JSON/바이너리 직렬화 엔진
    libubmslog.so        파일 기반 로깅
    libubmsutil.so       Worker 템플릿, 스레드 안전 큐, 산술 오버플로 방지, 변환 유틸
    libubmscrypto.so     RSA-4096, SHA256, RIPEMD160, Base58, AES-GCM, zlib 압축
    libubmsio_uring.so   io_uring 기반 서버/클라이언트, WebSocket, 세션 관리
    libubmsevent.so      libevent 기반 이벤트 엔진, 신호-슬롯, OS 시그널 통합
    libubmstopol.so      결정론적 2D 격자, 3경로 라우팅, 지향성 가십, 독자 DHT
    libubmshttp.so       REST API + 리버스 프록시 + 리다이렉트 + 레이트 리미팅
    libubmscoin.so       블록체인 핵심 (블록, TX, UTXO, 캐시, DB, 검증)
    ubmsdaemon           데몬 진입점, P2P 허브, 워커 스레드들
    ubmsnotify           독립 실행 FCM 푸시 알림 서버 (라이브러리 범용성 실증)

의존 관계:

libubmstype.so (기반)
    libubmslog.so
    libubmsutil.so (Worker, QueueSafe, Arith, Convert)
        libubmscrypto.so (RSA, SHA256, Base58, zlib)
            libubmsio_uring.so (io_uring 서버/클라이언트)
            libubmsevent.so (이벤트 루프, 신호-슬롯)
                libubmstopol.so (독자 DHT, 토폴로지)
                libubmshttp.so (REST API)
                    libubmscoin.so (블록체인 핵심)
                        ubmsdaemon (데몬 + P2P)
                        ubmsnotify (독립 실행 푸시 알림 서버, 라이브러리 범용성 실증)

3. 핵심 아키텍처

3.1 3계층 캐시 + TX풀 통합 아키텍처

캐시매니저는 3계층 캐시와 TX풀을 단일 잠금로 통합 제어하는 중앙 관제소. UTXO 조회, 잔액 계산, 이중지불 검사를 모두 흡수하여 원자적 상태 검사를 보장.

UBMS::CacheManager (내부 조회가 O(10) 이하라 잠금 점유 시간이 극히 짧다)
  │
  ├──  UBMS::TxCurrent (TX풀 + 주소별 예약 풀)
  │       m_tx: 타임스탬프 순 TX 맵
  │       m_reserved: 주소별 UBMS::UtxoPool
  │         ├─ spent_keys: 소비 예약된 UTXO key
  │         ├─ spent_list: 소비 입력 목록
  │         └─ available: TX풀 잔돈 (미소비 UTXO)
  │       m_globalSpentKeys: 크로스-주소 이중소비 방어
  │
  ├──  [1층] UBMS::VolatileCache (최근 10블록)
  │       std::list<UBMS::BlockDelta> m_deltas
  │       UBMS::BlockDelta = {
  │         m_addedUtxo:      새로 생긴 UTXO (맵)
  │         m_spentKeys:      소비된 UTXO key (셋)
  │         m_spentUtxoInfo:  소비 UTXO의 owner/miner
  │         m_transactions:   TX 목록 (서명 제거)
  │         m_addedReferrals: 새 추천인 관계
  │         m_mineAddress, m_reward
  │       }
  │       롤백 = popBack 한 번이면 끝
  │       조회 = 최신부터 역순 탐색 (O(10) 최대)
  │
  ├──  [2층] UBMS::ConfirmedCache (메모리 상주)
  │       m_childToParent:     리퍼럴 1:1 맵
  │       m_parentToChildren:  리퍼럴 1:N 맵
  │       m_nodeInfo:          채굴자별 통계
  │       m_mineTimeLast:      최근 100블록 채굴 시간
  │
  └──  [3층] DB (영구 저장소)
          TX, UTXO, 소유자/채굴자/주소 인덱스 저장
          Bloom filter로 미존재 키 빠른 제외

조회 우선순위 (상위 캐시부터 폴백)

UTXO 소비 확인 (isSpentKey):
  1) volatile.spentKeys → true면 즉시 소비됨
  2) volatile.addedUtxo → 있으면 미소비
  3) DB 조회 → 없으면 소비됨

잔액 조회 (getBalance):
  DB(owner 인덱스) + volatile(addedUtxo - spentKeys) 합산

TX풀 통합 조회 (getInputWithPool):
  DB UTXO + volatile 필터링 + TX풀 잔돈(available) 결합

블록차분 변경분 추출 (makeDelta)

블록 하나가 차분 하나로 변환되는 과정:

makeDelta(block):
  단계 1: 블록 기본 정보 복사 (height, hash, mineAddress, reward)

  단계 2: 각 TX 처리
    a) signature, publicKey 제거 → m_transactions (메모리 절약)
    b) output → UBMS::S_UTXO 변환 → m_addedUtxo[txid:index]
    c) input → m_spentKeys.insert(txid:index)
    d) referral → m_addedReferrals.push_back({child, parent})

  단계 3: 스테이킹 리워드 → m_addedUtxo에 추가

  단계 4: 중복 제거 (같은 TX에서 추가+삭제면 삭제 우선)
    for each spentKey: m_addedUtxo.erase(key)

  단계 5: spent UTXO 정보 사전 수집 
    for each spentKey:
      volatile 또는 DB에서 owner/minerAddress를 미리 조회
      → m_spentUtxoInfo[key] = {owner, minerAddress}
      → DB 커밋 시 getUTXO 실패해도 인덱스 안전하게 삭제 가능

영리한 롤백 전략

추가 (addBlock):
  makeDelta(block)
  → m_confirmed.applyDelta(delta)   // 리퍼럴/노드정보 즉시 반영
  → m_volatile.pushBack(delta)      // delta 리스트에 추가
  → if size > 10: popFront → commitToDb()  // 오래된 것 DB 이관

롤백 (rollBack):
  m_volatile.popBack()               // delta 통째로 제거 (O(1))
  m_confirmed.rollbackReferrals()    // 리퍼럴 역순 제거
  m_confirmed.rollbackNodeInfo()     // 채굴 통계 감산
  → 인덱스 정리 불필요, UTXO 가감연산 불필요
  → delta 제거만으로 자동 원복

비트코인 코어의 DisconnectBlock 대비:
  비트코인: 각 TX의 input/output을 역으로 재계산 → O(TX수)
  UBMS:     delta 통째로 pop → O(1)

DB 커밋 + 인덱스 생성 (commitToDb)

volatile이 10블록을 초과하면 가장 오래된 차분을 일괄 커밋.

commitToDb(delta):
  WriteBatch _batch;   // 원자적 배치 쓰기

  1) TX 저장 + 주소별 인덱스
     for each tx:
       addTx(tx)
       addTxAddrIndex(tx.address, txid)  // 발신자 인덱스
       for each output:
         addTxAddrIndex(output.to, txid) // 수신자 인덱스

  2) UTXO 추가 + 소유자/채굴자 인덱스
     for each addedUtxo:
       addUTXO(utxo)
       addOwnerIndex(owner, key)
       if stake.LOCK:
         addMinerIndex(minerAddr, key)

  3) UTXO 삭제(spent) + 인덱스 제거 
     for each spentKey:
       if m_spentUtxoInfo에 사전 수집 정보 있으면:  ← 핵심
         owner/miner 인덱스 안전 삭제 (DB 재조회 불필요)
       else:
         DB에서 getUTXO로 조회 (폴백)
       removeUTXO(txid, index)

  4) Referral 저장
  5) CommittedHeight 갱신
  6) execBatch(_batch)  // 전부 성공하거나 전부 실패

소비 UTXO 사전수집이 핵심인 이유:

인덱스 3종 상세

인덱스생성 시점삭제 시점용도
ownerUTXO 생성 시UTXO 소비 시주소별 잔액/UTXO 조회
minerstake LOCK 시UTXO 소비 시채굴자별 위임 스테이크
txaddrTX 커밋 시삭제 안 함 (이력)주소별 TX 이력 조회
getBalance(address):
  DB 소유자 인덱스 prefix 스캔
  + volatile addedUtxo 중 owner 일치
  - volatile spentKeys 제외
  = 최종 잔액

getStakeToMine(minerAddress):
  DB 채굴자 인덱스 prefix 스캔
  + volatile 중 stake.LOCK && minerAddress 일치
  = 해당 채굴자에게 위임된 스테이크 목록

getTx(address):
  DB 주소 인덱스 prefix 스캔
  + volatile m_transactions 중 address 일치
  = 해당 주소의 전체 TX 이력

동작 흐름:

블록 추가 -> makeDelta(변경분 추출) -> volatile에 pushBack
  -> 10개 넘으면 -> 가장 오래된 delta를 DB에 커밋 (배치 쓰기)
  -> TX풀 정리 -> 인덱스 생성

3.2 독자 설계 UTXO 모델

UBMS의 UTXO는 "UTXO"라는 이름만 비트코인과 같을 뿐, 내부 구조는 완전히 독자 설계. 비트코인의 Script 기반 잠금/해제 모델을 사용하지 않으며, 독자적인 타입 시스템 위에 구축.

비트코인 UTXO vs UBMS UTXO 구조 비교

비트코인 UTXO (CTxOut)
  nValue            금액 (satoshi)
  scriptPubKey      잠금 스크립트 (Script 바이트코드)
  → Script 인터프리터가 해석하여 잠금/해제 판정
  → 고정 바이너리 직렬화 (CSerialize)
  → 스테이킹 개념 없음
  → 메타데이터 없음

UBMS UTXO (UBMS::S_UTXO : UBMS::Serializable)
  index             출력 인덱스
  amount            금액 (mensch 단위)
  timestamp         생성 시각
  owner             소유자 주소
  txid              원본 트랜잭션 ID
  stake {           스테이킹 상태 머신 (UBMS::S_STAKE)
    state           NONE → LOCK → UNLOCK 상태 전이
    minerAddress    위임 채굴자 주소
  }
  ubms {            메타데이터 컨트랙트 (UBMS::S_UBMS)
    metaData        JSON 형태 온체인 메타데이터
    ttl             유효기간 (만료 시 자동 소멸)
    conditions      조건부 실행 규칙
  }

독자 타입 시스템 (UBMS::Serializable)

UBMS의 모든 데이터 구조는 독자 개발된 Serializable 프레임워크를 상속. 비트코인의 CSerialize 매크로나 이더리움의 RLP 인코딩과는 완전히 다른 설계.

UBMS::Serializable (기반 클래스)
  ├─ describe() 순수 가상 함수로 필드를 자기서술적으로 등록
  ├─ reg()         기본 타입 (uint64_t, string, bool, float, double)
  ├─ regEnum()     범위 검증 포함 열거형
  ├─ regStruct()   중첩 구조체 (재귀 직렬화)
  ├─ regVec()      구조체 벡터 (OOM 방어: 크기 상한 제한)
  ├─ regSet()      문자열 집합
  ├─ regRawTail()  나머지 버퍼 전체를 raw 바이너리로
  ├─ regPtrStatus() shared_ptr 존재 여부만 bool로
  │
  ├─ toJson() / fromJson()           JSON 자동 변환
  ├─ serialize() / deserialize()     바이너리 자동 변환
  └─ E_REG_FLAG: REG_ALL / REG_JSON_ONLY / REG_BIN_ONLY  포맷별 필드 선택

핵심 설계 원리:

1. 자기서술적:  describe()에서 필드를 등록하면 JSON/바이너리 양방향 직렬화가 자동 생성됨
2. 이중 포맷:   하나의 구조체가 REST API용 JSON과 P2P용 바이너리를 동시에 지원
3. 재귀 합성:     regStruct/regVec으로 복합 구조체를 제한 없이 중첩 가능
4. 안전한 역직렬화: 버퍼 경계 검사, 벡터 크기 상한, enum 범위 검증, 타입 불일치 무시
5. 포맷 분리:     REG_JSON_ONLY/REG_BIN_ONLY로 네트워크 전송용과 API 응답용 필드를 분리

UBMS 타입 계층도

UBMS::Serializable (libubmstype.so)
  │
  ├── UBMS::S_UBMS            메타데이터 (metaData, ttl, conditions)
  ├── UBMS::S_STAKE           스테이킹 상태 (state, minerAddress)
  ├── UBMS::S_INPUT           TX 입력 (txid, index, amount, stake, ubms)
  ├── UBMS::S_OUTPUT          TX 출력 (to, amount, index, stake, ubms)
  ├── UBMS::S_REFERRAL        리퍼럴 관계 (child, parent, ref[])
  ├── UBMS::S_REFERRAL_TREE   리퍼럴 트리 (재귀 구조: name, level, children[])
  ├── UBMS::S_REWARD          보상 정보 (owner, amount, reward, txid)
  ├── UBMS::S_TRANSACTION     트랜잭션 (type, in[], out[], referral, signature)
  ├── UBMS::S_BLOCK           블록 (헤더 + transaction[] + stakeReward[])
  ├── UBMS::S_BLOCK_META      블록 저장 위치 (fileName, fileOffset, dataSize)
  ├── UBMS::S_BLOCK_MINI      경량 블록 (검증에 필요한 최소 필드만 포함)
  ├── UBMS::S_HEIGHT          피어 높이 정보
  ├── UBMS::S_MINE_INFO       채굴 정보 (stakers[], transactions[], height)
  ├── UBMS::S_WALLET          지갑 (address, balance, publicKey)
  ├── UBMS::S_MESSAGE         P2P 메시지 (header, path[], avoid{}, payload)
  │                           setPayload<T>() / getPayload<T>() 범용 페이로드
  │
  ├── UBMS::S_INPUT_LIST      입력 목록 컨테이너 (독립 직렬화)
  ├── UBMS::S_BLOCK_LIST      블록 목록 컨테이너 (독립 직렬화)
  └── UBMS::S_TRANSACTION_LIST 트랜잭션 목록 컨테이너 (독립 직렬화)

비트코인과의 핵심 차이 요약

항목Bitcoin UTXOUBMS UTXO
잠금 모델Script 바이트코드 (OP_DUP, OP_HASH160...)상태 머신 (NONE→LOCK→UNLOCK)
스크립트 VMScript 인터프리터 필수VM 없음 — 네이티브 C++ 처리
스테이킹불가능 (외부 프로토콜 필요)UTXO 자체에 S_STAKE 내장
메타데이터OP_RETURN 80바이트 제한S_UBMS: JSON 메타 + TTL + 조건 무제한
직렬화CSerialize 매크로 (바이너리 전용)Serializable: JSON + 바이너리 자동 이중 생성
추천인불가능S_REFERRAL: 5단계 유통인 체인 내장
보상coinbase TX 하나S_REWARD[]: 채굴 5% + 스테이킹 95% 분배
검증 전파전체 블록 전송S_BLOCK_MINI: 경량 블록으로 검증자 대역 절감
위임 채굴불가능S_STAKE.minerAddress로 UTXO 레벨 위임

UBMS는 UTXO라는 개념적 모델(미사용 출력 추적)만 차용했을 뿐, 잠금/해제 방식, 상태 관리, 메타데이터, 직렬화 엔진까지 전부 독자 설계.

UTXO 조회 순서:

DB(owner 인덱스) -> volatile에서 spent 필터링 -> TX풀 예약 풀 반영
= 최종 사용 가능 잔액

3.3 Shifted Sigmoid 보상 알고리즘

UBMS의 핵심 알고리즘인 Shifted Sigmoid은 스테이킹 보상을 비선형으로 분배. 대량 스테이킹 독식을 구조적으로 방지하는 것이 목적.

Sigmoid 가중치 계산 (백서 인용)

$$R(x) = \frac{1}{1 + e^{-z}}$$
$$z = \left(\frac{x + s}{T} - 0.5\right) \times 10$$
  x : 해당 스테이커의 스테이킹 수량
  T : 전체 스테이커 스테이킹 합계
  r = 0.2 (좌측 이동 비율)
  s = T × r (이동값)
  10을 곱해 소지분과 대지분 간 격차를 유의미하게 증폭

개별 스테이커 보상 공식

$$\text{reward}(x) = (\text{block reward} \times 95\%) \times \frac{R(x)}{\sum R(x_i)}$$
$$z = \left(\frac{x + T \times 0.2}{T} - 0.5\right) \times 10$$

보상 분배 구조:

블록 보상 분배:
  채굴자: 블록 보상의 5%   ← PoW
  스테이커: 블록 보상의 95% ← PoS (Shifted Sigmoid 비율로 분배)

효과:

3.3.1 소각 메커니즘 (Burn Mechanism)

PoS 보상 분배 시 참여 노드 수가 적을 때 일부 보상을 자동 소각(Burn)하는 공급 조절 메커니즘이 내장되어 있다.

$$\text{PoS 분배율} = \max(0.01,\;\min(1,\;\tfrac{N}{10{,}000})) \times 100\%$$
$$\text{PoS 소각률} = \Big(1 - \max(0.01,\;\min(1,\;\tfrac{N}{10{,}000}))\Big) \times 100\%$$
노드 수         분배율       소각률       비고
0              0%          100%        PoS 보상 전액 소각
100            1%           99%        1% 분배, 99% 소각
1,000         10%           90%        10% 분배, 90% 소각
5,000         50%           50%        50% 분배, 50% 소각
9,500         95%            5%        95% 분배, 5% 소각
10,000 이상    100%            0%        전액 분배, 소각 없음

설계 효과:

3.4 반감기 스케줄

초반 채굴 단계

채굴 기간: 6시간 = 6 × 60 × 60 = 21,600초
블록 생성 시간: 10초/블록
총 블록 수: 21,600 / 10 = 2,160블록
반감기 간격: 540블록
초기 보상 R₀: 1,000 UBMS/블록
반감기 횟수: 4회

구간별 채굴량:

구간 1: R₀     = 1,000 × 540 = 540,000 UBMS    (블록 0 ~ 539)
구간 2: R₀/2   =   500 × 540 = 270,000 UBMS    (블록 540 ~ 1,079)
구간 3: R₀/4   =   250 × 540 = 135,000 UBMS    (블록 1,080 ~ 1,619)
구간 4: R₀/8   =   125 × 540 =  67,500 UBMS    (블록 1,620 ~ 2,159)
─────────────────────────────────────────────
$$C_1 = \sum C_{1i} = 1{,}012{,}500 \;\text{UBMS}$$

후반 채굴 단계

블록 생성 시간: 10분/블록
연간 블록 수: 365 × 24 × 60 / 10 = 52,560블록/년
반감기 간격: 4 × 52,560 = 210,240블록 (약 4년)
후반 초기 보상 R₀': 48 UBMS/블록

구간별 채굴량:

 구간  5: 48    × 210,240 = 10,091,520 UBMS   (블록 2,160 ~ 212,399)
 구간  6: 24    × 210,240 =  5,045,760 UBMS   (블록 212,400 ~ 422,639)
 구간  7: 12    × 210,240 =  2,522,880 UBMS   (블록 422,640 ~ 632,879)
 구간  8:  6    × 210,240 =  1,261,440 UBMS   (블록 632,880 ~ 843,119)
 구간  9:  3    × 210,240 =    630,720 UBMS   (블록 843,120 ~ 1,053,359)
구간 10:  1.5  × 210,240 =    315,360 UBMS   (블록 1,053,360 ~ 1,263,599)
구간 11:  0.75 × 210,240 =    157,680 UBMS   (블록 1,263,600 ~ 1,473,839)
─────────────────────────────────────────────
$$C_2 = \sum C_{2j} \approx 20{,}000{,}000 \;\text{UBMS}$$

총 발행량 요약

$$\text{총 발행} = C_1 + C_2 = 1{,}012{,}500 + 20{,}000{,}000 \approx 21{,}012{,}500 \;\text{UBMS}$$

PoS 소각분을 제외하면 실제 유통량은 더 적음

3.5 PoB (Proof of Behavior) — 5단계 유통인 수수료 분배

UBMS의 세 번째 합의 축인 PoB는 "행위 증명" 메커니즘. 트랜잭션 수수료가 5단계 유통인(Distributor) 체인을 따라 온체인 자동 분배.

수수료 분배 비율 (백서 인용)

전체 수수료 = F 일 때:

  1대 (직접 추천인)    →  F × 60%
  2대                  →  F × 20%
  3대                  →  F × 10%
  4대                  →  F ×  7%
  5대 (최상위)          →  F ×  3%
  ───────────────────────────
  합계                     100%

효과:

3.6 동적 수수료 체계

수수료는 고정이 아닌 시장 상황에 따라 자동 조정. 외부 시장가 데이터를 활용하여 합리적 수수료를 산출.

수수료 공식 (백서 인용)

$$EF = \sqrt{\frac{v}{v_0}} = \sqrt{\frac{v}{10{,}000}}$$
$$F = B \times EF \times CF = 1{,}000 \times \sqrt{\frac{v}{10{,}000}} \times CF$$
  v₀ = 10,000 원 (기준 시장가)
  B  = 1,000 원 (기저 수수료)
  CF = 최근 250개 블록의 혼잡도 반영, 기본값 1.0

계산 예시:

예시 1: 시장가 v = 10,000 원
  EF = √(10,000 / 10,000) = √1 = 1
  F  = 1,000 × 1 × 1.0 = 1,000 원

예시 2: 시장가 v = 100,000,000 원
  EF = √(100,000,000 / 10,000) = √10,000 = 100
  F  = 1,000 × 100 × 1.0 = 100,000 원

비트코인과 이더리움의 수수료가 거래 금액과 무관하게 고정/혼잡 기반인 반면, UBMS는 외부 시장가 기반 경제 팩터를 도입하여 거래 규모에 비례하는 합리적 수수료를 구현.

3.7 UTXO 기반 메타데이터 스마트 컨트랙트

UBMS는 UTXO 위에 메타데이터를 탑재하여 스마트 컨트랙트를 구현. 이더리움의 계정 모델이 아닌, UTXO 확장 방식.

UBMS::S_UTXO.ubms 필드:
  meta     메타데이터 (온체인 저장)
  ttl      유효기간 (만료 시 자동 소멸)
  조건실행  조건부 UTXO 잠금/해제

온체인/오프체인 혼합 실행 모델:


4. PSAN 네트워크 아키텍처

PSAN(Role-Polymorphic Self-Adjusting Network, 역할 다형성 자율 조정 네트워크)은 UBMS의 P2P 네트워크 설계 철학.

핵심 원리

1. 역할 다형성: 하나의 노드가 릴레이/투표자/채굴자 역할을 동적으로 수행
2. 자율 조정:   네트워크 규모에 따라 BP(Blueprint) 수를 자동 산출
3. CF 완화:     메시지 플러딩 방지, 결정론적 경로로 대역 낭비 제거

BP(Blueprint) 계산 공식 (백서 인용)

$$R = \max\!\Big(3,\;\lfloor \log_2(N) \,/\, 2 \rfloor \times 2 + 1\Big)$$
$$V = \max\!\Big(5,\;\lfloor \log_2(N) \,/\, 1.2 \rfloor \times 2 + 1\Big)$$

N = 전체 노드 수, 항상 홀수로 설정하여 다수결 명확화

노드 수별 BP 예시

100개 노드:      log₂(100) ≈ 6.64    →  R = 3,   V = 11
1,000개 노드:    log₂(1000) ≈ 9.96   →  R = 5,   V = 21
10,000개 노드:   log₂(10000) ≈ 13.28 →  R = 7,   V = 51
100,000개 노드:  log₂(100000) ≈ 16.61→  R = 11,  V = 101

최소 합의 요건

릴레이 노드  3개 이상
투표 노드    5개 이상
채굴 노드    1개 이상
합계        최소 9개 노드로 합의 가능

비콘 체인 없는 완전 분산형 합의:
  별도의 비콘 체인이나 중앙 코디네이터 없이
  노드 간 직접 투표로 합의를 달성함

4.1 스레딩 모델

메인 스레드
  UBMS::EventBase (신호 처리)
  P2P 허브
    UBMS::UringPool (CPU 코어 수만큼 스레드)
      UBMS::ServerBinP2P (인바운드 P2P)
      UBMS::ServerWeb (웹소켓)
    워커 스레드들 (각각 독립 큐 보유)
      UBMS::DecodeWorker  (바이너리 프레임 디코딩)
      UBMS::SendWorker    (메시지 직렬화 + 전송)
      UBMS::NodeWorker    (피어 관리, 토폴로지)
      UBMS::ChainWorker   (블록 채굴, 검증, 동기화)
      UBMS::TxWorker      (트랜잭션 전파)
    UBMS::HttpWorker (REST API)

4.2 메시지 흐름

수신:

UBMS::ServerBinP2P::onRead (UBMS::UringPool 스레드)
  -> DecodeWorker 큐에 push
  -> 32바이트 메시지 ID 중복 확인
  -> 평문 해제 또는 복호화
  -> p2p::execPlain/execCrypto (라우팅)
  -> NodeWorker / ChainWorker / TxWorker 큐에 push

전송:

워커에서 UBMS::SendWorker::sendToOutbound() 호출
  -> 직렬화 + 압축(평문) 또는 암호화
  -> 32바이트 메시지 ID 생성
  -> UBMS::ClientBinP2P::sendMessageBinary()

4.3 P2P 프로토콜

메시지 구조 (UBMS::S_MESSAGE):

messageId   32바이트 해시
header      명령 식별자 (REQUEST_INIT, VOTE_BLOCK, ADD_BLOCK 등)
type        페이로드 타입
payload     직렬화된 데이터
ttl         가십 전파 수명 (기본값 5)
priority    우선순위
path        라우팅 경로

피어 핸드셰이크:

아웃바운드 연결 -> REQUEST_INIT(평문) -> RESPONSE_INIT(평문)
  -> REQUEST_PEER_LIST(암호) -> RESPONSE_PEER_LIST(암호)
  -> 토폴로지 구성

가십 3가지 모드:

GOSSIP       무작위 5개 피어에 전파 (전통 가십, 보조용)
             TTL=5, XOR 모듈러2 기반 피어 거리 계산
GOSSIP_PATH  경로 내장형 전달 (3경로: 최단 + 좌편향 + 우편향)
             메시지에 path[]를 싣고 다음 노드 한 칸만 전진
             루프 구조적 차단, 중간 판단 불필요
GOSSIP_DIR   지향성 가십 (결정론 격자 기반 부채꼴 전파)
             방향 벡터 u=(sx,sy)를 메시지에 내장
             전방 이웃만 선택 (delta dot u > 0)
             팬아웃 최대 3, TTL = max(3, floor(0.8 * 대각선))

4.4 합의 흐름 (PoW + PoS + PoB 하이브리드)

RESET (라운드 초기화)
  -> REQUEST_MINE_INFO (TX 목록 수집)
  -> MINE (PoW: 블록 생성, 난이도 충족 해시 탐색)
  -> DISTRIBUTE_BLOCK (PSAN 경로로 검증자에게 전달)
  -> VOTE_BLOCK (PoS: 스테이커 검증자가 투표)
  -> VOTE_BLOCK_AGREE (70% 이상 승인, BFT 2/3 기준 + 안전 여유)
  -> ADD_BLOCK (체인에 추가)
     +-> 채굴자 보상 5%
     +-> 스테이커 보상 95% (Shifted Sigmoid 분배)
     +-> TX 수수료 -> 5단계 유통인 분배 (PoB: 60/20/10/7/3%)
  -> 새 RESET

블록 부족 시:

REQUEST_BLOCK -> RESPONSE_BLOCK -> ACCEPT_RESPONSE_BLOCK
  -> 높이가 따라잡으면 정상 모드 전환

5. 검증 체계

UBMS::InspectManager가 9개의 세부 검증기를 통합 관리.

UBMS::InspectTx        TX 구조 검증
UBMS::InspectUtxo      UTXO 유효성
UBMS::InspectBlock     블록 해시, 이전해시, 머클루트, 난이도, 타임스탬프
UBMS::InspectInput     입력 유효성
UBMS::InspectSpent     UTXO 소비 여부
UBMS::InspectStake     스테이크 검증
UBMS::InspectReferral  추천인 검증
UBMS::InspectBalance   잔액 검증
UBMS::InspectSignature 서명 검증

서명 중복 방지: 최근 서명을 윈도우 기반으로 추적.

Inspector (감사 도구):

buildReport()로 주소별 종합 감사 실행
  - UTXO 스냅샷 vs DB 일치성
  - 마이닝 보상 테이블 검증
  - 전체 블록 리플레이 시뮬레이션
  - 이중 지불 탐지

6. 기반 라이브러리 특징

6.1 io_uring 비동기 I/O (libubmsio_uring.so)

Linux io_uring을 직접 래핑한 고성능 I/O 엔진. libevent의 bufferevent를 대체하며, 훨씬 적은 시스템콜로 동일 작업을 수행.

핵심 최적화:

Multishot Accept/Recv  SQE 재등록 없이 연속 수신
Zero-Copy Send         커널이 직접 버퍼 참조, 메모리 복사 제거
Provided Buffer Ring   커널 관리 버퍼 풀, 할당 비용 제거
Fixed FD               fd 사전 등록, 조회 비용 제거
Batch Submit           여러 SQE를 한 번에 제출
Backpressure           수신/송신 큐 크기 제한으로 메모리 안정성

세대 번호(gen)로 stale CQE 감지: 연결이 끊긴 후 뒤늦게 도착하는 완료 이벤트를 안전하게 무시.

UBMS::UringSession이 per-fd 상태를 관리하며, 참조 카운팅(incRef/decRef)으로 안전하게 해제.

6.2 libevent 기반 이벤트 아키텍처 — Qt/Boost 없는 독자 설계

UBMS는 Qt의 시그널/슬롯, Boost.Asio의 이벤트 루프, Boost.Signals2의 옵저버 패턴을 libevent 하나로 전부 대체했다. 외부 GUI 프레임워크나 대형 라이브러리 의존 없이, libevent의 이벤트 루프를 기반으로 6가지 영역에 걸쳐 독자적인 이벤트 시스템을 구축.

6.2.1 이벤트 루프 엔진

libevent의 event_base를 독립 스레드로 구동하는 래퍼. EVLOOP_NO_EXIT_ON_EMPTY 플래그로 이벤트가 없어도 루프가 유지되며, event_base_loopbreak로 안전하게 종료. 이것이 UBMS 전체 이벤트 시스템의 심장.

UBMS::EventBase
  event_base_new()             이벤트 루프 생성
  event_base_loop()            EVLOOP_NO_EXIT_ON_EMPTY로 상주 구동
  event_base_loopbreak()       안전 종료
  evthread_use_pthreads()      멀티스레드 안전성 활성화

6.2.2 신호-슬롯 시스템 — libevent를 비동기 디스패처로 응용

Qt의 시그널/슬롯을 libevent 위에 재구현. 핵심 아이디어는 event_new로 타이머 이벤트를 만들되 timeval{0,0}으로 즉시 발화시켜, 이벤트 루프가 슬롯 콜백을 비동기 디스패치하게 만드는 것.

사용 예시:

// connect: 슬롯 등록 (weak_ptr로 수명 안전)
signal.connect(instance, "onBlock", &Handler::onNewBlock);

// emit: libevent 이벤트 큐에 즉시 예약, 이벤트 루프가 콜백 실행
signal.emit(instance, "onBlock", blockData);

emit 내부 동작:

1. COW 슬롯 스냅샷 획득 (shared_ptr 참조만 복사, 벡터 복사 제거)
2. EmitEvent 구조체 생성 (args + 슬롯 스냅샷 + 인스턴스)
3. event_new(base, -1, EV_TIMEOUT, cb_emit, emitEvent) 으로 libevent 이벤트 등록
4. event_add(ev, timeval{0,0}) 으로 즉시 발화 예약
5. 이벤트 루프 스레드에서 cb_emit이 슬롯 스냅샷을 순회하며 콜백 실행

안전성 설계 — 5중 방어:

weak_ptr 캡처          소멸된 객체에 콜백하지 않음 (UAF 방지)
COW 슬롯 벡터          emit 중 connect/disconnect 안전 (락프리 읽기)
3단계 상태 머신        Alive -> Marked -> Cleaning (CAS 전이, 재진입 방지)
m_cbCount 원자 카운터  소멸자가 진행 중 콜백 완료를 대기 (UAF 이중 방지)
event_base_once 정리   Marked 이벤트를 이벤트 루프에서 안전하게 지연 해제

Qt의 시그널/슬롯은 MOC 코드 생성기가 필요하고, Boost.Signals2는 헤더 비대로 컴파일 시간이 증가함. UBMS의 신호-슬롯은 순수 C++ 템플릿만으로 타입 안전한 비동기 신호-슬롯을 구현하며, 외부 코드 생성 도구가 불필요.

신호 관리자가 type_index 레지스트리로 전역 신호를 관리하여, 모듈 간 직접 참조 없이 느슨한 결합을 달성.

6.2.3 HTTP 서버 (libubmshttp.so) — libevent의 evhttp 기반 REST API

libevent의 evhttp를 기반으로 완전한 REST API 서버를 구축. 자체 이벤트 루프 스레드에서 독립 동작하며, 런타임 재바인딩(rebind)을 지원.

UBMS::Http          자체 UBMS::EventBase 소유, 독립 스레드 HTTP 서버
UBMS::Router        method+URI 기반 라우팅 테이블 (shared_mutex 보호)
                    addRoute: 외부 접근 가능 엔드포인트
                    addLocal: 로컬 전용 엔드포인트 (관리 API 분리)
UBMS::Forwarder     리버스 프록시, FIXED/ROUNDROBIN 정책
                    path/query 유지, 로컬 요청 제외, prefix 필터링
UBMS::Redirector    301/302/307/308 리다이렉트, ROUNDROBIN 분산
                    브라우저 캐시 고려한 상태코드 선택 (307 임시 vs 308 영구)
UBMS::Abuse         IP+URI별 요청 제한, LRU 캐시로 메모리 상한
UBMS::HttpRequest   onPreRoute 훅으로 포워딩/리다이렉트 파이프라인 구성

요청 처리 흐름:

evhttp 요청 도착
  -> Abuse 검사 (Rate Limiting)
  -> onPreRoute (Redirector -> Forwarder 순서로 가로채기)
  -> Router.route() (method+URI 매칭)
  -> 핸들러 실행 -> sendResponse

이 구조로 단일 HTTP 서버가 REST API + 리버스 프록시 + 리다이렉트 + 레이트 리미팅을 라이브러리 단 하나(libevent)로 제공. nginx나 별도 프록시 서버 없이 노드 자체가 이 모든 기능을 수행.

6.2.4 OS 시그널 핸들링

POSIX 시그널(SIGINT, SIGTERM 등)을 libevent의 이벤트 루프에 통합함. evsignal_new로 시그널을 이벤트로 변환하여, 비동기-안전하지 않은 작업도 이벤트 루프 스레드에서 안전하게 처리.

UBMS::SignalHandler _sigHandler;
_sigHandler.on(SIGINT,  [](int){ g_running.store(false); });
_sigHandler.on(SIGTERM, [](int){ g_running.store(false); });
_sigHandler.start(eventBase.getBase());

6.2.5 이벤트 루프 풀

이벤트 루프를 N개 생성하여 병렬 이벤트 처리를 지원. io_uring 풀과 대칭 구조로, io_uring이 I/O를 담당하고 이벤트 루프 풀이 로직 이벤트를 담당하는 이중 이벤트 엔진 아키텍처를 구성.

6.2.6 설계 요약 — libevent 단일 라이브러리로 6가지 역할

역할libevent API대체 대상
이벤트 루프 엔진event_base_loopBoost.Asio io_context
비동기 신호-슬롯event_new + EV_TIMEOUTQt signal/slot, Boost.Signals2
HTTP REST 서버evhttpnginx, Express, Flask
리버스 프록시evhttp + libcurlnginx proxy_pass
OS 시그널 통합evsignal_new직접 signal() 호출
타이머/주기 이벤트event_add + EV_PERSIST별도 타이머 라이브러리

Qt(~50MB), Boost(~150MB 헤더) 같은 대형 의존성 없이, libevent(~1MB) 하나로 GUI 프레임워크급 이벤트 시스템과 웹 서버 기능을 모두 구현함. 이는 빌드 시간 단축, 배포 크기 최소화, 크로스 컴파일 용이성에 직접적으로 기여.

6.2.7 ubmsnotify — 라이브러리 범용성의 실증

ubmsnotify는 UBMS 블록체인의 독립 실행 응용 프로그램. 메인 노드(ubmsdaemon)와 별도 프로세스로 동작하며, 블록 이벤트를 실시간으로 수신하여 모바일 디바이스에 FCM 푸시 알림을 전송.

이 프로그램이 기술적으로 중요한 이유는 — libubmsevent.so, libubmsio_uring.so가 블록체인 노드 전용이 아니라 범용 서버 애플리케이션 프레임워크로 동작함을 실증하기 때문.

ubmsnotify의 아키텍처:

ubmsnotify (독립 실행 바이너리)
    UBMS::EventBase          libevent 이벤트 루프 (libubmsevent.so)
    UBMS::SignalHandler      SIGINT/SIGTERM 안전 처리 (libubmsevent.so)
    UBMS::UringPool          io_uring 기반 네트워크 I/O (libubmsio_uring.so)
    WebSocket 서버     모바일 클라이언트 접속 수신 (libubmsio_uring.so)
    WebSocketClient    외부 블록체인 노드 구독 (libubmsio_uring.so)
    WorkQueue          단일 워커 스레드 + 1초 주기 틱 (자체 구현)
    FcmSender          Google FCM HTTP v1 API (libcurl + OpenSSL)
    ConsoleView        터미널 대시보드 (fmt::color + ANSI escape + ioctl 터미널 감지)

동작 흐름:

1. WebSocket 서버로 모바일 앱 접속 수신, FCM 토큰 + 지갑 주소 등록
2. WebSocketClient로 블록체인 노드에 WSS 연결, 새 블록 구독
3. 블록 도착 시 TX/스테이크 보상에서 등록된 주소 매칭
4. 매칭된 주소의 FCM 토큰으로 푸시 알림 전송
5. 토큰 자동 갱신, NOT_FOUND 토큰 자동 제거, 외부 연결 자동 재접속

핵심 설계 특징:

스레드 안전성    모든 I/O 콜백이 WorkQueue.post()로 워커 스레드에 직렬화
                 데이터 보호용 mutex 불필요, 큐 조작용 mutex만 사용
자동 복구        FCM 토큰 만료 시 자동 갱신, 외부 노드 끊김 시 자동 재연결
리소스 관리      LRU 기반 토큰 맵, 유효하지 않은 토큰 자동 제거

이것이 입증하는 것:

libubmsevent.so (UBMS::EventBase + UBMS::SignalHandler)     이벤트 루프 프레임워크로 독립 사용 가능
libubmsio_uring.so (UBMS::UringPool + WebSocket)            네트워크 서버 프레임워크로 독립 사용 가능
두 라이브러리 조합                         범용 실시간 서버 애플리케이션 구축 가능

이 라이브러리들을 Ubuntu 패키지로 배포하면, 블록체인과 무관한 일반 서버 애플리케이션 (채팅 서버, IoT 게이트웨이, 실시간 모니터링 서버 등)에도 그대로 활용할 수 있다. 블록체인 프로젝트가 범용 인프라 라이브러리를 자체 생산한 사례로, 이는 프로젝트의 기술적 깊이를 넘어 산업적 활용 가치를 보여준다.


6.3 암호화 (libubmscrypto.so)

RSA-4096           키 생성, 서명, 검증, 암호화
SHA-256            블록/TX 해싱
RIPEMD-160         주소 생성 (독립 구현, OpenSSL 의존 없음)
Base58Check        비트코인 호환 주소 인코딩
AES-GCM            세션 암호화 (진행 중)
HMAC-SHA256        메시지 인증
zlib               메시지 압축 (Zip Bomb 방어: 64MB 제한)

OpenSSL 3.x의 EVP API를 사용하고, default + legacy provider를 모두 로드.

향후 계획: 타원곡선 암호(ECDSA/Ed25519)를 추가하여 서명 크기와 키 생성 속도를 개선하고, 양자내성 암호(PQC) 알고리즘 도입을 위한 OpenSSL 3.x의 provider 구조를 활용할 예정.

6.4 독자 직렬화 엔진 (libubmstype.so)

libubmstype.so는 UBMS의 모든 데이터 구조의 기반이 되는 독자 개발 직렬화 프레임워크.

// 실제 UBMS::S_UTXO의 describe() — 이것만으로 JSON + 바이너리 직렬화가 자동 생성됨
void UBMS::S_UTXO::describe() {
    reg("index", index);
    reg("amount", amount);
    reg("timestamp", timestamp);
    reg("owner", owner);
    reg("txid", txid);
    regStruct("stake", stake);    // S_STAKE 재귀 직렬화
    regStruct("ubms", ubms);      // S_UBMS 재귀 직렬화
}

Serial 계층 (리틀엔디안 바이너리 코덱):

UBMS::Serial::writeUInt64/readUInt64    8바이트 리틀엔디안
UBMS::Serial::writeString/readString    길이 접두 문자열
UBMS::Serial::writeVector/readVector    템플릿 특수화 벡터
  → 벡터 크기 상한으로 OOM 공격 방어
  → 남은 버퍼 크기 검사로 버퍼 오버리드 방지

안전 역직렬화 설계:

- 버퍼 경계 초과 시 나머지 필드 건너뛰기 (부분 객체 안전 생성)
- enum 값 범위 벗어나면 fallback 값으로 복원
- JSON 타입 불일치 시 필드 무시 (크래시 방지)
- 벡터 크기 상한 + 남은 버퍼 대비 검사

6.5 토폴로지 (libubmstopol.so) - 결정론적 2D 격자 + 지향성 가십

이 모듈은 특허 출원된 독자 기술. 핵심 아이디어: 모든 피어를 같은 시드로 같은 바둑판에 배치하고, 그 위에서 경로를 계산.

6.5.1 결정론적 격자 배치

1. 각 피어의 IP와 시드로 HMAC-SHA256 해시를 계산
2. 해시값 4등분 후 XOR로 합쳐서 임계값(threshold) 생성
3. (임계값, IP) 쌍으로 오름차순 정렬
4. 정렬 순서대로 S x S 격자에 순차 배치 (S = ceil(sqrt(N)))
5. 좌표: r = i / S, c = i % S
$$h_p = \text{LOW}_w\!\big(\,F(\text{seed}) \oplus F(\text{ip}(p))\,\big)$$

정렬 키 = (h_p, ip) 오름차순

6.5.2 최단경로 탐색 알고리즘 — 직진 우선 BFS

2D 격자 위에서 출발 노드(start)와 목적 노드(goal)를 잇는 최단 경로를 찾는 것이 경로 전파 방식(GOSSIP_PATH)의 핵심임. UBMS는 일반적인 BFS를 격자 특성에 맞게 확장한 직진 우선 BFS(Straight-First BFS)를 사용.

그래프 모델링:

격자 S × S 위의 각 셀이 노드이고, 8방향 이웃이 간선(모두 가중치 1)임.
상하좌우 4방향 + 대각선 4방향 = 최대 8개 이웃.
경계 셀은 이웃 수가 줄어들고, 빈 셀(피어 미배치)은 건너뜀.

알고리즘 상세 (shorPathIndex):

입력: 시작 인덱스 s, 목표 인덱스 g
출력: s → g 최단 경로 (노드 인덱스 배열)

1. 초기화
   dist[N] = -1 (미방문),  prev[N] = -1 (부모 없음)
   pdx[N], pdy[N] = 0 (각 노드 도달 시 진입 방향 기록용)
   dist[s] = 0,  큐에 s 삽입

2. BFS 루프
   큐에서 u를 꺼냄
   u == g이면 즉시 종료

   u의 8이웃 목록을 구한 뒤, 탐색 순서를 정렬:

     정렬 규칙 1: 직선 이동 우선
       상·하·좌·우(축 정렬) 이웃을 대각선 이웃보다 먼저 탐색

     정렬 규칙 2: 직진 우선 (방향 연속성)
       부모→u 진입 방향과 u→v 방향이 같으면 우선 탐색
       (= 꺾이지 않고 직진하는 경로를 선호)

   정렬된 순서대로 이웃 v를 방문:
     미방문이면 dist[v] = dist[u] + 1, prev[v] = u
     v 도달 방향 (u→v)을 pdx[v], pdy[v]에 저장
     v == g이면 prev 체인을 역추적하여 경로 반환
     아니면 큐에 v 삽입

3. 경로 복원
   prev[g] → prev[prev[g]] → ... → s 역추적 후 reverse

직진 우선이 중요한 이유:

일반 BFS는 같은 거리의 경로 중 아무거나 반환함.
격자에서는 지그재그 경로와 직선 경로가 동일 거리일 수 있음.

예시 (5×5 격자, A→B):
  일반 BFS:    A → ↘ → → → ↗ → B     (지그재그, 같은 홉)
  직진 우선:   A → → → → → B           (직선, 같은 홉)

직선 경로가 메시지 전파에 유리:
  - 중간 노드의 포워딩 방향 판단이 일관됨
  - 편향 경로(P+, P-)와의 경로 분리가 명확해짐
  - 3경로 간 겹침(overlap)이 최소화됨

8이웃 탐색과 체비셰프 거리:

격자에서 8방향 이동 시 최단 거리는 체비셰프 거리(Chebyshev distance):
  d_cheb(A, B) = max(|Δr|, |Δc|)

대각선 이동 1칸 = 수직 1칸 + 수평 1칸을 한 번에 소화
따라서 BFS 홉 수 = max(|r₁-r₂|, |c₁-c₂|)

100×100 격자(10,000 노드)에서 최악 거리 = 99홉
평균 거리 ≈ 66홉

복잡도:

시간: O(N)  — 각 노드 최대 1회 방문, 이웃 정렬은 O(8 log 8) = O(1)
공간: O(N)  — dist, prev, pdx, pdy 배열
N = 격자 내 노드 수

6.5.3 3경로 라우팅 (최단 1 + 좌우 편향 2)

최단경로 BFS를 기반으로, 3개의 독립 경로를 생성하여 메시지 전달 신뢰성을 확보.

경로 P0: BFS 최단 경로 (직진 우선 8이웃 무가중 그래프)
경로 P+: 좌측 편향 경로 (중간점을 왼쪽으로 밀어서 우회)
경로 P-: 우측 편향 경로 (중간점을 오른쪽으로 밀어서 우회)

편향 경로 생성 과정 (Affine Waypoint):

편향 경로는 단순히 BFS를 두 번 호출하되, 중간 경유지(waypoint)를 아핀 변환으로 생성.

편향 경로 생성 단계:

  1. 진행 벡터 d = (goal.c - start.c, goal.r - start.r)
  2. 진행 거리 L = ‖d‖ = hypot(Δc, Δr)
  3. 진행각 θ = atan2(Δr, Δc)

  4. 직선 중간점(t=0.9 지점)을 로컬 프레임으로 변환
     [x_L, y_L] = R(-θ) × (t·Δc, t·Δr)     ← 역회전: 진행축을 x축에 정렬

  5. 법선(y축) 방향으로 편향 적용
     α = k × L × 0.2                          ← 휨 세기 (거리에 비례)
     y_L += α                                  ← 로컬 y축으로 밀어냄

  6. 월드 좌표로 복귀
     [dC, dR] = R(θ) × (x_L, y_L)            ← 정회전으로 원래 방향 복원
     mid = start + (dC, dR)                   ← 절대 좌표

  7. 격자 스냅 + 경계 클램프
     mid = snapClamp(mid)                     ← 부동소수 → 정수 셀, 격자 내 보정

  8. 빈 셀 보정
     mid 셀에 피어가 없으면 반경 3 이내에서 가장 가까운 유효 셀 채택
$$\theta = \text{atan2}(\Delta r,\;\Delta c)$$
$$\alpha = k \times \|\vec{d}\| \times 0.2$$
$$\hat{n} = [-\sin\theta,\;\cos\theta]$$
$$p_m = p_s + t \cdot \vec{d} \;\pm\; \alpha \cdot \hat{n} \qquad (t = 0.9)$$
최종 경로 합성:
  P+ = BFS(start → mid+) ⊕ BFS(mid+ → goal)
  P- = BFS(start → mid-) ⊕ BFS(mid- → goal)

아핀 변환 적용 순서 (OpenGL의 SRT 행렬곱 순서와 동일):

S (Shear)  : 법선 방향 휨 적용 (α만큼 밀어냄)
R (Rotate) : 진행각 θ로 회전/역회전
T (Translate): 시작점 좌표로 평행이동

순서: 로컬 변환(역회전 → 휨 적용 → 정회전) → 절대 좌표 이동
이 순서가 뒤바뀌면 중간점이 격자 밖으로 벗어남

경로 분리 보장:

t = 0.9로 설정하여 중간점이 목적지의 90% 지점에 위치
→ 출발~중간점 구간에서 최단경로(P0)와 겹칠 확률이 극히 낮음
→ 3경로가 격자 위에서 부채꼴 형태로 펼쳐져 독립성 확보

+k (좌측)와 -k (우측)를 대칭 적용하므로
P+와 P-는 P0 기준 양쪽으로 갈라짐

6.5.4 지향성 가십 (Directional Gossip)

1. 발신 노드가 이웃에게 보낼 때 방향 벡터 u = (sx, sy)를 메시지에 내장
2. 수신 노드는 8이웃 중 "전방 이웃"만 선택해서 전달
   전방 조건: δ · u > 0 (이동벡터와 방향벡터의 내적이 양수)
3. 팬아웃 최대 3
4. TTL = max(3, floor(0.8 × D + 0.5)),  D = sqrt((S-1)² + (S-1)²)

성능 비교 (N=10,000 노드, S=100):

                     총 전송 수       지연         재현성
최단경로 전파:       ~100            O(√N)        결정론적
경로 3개 전파:       ~336            O(√N)        결정론적
지향성 가십:         ~30,000         O(√N)        결정론적
전통 가십:           ~399,000        O(log N)     비결정적

6.5.5 운용 전략

평시:     경로 3개로 전역 신호 전달 (대역 최소)
장애시:   지향성 가십 보조 활성화 (커버리지 확보)
전통가십: 피크/중복 비용이 커서 상시 운용 비권장

6.5.6 독자 DHT 피어 관리 — 아웃바운드 전용 버킷

UBMS의 DHT는 Kademlia 프로토콜이 아닌 완전한 독자 설계. 이름만 DHT일 뿐 구조와 동작 방식이 근본적으로 다르다.

XOR 거리:     SHA256(ip1) XOR SHA256(ip2)의 상위 64비트
버킷 구조:    고정 개수, log2(distance) 기반 분류 (Kademlia는 160개 k-bucket)
버킷 용도:    아웃바운드 전용 (연결할 대상 관리, 인바운드는 별도)
버킷 크기:    Kademlia의 k=20 대비 대폭 확장
정렬 기준:    XOR 거리 오름차순, 타이브레이커 ip 사전순
교체 정책:    가장 먼 피어 교체 (Kademlia는 가장 오래된 피어 유지)
COW 갱신:     atomic shared_ptr로 버킷 전체를 스냅샷 교체
회전 엣지:    Near/Far/Storage 3종 캐시, 20~30%씩 주기적 갱신
가십 중복:    해시셋 + FIFO 큐 (상한 제한)

Kademlia와의 핵심 차이:

Kademlia                        UBMS DHT
160개 k-bucket (비트별)         고정 개수 버킷 (log2 구간)
k=20 (버킷당 20개)             대폭 확장된 버킷 용량
양방향 (요청+응답)              아웃바운드 전용
가장 오래된 피어 우선           XOR 거리 가까운 피어 우선
FIND_NODE/STORE 프로토콜        격자 + 가십 + 회전 엣지 조합
핑-퐁 기반 활성 확인            client 유효성 직접 검사

버킷 수와 버킷 용량은 상수이며, 네트워크 규모에 따라 조정 가능. 독자 DHT에서 버킷은 피어 목록을 거리별로 분류하는 단순한 리스트이고, 특허 기술인 격자 라우팅과 지향성 가십이 메시지 전파의 핵심을 담당하므로 DHT는 피어 발견 보조 역할에 한정.

6.6 유틸리티 (libubmsutil.so)

UBMS::Worker<T> 템플릿: 큐 기반 워커 스레드의 공통 패턴.

push()로 작업 추가, process()에서 처리
callSync()로 워커 스레드에서 동기 실행 (promise/future)
60초 타임아웃 안전장치

UBMS::QueueSafe<T>: condition_variable 기반 스레드 안전 큐.

UBMS::Arith: uint64_t 오버플로/언더플로 검사. mulDiv()에서 uint128_t 중간값 사용.


7. 멀티스레드 안전성

7.1 락 전략

컴포넌트락 타입읽기쓰기
UBMS::CacheManagershared_mutexshared_lock (동시 다중)unique_lock (배타적)
UBMS::Chainmutex-addBlock/rollBack 직렬화
UBMS::BlockCurrentatomic shared_ptr + mutexatomic load (락 없음)mutex 보호
UBMS::BlockMetaFullCacheatomic shared_ptr + mutexatomic load (락 없음)COW 교체
UBMS::BlockPoolatomic shared_ptr + mutexatomic load (락 없음)COW 교체
UBMS::VolatileCacheshared_mutexshared_lockunique_lock
UBMS::ConfirmedCacheshared_mutexshared_lockunique_lock
UBMS::TxCurrentshared_mutexshared_lockunique_lock
DBmutex모든 연산 직렬화모든 연산 직렬화

7.2 TOCTOU 회피 설계

취약한 설계 (분리 호출):

Thread A: isSpentKey(key) → false (미소비)
  --- 이 사이에 Thread B가 addBlock()으로 key 소비 ---
Thread A: addTx(key) → 이미 소비된 UTXO로 TX 생성 (이중 지불!)

UBMS의 해결: 원자적 검사 함수

checkDoubleSpendWithPool(address, key):
    // CacheManager의 shared_lock이 이미 걸린 상태

    // 1단계: 확정 원장 소비 확인
    //        TX풀 잔돈이면 통과, 아니면 거부

    // 2단계: TX풀 소비 확인 (같은 주소)
    //        이미 소비 예약되었으면 거부

    // 3단계: 전역 크로스-주소 이중소비 확인
    //        다른 주소의 TX가 이미 사용했으면 거부

    // 전부 통과하면 미소비 확인 완료

원자적 검사 함수 전체 목록:

함수검사 범위용도
checkDoubleSpendWithPool()확정 + TX풀 + 전역이중 지불 다단 검사
isNotSpentKeyWithPool()확정 + TX풀 잔돈미소비 확인
getUTXOWithPool()확정 + TX풀UTXO 통합 조회
getInputWithPool()DB + volatile + TX풀입력 수집
getBalanceAvailableWithPool()DB + volatile + TX풀사용 가능 잔액
getStakeWithPool()DB + volatile + TX풀스테이크 통합 조회

락 계층 설계 (교착 방지):

UBMS::Chain::m_mutex (std::mutex, 배타적)     ← addBlock/rollBack 직렬화
  └→ UBMS::CacheManager::m_mutex (shared_mutex) ← 읽기/쓰기 분리
       └→ UBMS::VolatileCache::m_mutex          ← 내부 보호
       └→ UBMS::ConfirmedCache::m_mutex         ← 내부 보호
       └→ UBMS::TxCurrent::m_mutex              ← 내부 보호

규칙: 외부 → 내부 순서로만 취득, 역순 불가 (교착 원천 차단)

7.3 락프리 읽기 패턴

현재 블록, 블록 메타 전체캐시, 블록풀은 읽기 경로에서 잠금 없이 현재 상태의 스냅샷을 즉시 가져올 수 있도록 설계됨. 쓰기는 단일 경로로 제한하여 데이터 경합을 원천 차단하면서도, 읽기 쪽에 대기나 차단이 발생하지 않음.

7.4 TX풀 이중 소비 방지 — 4단 충돌 검사

isConflict_(reserved, tx):

  검사 1: TX 내부 입력 중복
    같은 TX 안에서 동일 UTXO를 두 번 참조하면 거부

  검사 2: 주소별 예약 풀 이중 소비
    같은 주소의 이전 TX가 이미 소비 예약한 UTXO면 거부

  검사 3: 전역 크로스-주소 이중 소비 
    다른 주소의 TX가 이미 사용한 UTXO면 거부
    → m_globalSpentKeys (unordered_set, O(1) 조회)

  검사 4: TX 내부 출력 인덱스 중복
    같은 출력 인덱스를 두 번 생성하면 거부

TX풀 예약 풀 (UtxoPool) 동작:

applyReserveAdd_(tx):
  output 중 자기 주소로 돌아오는 잔돈 → available에 추가
  input → spent_keys + m_globalSpentKeys에 등록

효과:
  A가 5 UBMS UTXO로 3 UBMS 전송 시
  → spent_keys: {원본 5 UBMS key}
  → available: {잔돈 2 UBMS key}   ← 다음 TX에서 즉시 사용 가능

블록 확정 후 TX풀 정리 (3단계):

1) syncCurrentTx(confirmedTxList)         → txid로 확정된 TX 제거
2) removeConflictingCurrentTx(spentKeys)  → 충돌하는 미확정 TX 제거
3) cleanupCurrentTxByHeight(minHeight)    → 너무 오래된 TX 제거

8. 성능 분석

이하 O() 표기는 시간 복잡도(Time Complexity)를 나타낸다. O(1)은 데이터 양과 무관하게 일정한 시간, O(N)은 데이터 양에 비례하는 시간을 의미.

8.1 조회 성능

연산경로비고
잔액 조회DB(owner 인덱스) + volatile 필터링O(UTXO 개수)
TX 존재 확인volatile(10블록) -> DB최신 TX는 메모리에서 즉시
UTXO 소비 확인volatile spentKeys -> DBO(10) 최대
최근 TX 조회volatile 역순 -> DBtxid 타임스탬프 정렬
referral 조회ConfirmedCache 메모리O(1) 해시맵

8.2 쓰기 성능

연산비용비고
블록 추가O(TX수 + UTXO수)volatile pushBack
DB 커밋O(차분 크기)10블록마다 한 번, 배치 쓰기
롤백O(1)volatile popBack, DB 건드리지 않음

8.3 I/O 성능 — 실측 벤치마크

측정 환경: AMD Ryzen 7 2700X (2018년 출시), 싱글스레드 (1 core), 3초 측정, localhost
8년 전 CPU의 단일 코어만으로 측정한 수치. 동일 세대 Ryzen 9 3900X에서는 싱글코어 기준 30% 이상 향상 확인

처리량 — 텍스트 프로토콜

메시지 크기클라이언트처리량 (msg/s)송신수신
32B11,195,7573,587,4333,587,271
32B1010,132,69260,851,19230,398,077
256B1883,1322,649,5812,649,396
256B104,284,16527,230,56412,852,496
1KB1801,8052,405,4162,405,416
1KB101,628,3768,246,6304,885,129
4KB1320,2681,299,084960,806
4KB10205,1661,706,216615,498

처리량 — 바이너리 프로토콜

메시지 크기클라이언트처리량 (msg/s)송신수신
32B11,431,7834,295,6704,295,349
32B109,755,88574,314,91529,267,656
256B11,231,1943,693,6943,693,584
256B105,260,27231,169,94015,780,817
1KB1627,7741,883,3221,883,322
1KB101,709,7458,647,5785,129,235
4KB1509,8161,687,9591,529,449
4KB10447,8002,172,0841,343,400

레이턴시 (64B echo, 1,000회 반복)

지표
평균32.0 us
p5032.0 us
p9938.1 us
min28.1 us
max40.6 us

연결 속도

지표
연결 속도12,419 conn/s
총 연결1,000건 / 0.08초

실측 수치 요약

위 벤치마크는 libubmsio_uring.so 자체 실측값이며, 타 라이브러리와의 동일 조건 비교 측정은 수행하지 않았다. 다만 싱글스레드에서 1KB 메시지 170만 msg/s, 32B 메시지 1,013만 msg/s, p99 레이턴시 38us는 io_uring의 커널 수준 최적화를 실용적으로 잘 활용한 결과이며, 공개된 epoll 기반 라이브러리(libevent, libuv, Boost.Asio 등)의 벤치마크 자료와 대조해도 상당히 높은 수치.

주요 실측 수치:

- 바이너리 1KB, 10클라이언트: 1,709,745 msg/s (싱글스레드)
- 텍스트 1KB, 10클라이언트: 1,628,376 msg/s (싱글스레드)
- 32B 소형 메시지, 10클라이언트: 10,132,692 msg/s
- p99 레이턴시: 38.1us (64B echo RTT)
- 연결 속도: 12,419 conn/s (1,000건/0.08초)
- 멀티코어 활용 시 추가 향상 확인 (사무실 장비에서 20%+ 향상)

io_uring 자체의 커널 수준 최적화(SQE 배치 제출, 커널 측 폴링, 시스템콜 감소)가 처리량의 주된 원인이며, libubmsio_uring.so는 이 위에 multishot, zero-copy, provided buffers, backpressure를 조합하여 블록체인 노드에 적합한 네트워크 계층을 구성.

벤치마크 바이너리(ubmsio_uring_benchmark)가 빌드 산출물에 포함되어 있으므로, 위 수치는 누구든 동일 환경에서 직접 재현할 수 있다.

8.4 메모리 사용 추정

VolatileCache     ~50MB  (10블록 x 5MB/블록)
ConfirmedCache    ~10MB  (referral tree + nodeInfo)
TxCurrent         ~100MB (pending TX + 예약 풀)
BlockPool         ~100MB (미확정 분기)
합계              ~260MB (정상 상태)

DB           수 GB ~ 수백 GB (블록 데이터)

8.5 네트워크 최적화

메시지 압축       zlib (평문 메시지)
메시지 중복 제거  메시지 ID 해싱 + 윈도우 기반 중복 추적
공개키 캐싱       LRU 방식 (PEM 파싱 비용 제거)
배치 전송         sendmsg 일괄 전송

9. 보안 설계

9.1 빌드 보안

최상위 빌드 스크립트에서 보안 플래그를 전역 설정하여, 하위 11개 모듈 전체에 자동 적용.

컴파일러 보안

링커 보안

릴리즈 빌드 추가 조치

9.2 암호화 보안

RSA-4096 키 쌍              충분한 키 길이
SHA-256 이중 해싱            주소 생성 시
HMAC-SHA256                  메시지 인증
Base58Check                  체크섬으로 주소 오류 검출
Zip Bomb 방어                압축해제 64MB 제한

9.3 런타임 보안

Arith 오버플로 검사          금액 계산 시 uint64_t 범위 초과 방지
서명 중복 검사               윈도우 기반 서명 추적
TOCTOU 해소                  이중 지불 원자적 검사
globalSpentKeys              크로스-주소 이중소비 차단

9.4 직렬화 안전성

libubmstype.so의 describe() 자기서술 패턴은 직렬화와 역직렬화를 동일한 선언에서 자동 생성함. 이로 인해 역직렬화 경로에서 발생할 수 있는 보안 위협이 프레임워크 수준에서 차단.

벡터 크기 상한 검사          비정상 크기 패킷에 의한 메모리 폭주 방지
버퍼 경계 검사               읽기 범위를 초과하는 접근 차단
enum fallback 처리           정의되지 않은 값에 대한 안전한 기본값 적용
수동 파싱 코드 제거          개발자 실수에 의한 역직렬화 취약점 원천 차단

P2P 환경에서 악의적 패킷이 유입되는 것을 전제로 설계되었으며, 대부분의 프로젝트에서 사후 패치로 추가되는 역직렬화 안전성이 여기서는 구조적으로 내장되어 있다.

9.5 테스트 인프라

모듈별 단위 테스트가 GTest 기반으로 구성되어 있으며, 약 5,800줄 규모의 테스트 코드가 존재. 현재 대규모 리팩토링 진행으로 일부 테스트가 갱신 대기 상태이며, 코드 안정화에 따라 순차적으로 복구 예정.


10. 설계 장점 요약

10.1 캐시 설계

10.2 I/O 설계

10.3 동시성 설계

10.4 데이터 설계

10.5 네트워크 설계 (특허 기술)

10.6 경제 설계 (토크노믹스)


11. 데이터 구조 핵심

UBMS::S_BLOCK (블록)

hash, previousHash, merkleHash, height, nonce, difficulty
transaction[], stakeReward[]
.
.
.

UBMS::S_TRANSACTION (트랜잭션)

type (NONE/LOCK/UNLOCK/REFERRAL)
txid, address, signature, publicKey
in[], out[], referral
.
.
.

UBMS::S_UTXO (미사용 출력)

txid, index, amount, owner
stake (NONE/LOCK/UNLOCK + minerAddress)
ubms (메타, TTL, 조건)
.
.
.

UBMS::BlockDelta (블록차분)

height, hash, previousHash
addedUtxo{}, spentKeys{}, spentUtxoInfo{}
transactions[], addedReferrals[]
.
.
.

12. 외부 의존성

라이브러리용도라이선스비고
OpenSSL 3.xRSA, SHA, HMAC, 난수Apache 2.0EVP API
liburingio_uring 시스템 인터페이스MIT / LGPL 2.1Linux 5.19+
libevent이벤트 루프, 신호-슬롯, HTTP 서버, OS 시그널, 타이머BSD 3-ClauseQt/Boost 전면 대체
DB영구 KV 저장소BSD 3-ClauseBloom filter
jsoncppJSON 파싱MIT
fmt포맷 출력MIT
zlib압축/해제zlib License
libcurlHTTP 클라이언트MIT/X inspiredFCM 알림용

12.1 라이선스 독립성 — 깨끗한 의존성 구조

블록체인 프로젝트에서 라이선스 문제는 간과하기 쉽지만, 상용화 단계에서 치명적인 장벽이 된다. 실제로 적지 않은 오픈소스 블록체인 프로젝트가 GPL, AGPL, SSPL 등 전염성(copyleft) 라이선스를 가진 라이브러리를 무분별하게 끌어다 쓰면서 라이선스 누더기가 되어 있다. 이 경우 프로젝트 전체가 해당 라이선스 조건에 종속되며, 상용 배포, 독점 라이선스 전환, 기술 라이선싱이 법적으로 불가능하거나 극도로 복잡해진다.

UBMS의 외부 의존성은 전부 허용적 라이선스(permissive license)로 구성:

Apache 2.0       상용 이용 자유, 특허 허가 포함
BSD 3-Clause      상용 이용 자유, 재배포 시 저작권 고지만 필요
MIT               사실상 무제한 사용
zlib License      거의 무제한, 출처 허위 표시만 금지

이 구성이 의미하는 것:

특히 주목할 점은 Qt(LGPL/GPL/상용)와 Boost(BSL-1.0)를 의존성에서 완전히 제거한 것. Qt는 LGPL 조건에서 동적 링킹 의무와 사용자 재링크 보장 등 까다로운 조건이 붙고, 상용 라이선스는 연간 수천 달러의 비용이 발생. UBMS는 libevent(BSD) 하나로 Qt의 시그널/슬롯과 이벤트 루프를 대체함으로써 이 라이선스 부담을 원천적으로 회피했다.

9개 외부 의존성 전부가 허용적 라이선스라는 것은 우연이 아니라 의도적 설계. 이는 프로젝트의 법적 자유도를 최대화하며, 투자자나 파트너에게 라이선스 실사(due diligence) 부담이 없는 깨끗한 코드베이스를 제시할 수 있음을 의미.

12.2 범용 라이브러리로의 성장 가능성

UBMS 프로젝트는 블록체인 노드를 만드는 과정에서 부산물로 독립적 가치를 가진 범용 라이브러리를 여럿 생산했다. 이 라이브러리들은 블록체인과 무관한 일반 서버 애플리케이션에도 그대로 사용할 수 있으며, ubmsnotify(독립 실행 FCM 푸시 알림 서버)가 이를 실증.

독립 배포 가능한 라이브러리:

libubmsio_uring.so   io_uring 기반 고성능 네트워크 서버/클라이언트 프레임워크
                     Server, Client, WebSocket, WebSocketClient, SafeCurl 포함
                     채팅 서버, IoT 게이트웨이, 게임 서버 등에 즉시 적용 가능

libubmsevent.so      libevent 기반 이벤트 엔진 + 비동기 신호-슬롯 + OS 시그널 통합
                     Qt/Boost 없이 이벤트 구동 애플리케이션 구축 가능

libubmstype.so       독자 직렬화 엔진 (describe() 하나로 JSON + 바이너리 자동 생성)
                     protobuf/flatbuffers 대체, 외부 코드 생성 도구 불필요

libubmshttp.so       REST API + 리버스 프록시 + 리다이렉트 + 레이트 리미팅
                     nginx 없이 애플리케이션 레벨에서 HTTP 서비스 구축 가능

libubmscrypto.so     RSA-4096, SHA-256, RIPEMD-160, Base58, HMAC, zlib 통합
                     OpenSSL EVP API 래퍼로 암호화 기능 간편 사용

이 라이브러리들의 라이선스 의존성이 전부 허용적(permissive)이므로, Ubuntu/Debian 패키지(apt)로 배포하거나, vcpkg/Conan 같은 C++ 패키지 매니저에 등록하는 데 법적 장벽이 전혀 없다.

전망:


13. 블록 검증 흐름

UBMS::Chain::addBlock(target)
  |
  +--> UBMS::Chain::m_mutex.lock()
  |
  +--> UBMS::InspectManager::validateBlock()
  |     +--> 해시 검증
  |     +--> 이전 해시 검증
  |     +--> 머클루트 검증
  |     +--> 난이도 검증
  |     +--> 타임스탬프 검증
  |
  +--> UBMS::InspectManager::validateBlockTxSignatures()
  |     +--> 각 TX 서명 검증
  |
  +--> UBMS::InspectManager::validateBlockInputsNotSpent()
  |     +--> 입력 UTXO 소비 여부 검사
  |
  +--> UBMS::CacheManager::addBlock()
  |     +--> makeDelta() (UTXO 변경분 추출)
  |     +--> volatile.pushBack(delta)
  |     +--> confirmed.updateNodeInfo()
  |     +--> confirmed.addReferral()
  |     +--> 오버플로우 시 DB 커밋
  |
  +--> BlockMetaFullCache 업데이트
  +--> BlockCurrent 교체
  +--> BlockPool에서 제거
  |
  +--> Chain::m_mutex.unlock()

14. 결론

UBMS(UTXO-Based Metadata Smart Chain)는 100% 독자 개발된 블록체인 풀노드 시스템으로, "끊임없는 발전: 정지되지 않는 블록체인"을 지향. 수백 개의 헤더/구현 파일, 11개 라이브러리 모듈 + 데몬 + 독립 알림 서버로 구성되며, 외부 프레임워크(Qt, Boost) 없이 표준 C++과 최소한의 허용적 라이선스 라이브러리만으로 전체를 구축했다.

이하는 본 보고서에서 분석한 전체 기술 영역의 요약.

합의 설계 (3항, 5항)

경제 설계 (3항)

네트워크 설계 — PSAN (4항, 6.5항)

캐시 및 데이터 설계 (3항, 10항, 11항)

기반 라이브러리 (6항)

멀티스레드 안전성 (7항)

성능 (8항)

보안 설계 (9항)

라이선스 독립성 및 범용성 (12항)

UBMS는 블록체인 노드를 만드는 과정에서 합의, 네트워크, 캐시, I/O, 이벤트, 직렬화, 보안의 모든 계층을 외부 프레임워크 없이 독자 설계했으며, 그 과정에서 생산된 라이브러리들은 블록체인을 넘어 범용 서버 인프라로서의 가치를 갖는다.

15. 개발 연대표

15.1 구상기 (2022 ~ 2024.10)

15.2 프로토타입기 (2025.2 ~ 2025.4)

15.3 공개 테스트기 (2025.5 ~ 2025.7)

15.4 가운영기 (2025.8 ~ 현재)

15.5 현재 네트워크 현황