<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title> 개발</title>
    <link>https://junmonologue.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 6 Apr 2026 23:39:04 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>jundev</managingEditor>
    <image>
      <title> 개발</title>
      <url>https://tistory1.daumcdn.net/tistory/5089468/attach/5852c65a27664551ac4c11c5d7a37516</url>
      <link>https://junmonologue.tistory.com</link>
    </image>
    <item>
      <title>[1] 왜 지금 &amp;lsquo;KRW 스테이블코인 결제 게이트웨이&amp;rsquo;를 만들려고 하는가</title>
      <link>https://junmonologue.tistory.com/39</link>
      <description>&lt;h1&gt;[1] 왜 지금 &amp;lsquo;KRW 스테이블코인 결제 게이트웨이&amp;rsquo;를 만들려고 하는가&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;원화 스테이블코인이 &amp;lsquo;결제&amp;rsquo;로 들어오면, PG는 결국 온체인 이벤트(토큰 이동)까지 포함해서 정산&amp;middot;대사를 다시 설계해야 한다.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 한 줄이 이 사이드 프로젝트의 출발점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 앞으로 연재할 &lt;b&gt;「KRW Stablecoin Payment Gateway &amp;amp; Settlement System 개발기」 1편&lt;/b&gt;으로,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;지금 한국에서 &lt;b&gt;CBDC / 토큰화 예금 / 원화 스테이블코인&lt;/b&gt;이 실제로 어디까지 왔는지 정리하고&lt;/li&gt;
&lt;li&gt;그 흐름 속에서 내가 풀고 싶은 &lt;b&gt;기술 문제를 개발자 관점으로 재정의&lt;/b&gt;하고&lt;/li&gt;
&lt;li&gt;이 시리즈에서 만들 시스템의 &lt;b&gt;목표&amp;middot;범위&amp;middot;연재 계획&lt;/b&gt;을 잡는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 왜 하필 지금, 왜 하필 이 주제인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국은 카드&amp;middot;계좌이체&amp;middot;간편결제가 이미 &amp;ldquo;완성형&amp;rdquo;에 가깝다.&lt;br /&gt;그래서 나도 처음엔 의문이었다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미 잘 되는데, 굳이 디지털 원화(CBDC)나 스테이블코인을 또 왜?&lt;/li&gt;
&lt;li&gt;이거 진짜 상용으로 가는 건가, 아니면 연구로 끝나는 건가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 자료를 따라가다 보니, 결론은 한 문장으로 정리되더라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;CBDC는 &amp;lsquo;상용 리테일&amp;rsquo;으로 바로 가는 분위기는 아니고, 대신 &amp;lsquo;기관/인프라 실험&amp;rsquo; 쪽으로 진도가 나갔고&lt;br /&gt;스테이블코인은 법&amp;middot;감독 체계를 어떻게 만들지 논쟁이 붙으면서 &amp;lsquo;결제 수단&amp;rsquo; 쪽으로 더 앞에 나와 있다.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자 입장에서 이건 이렇게 번역된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;몇 년 안에 &amp;lsquo;원화 토큰(스테이블코인/토큰화 예금)&amp;rsquo;이 결제 UX에 들어오면,&lt;br /&gt;&lt;b&gt;PG/정산/대사/장애수렴을 온체인까지 포함해서 다시 짜야 한다.&lt;/b&gt;&lt;br /&gt;그걸 코드 레벨로 한번 만들어보자.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 한국의 CBDC 흐름: &amp;ldquo;도입 확정&amp;rdquo;이 아니라 &amp;ldquo;연구&amp;middot;실험의 축적&amp;rdquo;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 제일 먼저 정리할 건 이거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한국은행은 &amp;lsquo;CBDC를 발행하기로 결정했다&amp;rsquo;고 말한 적이 없다.&lt;/b&gt;&lt;br /&gt;공식 표현은 &amp;ldquo;아직 발행 여부를 결정하지 않았고, 연구&amp;middot;실험을 진행 중&amp;rdquo;에 가깝다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1. 리테일 CBDC는 &amp;lsquo;필요성&amp;rsquo;부터 다시 따지는 분위기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국은 이미 전자결제 인프라가 강해서,&lt;br /&gt;리테일 CBDC가 &amp;ldquo;무조건 필요하다&amp;rdquo;로 바로 이어지지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 리테일 CBDC는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기술적으로 가능하냐(가능)&lt;/li&gt;
&lt;li&gt;상용으로 깔았을 때 은행/금융중개에 어떤 영향이 있냐(대체효과)&lt;br /&gt;같은 걸 중심으로 계속 연구하는 흐름이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2. 대신 진도가 난 건 &amp;ldquo;기관용(도매) + 토큰화 예금&amp;rdquo; 쪽 : Project &amp;lsquo;한강&amp;rsquo;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년엔 흐름이 더 명확해졌다.&lt;br /&gt;한국은행이 실거래 기반 실험(Project 한강)을 진행했고, 큰 틀은 이렇게 알려져 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중앙은행 쪽: &lt;b&gt;기관용 CBDC(도매 CBDC)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;은행 쪽: 예금을 토큰으로 바꾼 &lt;b&gt;&amp;lsquo;예금 토큰(토큰화 예금)&amp;rsquo;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;소비자 체감: 예금 토큰을 &lt;b&gt;QR 결제&lt;/b&gt;로 써보는 실험&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 &amp;ldquo;전국민 디지털 현금&amp;rdquo;이 아니라,&lt;br /&gt;&lt;b&gt;&amp;lsquo;은행 돈(예금)&amp;rsquo;을 토큰으로 바꿔서 결제&amp;middot;정산 인프라를 시험해보는 방향&lt;/b&gt;이 먼저 굴러간 거다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.3. 후속 확장(2단계)은 &amp;lsquo;지연/재조정&amp;rsquo; 톤이 맞다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1단계 실험 이후 &amp;ldquo;2단계가 바로 크게 확장된다&amp;rdquo;는 분위기보다는,&lt;br /&gt;&lt;b&gt;비용 부담&amp;middot;상용화 불확실성&amp;middot;은행의 수용성&lt;/b&gt; 같은 이유로&lt;br /&gt;후속 논의가 지연되거나 재조정된다는 보도가 이어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 포인트는 하나다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CBDC가 &amp;ldquo;곧 전국민 상용&amp;rdquo;으로 고정된 게 아니라,&lt;br /&gt;&lt;b&gt;유즈케이스와 사업성/정책성을 계속 재평가하는 상태&lt;/b&gt;라는 것.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 원화 스테이블코인 흐름: &amp;ldquo;감독&amp;middot;발행 구조를 어떻게 만들 건가&amp;rdquo;로 전장이 옮겨짐&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CBDC가 연구/실험 중심으로 쌓이는 동안,&lt;br /&gt;원화 스테이블코인은 &amp;ldquo;제도 설계&amp;rdquo; 쪽에서 더 뜨겁게 붙었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. 2024년 7월: &amp;lsquo;가상자산 이용자 보호&amp;rsquo;는 시작됐지만, 발행&amp;middot;준비금 프레임은 별개였다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 7월 시행된 이용자 보호 법/하위 규정들은&lt;br /&gt;거래소&amp;middot;보관&amp;middot;불공정거래 같은 &amp;lsquo;시장 질서/이용자 보호&amp;rsquo;에 초점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &amp;ldquo;원화 스테이블코인을 누가 어떤 조건으로 발행하고, 준비금을 어떻게 관리하고, 상환을 어떻게 보장할 건지&amp;rdquo;는&lt;br /&gt;별도의 틀로 계속 논의되는 영역이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2. 쟁점 1: 감독 주체(금융당국 vs 중앙은행) / 쟁점 2: 발행 구조(은행 중심 vs 비은행 참여)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 논쟁은 크게 두 축이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;감독 주체&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이걸 전자금융/디지털자산 규율로 볼 건지&lt;/li&gt;
&lt;li&gt;통화&amp;middot;금융안정 관점에서 중앙은행 권한을 얼마나 둘 건지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;발행 구조&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;은행이 중심이 되는 모델로 갈지&lt;/li&gt;
&lt;li&gt;비은행(핀테크/블록체인 기업) 참여를 어디까지 허용할지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 최근 보도에서 반복적으로 거론되는 방향 중 하나가&lt;br /&gt;&lt;b&gt;&amp;lsquo;은행이 과반(예: 51% 이상) 지분을 가진 컨소시엄&amp;rsquo;&lt;/b&gt; 같은 구조다.&lt;br /&gt;(이건 아직 &amp;ldquo;확정&amp;rdquo;이라기보다 &amp;ldquo;유력하게 거론되는 설계안&amp;rdquo; 정도로 두는 게 안전하다.)&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 개발자 시선에서 문제를 다시 쓰면, 결국 이거다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정책 얘기를 길게 했지만, 내가 만들고 싶은 건 &amp;ldquo;정책 해설&amp;rdquo;이 아니다.&lt;br /&gt;개발자 시선에서 진짜 문제는 아래다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원화 스테이블코인이 결제 UX에 들어왔다고 치자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 순간 PG/정산은 &amp;ldquo;HTTP 요청 몇 개 붙이는 문제&amp;rdquo;가 아니라&lt;br /&gt;&lt;b&gt;온체인과 오프체인이 동시에 돈을 움직이는 분산 시스템&lt;/b&gt;이 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.1. 온체인 최종성 vs 서비스 최종성&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;블록에 포함되면 결제 성공으로 볼 건가?&lt;/li&gt;
&lt;li&gt;몇 컨펌을 기다릴 건가?&lt;/li&gt;
&lt;li&gt;reorg(재편성)나 노드 장애가 나면 사용자는 뭘 보게 되나?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;체인에서 확정&amp;rdquo;과 &amp;ldquo;서비스에서 확정&amp;rdquo;은 그냥 같은 말이 아니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.2. 온&amp;middot;오프체인 분산 트랜잭션 (결제/정산의 현실)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정산을 생각하면 보통 이런 형태가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 온체인: 가맹점 쪽 토큰을 회수/소각(burn)하는 트랜잭션&lt;br /&gt;2) 오프체인: 원화 준비금/계좌망을 통해 가맹점 계좌로 실제 이체(또는 그에 준하는 처리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) 성공, (2) 실패하면?&lt;br /&gt;사용자/가맹점 입장에선 &amp;ldquo;돈이 사라진 것처럼 보이는&amp;rdquo; 사고가 난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 여기엔 결국&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Saga(보상 트랜잭션)&lt;/li&gt;
&lt;li&gt;상태 머신(정산 상태 수렴)&lt;/li&gt;
&lt;li&gt;재시도/타임아웃/중복 처리&lt;br /&gt;같은 패턴이 들어갈 수밖에 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.3. 리컨실레이션(정합성 검증)은 &amp;lsquo;옵션&amp;rsquo;이 아니라 &amp;lsquo;기본값&amp;rsquo;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최소한 아래 셋은 계속 맞아야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;온체인: totalSupply / 이벤트(Transfer, Mint, Burn)&lt;/li&gt;
&lt;li&gt;오프체인: 준비금&amp;middot;정산 계정(또는 그 시뮬레이션)&lt;/li&gt;
&lt;li&gt;내부 장부(DB): 주문/결제/정산 상태와 잔액 변화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;셋이 어긋나는 순간, 이 시스템은 &amp;ldquo;결제 인프라&amp;rdquo;라고 부르기 어렵다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.4. 멱등성/동시성, 그리고 장애 전파 차단&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결제 버튼 연타&lt;/li&gt;
&lt;li&gt;네트워크 타임아웃 후 재시도&lt;/li&gt;
&lt;li&gt;중복 HTTP 요청&lt;/li&gt;
&lt;li&gt;이벤트 중복 소비&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 건 실제 서비스에서 무조건 터진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Idempotency Key&lt;/li&gt;
&lt;li&gt;분산 락(또는 원자적 상태 전이)&lt;/li&gt;
&lt;li&gt;Circuit breaker / Retry / Bulkhead&lt;br /&gt;같은 것들을 처음부터 설계에 넣어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 이 시리즈에서 만들 것: KRW Stablecoin Payment Gateway &amp;amp; Settlement System (현실형 PoC)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 시리즈의 목표는 딱 이거다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;원화 스테이블코인을 결제 레일로 쓴다는 가정 하에,&lt;br /&gt;PG/정산/대사까지 포함한 백엔드 인프라를 &lt;b&gt;현실적인 PoC 수준&lt;/b&gt;으로 설계&amp;middot;구현한다.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5.1. 범위(이번 시리즈에서 하는 것)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결제 API
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;REST 기반 결제 요청 처리&lt;/li&gt;
&lt;li&gt;멱등성 보장, 중복 방지, 재시도 설계&lt;/li&gt;
&lt;li&gt;온체인 Tx 생성 + 컨펌 체크 + 이벤트 기반 상태 전이&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;정산(배치)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일/시간 단위 정산 배치&lt;/li&gt;
&lt;li&gt;온체인 처리(회수/소각) + 오프체인 처리(계좌 이체 &amp;ldquo;시뮬레이션&amp;rdquo;)를 묶는 Saga&lt;/li&gt;
&lt;li&gt;정산 상태 추적(성공/실패/보상/재처리)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;리컨실레이션 &amp;amp; 모니터링
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;온체인 이벤트 리스닝&lt;/li&gt;
&lt;li&gt;온체인 &amp;harr; 오프체인 &amp;harr; 내부 장부 불일치 탐지&lt;/li&gt;
&lt;li&gt;감사 로그, 알림, 대시보드&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5.2. 범위(이번엔 안 하는 것)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;KYC/AML/Travel Rule 같은 컴플라이언스 구현
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실제 프로덕션에선 중요하지만, 이번 프로젝트는 &lt;b&gt;결제&amp;middot;정산 인프라의 복잡도&lt;/b&gt;에 집중한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정책이 어떻게 결론나든,&lt;br /&gt;&amp;lsquo;토큰이 결제 UX에 들어오는 순간 PG가 마주치는 문제&amp;rsquo;는 꽤 정직하게 정해져 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최종성(확정성)&lt;/li&gt;
&lt;li&gt;분산 트랜잭션&lt;/li&gt;
&lt;li&gt;정합성(대사)&lt;/li&gt;
&lt;li&gt;멱등성/동시성&lt;/li&gt;
&lt;li&gt;장애 전파 차단&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 시리즈는 그걸 &amp;ldquo;말&amp;rdquo;이 아니라&lt;br /&gt;&lt;b&gt;아키텍처와 코드&lt;/b&gt;로 한번 끝까지 만들어보는 기록이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 글(2편)에서는&lt;br /&gt;이 전제를 바탕으로 시스템&amp;nbsp;&lt;b&gt;아키텍처 다이어그램 + 핵심 유즈케이스 시퀀스&lt;/b&gt;부터 잡아보겠다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고 링크(대표 근거만)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한국은행 CBDC 연구/실험 안내: &lt;a href=&quot;https://www.bok.or.kr/eng/bbs/B0000364/list.do?menuNo=400411&quot;&gt;https://www.bok.or.kr/eng/bbs/B0000364/list.do?menuNo=400411&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;BIS Papers 123 (한국은행 CBDC 연구 관점 정리): &lt;a href=&quot;https://www.bis.org/publ/bppdf/bispap123_m.pdf&quot;&gt;https://www.bis.org/publ/bppdf/bispap123_m.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;BIS (Unified Ledger 관련 보고서): &lt;a href=&quot;https://www.bis.org/publ/othp77.pdf&quot;&gt;https://www.bis.org/publ/othp77.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;한국은행 &amp;lsquo;한강&amp;rsquo; 실거래 실험 보도(10만명): &lt;a href=&quot;https://www.koreatimes.co.kr/economy/cryptocurrency/20250318/bok-to-recruit-100000-participants-for-digital-currency-experiment&quot;&gt;https://www.koreatimes.co.kr/economy/cryptocurrency/20250318/bok-to-recruit-100000-participants-for-digital-currency-experiment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Project &amp;lsquo;한강&amp;rsquo; 관련 보도(개요): &lt;a href=&quot;https://www.koreaherald.com/article/10448743&quot;&gt;https://www.koreaherald.com/article/10448743&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2단계 논의 지연/일시정지 보도: &lt;a href=&quot;https://www.ledgerinsights.com/korean-cbdc-tokenized-deposit-project-paused-as-banks-favor-stablecoins/&quot;&gt;https://www.ledgerinsights.com/korean-cbdc-tokenized-deposit-project-paused-as-banks-favor-stablecoins/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;가상자산 이용자 보호법 시행(금융위): &lt;a href=&quot;https://www.fsc.go.kr/eng/pr010101/82683&quot;&gt;https://www.fsc.go.kr/eng/pr010101/82683&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;원화 스테이블코인(은행 과반 컨소시엄 등) 논의 보도: &lt;a href=&quot;https://www.koreatimes.co.kr/business/tech/20260204/stablecoin-bill-to-require-banks-to-hold-51-stake-in-issuers&quot;&gt;https://www.koreatimes.co.kr/business/tech/20260204/stablecoin-bill-to-require-banks-to-hold-51-stake-in-issuers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프로젝트/스테이블코인 결제</category>
      <category>스테이블코인</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/39</guid>
      <comments>https://junmonologue.tistory.com/39#entry39comment</comments>
      <pubDate>Mon, 9 Feb 2026 17:35:41 +0900</pubDate>
    </item>
    <item>
      <title>Spring Security 오픈소스 기여 후기</title>
      <link>https://junmonologue.tistory.com/38</link>
      <description>&lt;p&gt;Spring Security에 첫 기여를 진행했습니다.&lt;/p&gt;
&lt;p&gt;이슈 &lt;strong&gt;#18451 &amp;quot;Remove javadoc warnings for spring-security-data&amp;quot;&lt;/strong&gt;를 해결했습니다.&lt;br&gt;이번 PR은 &lt;code&gt;spring-security-data&lt;/code&gt; 모듈의 Javadoc 빌드 경고를 제거하고, 경고 발생 시 빌드를 실패하도록 설정하는 작업을 포함합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;이슈 이해하기&lt;/h2&gt;
&lt;h3&gt;이슈 #18451: Remove javadoc warnings for spring-security-data&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;목적:&lt;/strong&gt; &lt;code&gt;spring-security-data&lt;/code&gt; 모듈의 Javadoc 빌드 경고 제거  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;상위 이슈:&lt;/strong&gt; #18443 (전체 모듈의 Javadoc 경고 제거)  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;요구사항&lt;/strong&gt;&lt;ol&gt;
&lt;li&gt;Javadoc 경고 제거  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;javadoc-warnings-error&lt;/code&gt; 플러그인 적용  &lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;문제 분석&lt;/h2&gt;
&lt;h3&gt;Javadoc이란?&lt;/h3&gt;
&lt;p&gt;Java 주석(&lt;code&gt;/** ... */&lt;/code&gt;)으로부터 HTML API 문서를 자동 생성하는 도구입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;/**
 * 사용자에게 인사하는 메서드
 * @param name 사용자 이름
 * @return 인사 메시지
 */
public String greet(String name) { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;발견한 문제&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;SecurityEvaluationContextExtension.java&lt;/code&gt; 내 메서드에 &lt;code&gt;@param&lt;/code&gt; 태그가 누락되어 경고가 발생했습니다.&lt;/p&gt;
&lt;h4&gt;수정 전&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;/**
 * Sets the {@link SecurityContextHolderStrategy} to use.
 * @since 5.8
 */
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;해결 과정&lt;/h2&gt;
&lt;h3&gt;1. 코드 분석&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;spring-security-data&lt;/code&gt; 모듈 내 파일 조사:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SecurityEvaluationContextExtension.java&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AuthorizeReturnObjectDataHintsRegistrar.java&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;package-info.java&lt;/code&gt; 등&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 누락된 &lt;code&gt;@param&lt;/code&gt; 태그 추가&lt;/h3&gt;
&lt;h4&gt;수정 후&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;/**
 * Sets the {@link SecuritySecurityContextHolderStrategy} to use. The default action is to use
 * the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
 * @param securityContextHolderStrategy the {@link SecurityContextHolderStrategy} to use. Cannot be null.
 * @since 5.8
 */
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. &lt;code&gt;javadoc-warnings-error&lt;/code&gt; 플러그인 적용&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;spring-security-data.gradle&lt;/code&gt;에 플러그인 추가:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-groovy&quot;&gt;plugins {
    id &amp;#39;security-nullability&amp;#39;
    id &amp;#39;javadoc-warnings-error&amp;#39;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 로컬 빌드 검증&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./gradlew --no-build-cache clean :spring-security-data:javadoc&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;결과:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BUILD SUCCESSFUL&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;원리 설명&lt;/h2&gt;
&lt;h3&gt;Javadoc 경고 종류&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@param&lt;/code&gt;, &lt;code&gt;@return&lt;/code&gt;, &lt;code&gt;@throws&lt;/code&gt; 누락&lt;/li&gt;
&lt;li&gt;깨진 &lt;code&gt;{@link}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;문법 오류 태그&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;javadoc-warnings-error&lt;/code&gt; 플러그인 동작&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-groovy&quot;&gt;options.addBooleanOption(&amp;#39;Werror&amp;#39;, true)
options.addStringOption(&amp;#39;Xdoclint:all,-missing&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;커밋 메시지&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Remove javadoc warnings for spring-security-data

- Add javadoc-warnings-error plugin to spring-security-data.gradle
- Add missing @param tag in setSecurityContextHolderStrategy method

Closes gh-18451

Signed-off-by: Junmo &amp;lt;hongjm1022@gmail.com&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;최종 결과&lt;/h2&gt;
&lt;h3&gt;수정된 파일&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;spring-security-data.gradle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SecurityEvaluationContextExtension.java&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;검증 결과&lt;/h3&gt;
&lt;p&gt;Javadoc 빌드 경고 없음 → &lt;strong&gt;빌드 성공&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;PR merge&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PR 생성 완료 (&lt;code&gt;#18532&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;메인테이너 리뷰후 merge&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;</description>
      <category>개발</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/38</guid>
      <comments>https://junmonologue.tistory.com/38#entry38comment</comments>
      <pubDate>Thu, 22 Jan 2026 09:18:48 +0900</pubDate>
    </item>
    <item>
      <title>AWS 크레딧 1000불 받는 방법 (승인 실패 후 재검토 받는법)</title>
      <link>https://junmonologue.tistory.com/37</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt; “서버비 0원으로  프로젝트 운영하기”&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;서론&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;사이드 프로젝트나 개인 서비스 운영 시 겪는 문제들이 많습니다. &lt;/li&gt;
&lt;li&gt;최근 AWS가 프리티어 운영을 종료하고 크레딧으로 변경되며 AWS를 이용하는 분들의 비용에 대한 부담이 커지고 있다고 생각합니다. &lt;/li&gt;
&lt;li&gt;최근 프로젝트를 앱스토어에 배포 후 서버를 운영하며 비용을 어떻게 처리할지에 대한 고민을 하는 과정에서 좋은 방법을 찾게 되었습니다. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 글에서는 AWS Activate Startups Credit을 사용해서 서버 운용 비용에 대한 도움을 받을 수 있는 방법을 소개합니다. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@hsh111366/5%EB%B6%84-%EB%A7%8C%EC%97%90-AWS-140%EB%A7%8C%EC%9B%90-%EB%B2%8C%EA%B8%B0&quot;&gt;Sangho&amp;#39;s Interaction&lt;/a&gt; 너무 많은 도움을 받은 블로그입니다!&lt;br&gt;다들 꼭 한 번 읽어보시고 제 글 읽어주시면 감사하겠습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;  AWS Activate Startups Credit&lt;/h2&gt;
&lt;p&gt;AWS Activate Startups Credit은 AWS가 스타트업의 성장을 지원하기 위해 제공하는 크레딧 프로그램입니다.&lt;br&gt; 초기 스타트업부터 성장 단계의 스타트업까지 단계별로 다양한 혜택을 제공하여, 스타트업이 클라우드 인프라 비용 부담 없이 혁신적인 아이디어를 실현할 수 있도록 돕습니다.&lt;/p&gt;
&lt;p&gt;  &lt;strong&gt;공식 사이트&lt;/strong&gt;: &lt;a href=&quot;https://aws.amazon.com/startups?lang=ko&quot;&gt;AWS Startups&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;주요 혜택&lt;/h3&gt;
&lt;p&gt;AWS Activate 크레딧을 통해 스타트업은 다음과 같은 AWS 서비스를 활용할 수 있습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;클라우드 인프라&lt;/strong&gt;: EC2, S3, RDS, Lambda 등 핵심 인프라 서비스&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 서비스&lt;/strong&gt;: 데이터베이스, 분석 도구, 데이터 레이크 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI/ML 서비스&lt;/strong&gt;: Amazon Bedrock, SageMaker 등 선도적인 AI 및 머신러닝 모델&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;기술 지원&lt;/strong&gt;: AWS 기술 전문가와의 직접 상담 및 멘토링&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;크레딧 패키지 종류&lt;/h3&gt;
&lt;p&gt;AWS Activate는 스타트업의 성장 단계에 따라 두 가지 패키지를 제공합니다:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;종류&lt;/th&gt;
&lt;th&gt;크레딧 금액&lt;/th&gt;
&lt;th&gt;주요 특징&lt;/th&gt;
&lt;th&gt;대상&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Founder&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,000 USD&lt;/strong&gt; + Support 크레딧&lt;/td&gt;
&lt;td&gt;- AWS Activate Founders 프로그램 미신청 이력 필요&lt;br&gt;- 자금 지원 받지 않은 초기 스타트업&lt;br&gt;- 10년 이내 설립된 스타트업&lt;br&gt;- 웹사이트 또는 공개 프로필 보유&lt;/td&gt;
&lt;td&gt;개인/초기 스타트업, 사이드 프로젝트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Portfolio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;최대 100,000 USD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;- VC(벤처캐피탈) 또는 엑셀러레이터 추천 필요&lt;br&gt;- 투자받은 스타트업&lt;br&gt;- 성장 단계의 스타트업&lt;/td&gt;
&lt;td&gt;투자받은 스타트업, 액셀러레이터 프로그램 참여 기업&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;Founder vs Portfolio 차이점&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Founder 패키지&lt;/strong&gt;는 누구나 신청 가능한 개인/초기 스타트업용 프로그램으로, 비교적 간단한 자격 요건을 충족하면 1,000 USD 크레딧을 받을 수 있습니다. 이는 사이드 프로젝트나 초기 스타트업에게 적합하며, 별도의 투자나 추천 없이도 신청 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Portfolio 패키지&lt;/strong&gt;는 VC나 엑셀러레이터의 추천을 받은 스타트업을 대상으로 하며, 최대 10만 USD까지 더 많은 크레딧을 제공합니다. 이는 성장 단계의 스타트업이나 이미 투자를 받은 기업에게 적합합니다.&lt;/p&gt;
&lt;h3&gt;유효기간 및 사용 범위&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;크레딧 유효기간&lt;/strong&gt;: 일반적으로 2년 (승인 시점부터)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;사용 가능 서비스&lt;/strong&gt;: 대부분의 AWS 서비스 (프리티어 제외)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;사용 제한&lt;/strong&gt;: 크레딧은 AWS 서비스 비용에만 사용 가능하며, 현금으로 환불되거나 이전되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 글에서는 제가 신청하고 승인받은 &lt;strong&gt;AWS Activate Founder 과정&lt;/strong&gt;에 대해 알아보겠습니다.   &lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;  신청 과정&lt;/h2&gt;
&lt;p&gt;0️⃣ &lt;strong&gt;AWS Builder 계정 생성&lt;/strong&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/startups/credits&quot;&gt;AWS Activate Startups&lt;/a&gt;&lt;br&gt;AWS 계정 말고 Builder 계정 생성이 필요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;1️⃣ &lt;strong&gt;크레딧 신청 버튼 클릭&lt;/strong&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Builder 계정 로그인 후 “지금 신청” 버튼 클릭&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2️⃣ &lt;strong&gt;패키지 선택&lt;/strong&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Founder / Portfolio 중 Founder 선택&lt;br&gt;저희는 Founder로 신청합니다! &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3️⃣ &lt;strong&gt;프로필 작성&lt;/strong&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;개인 프로필 (직책, LinkedIn 링크등 필요한 요소들을 넣어줍니다)&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zG1wv/dJMcacIbiXt/kOdGOUoxRqUx5e74Zizr2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zG1wv/dJMcacIbiXt/kOdGOUoxRqUx5e74Zizr2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zG1wv/dJMcacIbiXt/kOdGOUoxRqUx5e74Zizr2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzG1wv%2FdJMcacIbiXt%2FkOdGOUoxRqUx5e74Zizr2k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;스타트업 프로필 (앱/웹 링크, 인스타그램 등)&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biLgNy/dJMcadNRcxy/Otmi71ZkxUQkpyqtLKmahK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biLgNy/dJMcadNRcxy/Otmi71ZkxUQkpyqtLKmahK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biLgNy/dJMcadNRcxy/Otmi71ZkxUQkpyqtLKmahK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiLgNy%2FdJMcadNRcxy%2FOtmi71ZkxUQkpyqtLKmahK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;웹페이지가 존재한다면 넣어주고 앱인 경우엔 웹페이지 생성을 하는 것을 추천드립니다!       &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;저는 앱서비스라 가벼운 웹페이지를 생성하여 vercel로 배포 후 링크를 첨부했습니다.&lt;br&gt;&lt;a href=&quot;https://jikgwaneottae-web.vercel.app/&quot;&gt;직관어때&lt;/a&gt;  &amp;lt;- 저희 서비스 웹페이지 입니다. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;공개 프로필 url에는 인스타그램 계정을 생성후 첨부했습니다.&lt;br&gt;&lt;a href=&quot;https://www.instagram.com/jikgwaneottae/&quot;&gt;직관어때 인스타&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4️⃣ &lt;strong&gt;제품 및 자금 조달 설명&lt;/strong&gt;  &lt;/p&gt;
&lt;p&gt;   &lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xK1G0/dJMcaaXTQ2A/D1uzLVVLBKtDuby82SZo4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xK1G0/dJMcaaXTQ2A/D1uzLVVLBKtDuby82SZo4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xK1G0/dJMcaaXTQ2A/D1uzLVVLBKtDuby82SZo4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxK1G0%2FdJMcaaXTQ2A%2FD1uzLVVLBKtDuby82SZo4k%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;제품 설명에서는 AWS에 관심이 많다는 어필을 많이하려고 노력했습니다.&lt;/li&gt;
&lt;li&gt;그리고 250글자의 서비스 소개글이 있는데 구체적인 계획, 실사용자등 저희 서비스의 현재 상황과 앞으로의 플랜을 수치로 자세하게 어필하며 소개하려고 했습니다.&lt;/li&gt;
&lt;li&gt;자금 조달 여부는 솔직하게 체크하시면 됩니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;5️⃣ &lt;strong&gt;AWS 계정 연결&lt;/strong&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;실제 AWS 계정과 연동&lt;br&gt;Builder가 아닌 실제 서버를 구축하고 운영하고 있는 AWS 계정과 연동이 필요합니다.&lt;/li&gt;
&lt;li&gt;“연결 완료” 표시 확인 후 다음 단계 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;6️⃣ &lt;strong&gt;검토 및 제출&lt;/strong&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 항목 점검 후 제출&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;  승인 과정&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;신청 후 약 3~5일내로 결과 메일이 왔습니다. &lt;/li&gt;
&lt;li&gt;승인 시 이메일로 통보&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmq0sX/dJMcai9s7pB/WjKIS4deeBWAqGk8mrCB00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmq0sX/dJMcai9s7pB/WjKIS4deeBWAqGk8mrCB00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmq0sX/dJMcai9s7pB/WjKIS4deeBWAqGk8mrCB00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbmq0sX%2FdJMcai9s7pB%2FWjKIS4deeBWAqGk8mrCB00%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;승인 메일 도착 후 AWS 콘솔에서 크레딧 확인 가능&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nwlsH/dJMcajN4Dxt/muY5SaC5KvdF2lkA0geDNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nwlsH/dJMcajN4Dxt/muY5SaC5KvdF2lkA0geDNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nwlsH/dJMcajN4Dxt/muY5SaC5KvdF2lkA0geDNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnwlsH%2FdJMcajN4Dxt%2FmuY5SaC5KvdF2lkA0geDNK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;⚠️ 승인 실패 시 대처법&lt;/h2&gt;
&lt;p&gt;사실 신청에 관한 자세한 내용은 제가 위에서 도움을 많이 받았던 블로그에 더욱더 자세하게 나와있습니다.&lt;br&gt;이 글에서는 &lt;strong&gt;저와같이 거절을 당했을 경우&lt;/strong&gt; 어떻게 해결해야할지에 대해 자세하게 다뤄보도록 하겠습니다. &lt;/p&gt;
&lt;p&gt;저도 처음 신청후 거절 이메일을 받았습니다&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJ3y1e/dJMcafLFMnp/81OzUnHrXDsaelDgKEykb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJ3y1e/dJMcafLFMnp/81OzUnHrXDsaelDgKEykb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJ3y1e/dJMcafLFMnp/81OzUnHrXDsaelDgKEykb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJ3y1e%2FdJMcafLFMnp%2F81OzUnHrXDsaelDgKEykb0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Valid billing and AWS account details;&lt;/li&gt;
&lt;li&gt;Consistent business information;&lt;/li&gt;
&lt;li&gt;connection to accounts linked to misuse.&lt;br&gt;이러한 내용이 적혀있었는데 구체적인 내용을 물어보고 싶었으나 응답을 할 수 있는 이메일을 찾을 수 없었습니다.   &lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;해결 방법&lt;/h3&gt;
&lt;p&gt;거절 이메일에는 응답할 수 있는 이메일 주소가 없어서 직접 문의하기가 어려웠습니다. 그래서 AWS Support 센터를 통해 문의를 시도했습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AWS Support 센터 접속&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2Txkk/dJMcaiuRzgY/jOT0r81xcAWvB8AK2PgGBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2Txkk/dJMcaiuRzgY/jOT0r81xcAWvB8AK2PgGBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2Txkk/dJMcaiuRzgY/jOT0r81xcAWvB8AK2PgGBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2Txkk%2FdJMcaiuRzgY%2FjOT0r81xcAWvB8AK2PgGBk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;AWS 리소스 - AWS 문의 페이지에 접속하면 직접 문의하는 곳이 아닌 AI 어시스턴스가 답변을 해주는 방식으로 구성되어 있습니다.&lt;br&gt;이 AI 어시스턴스에게 거절된 이메일의 내용을 물어봤지만 자세한 설명을 받을 수 없었습니다.&lt;/p&gt;
&lt;p&gt;그래서 직접적으로 연락할 수 있는 방법을 알려달라고 요청했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI6Un3/dJMcahJurJr/IakGTvXeqKKqeh6Bu2TyaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI6Un3/dJMcahJurJr/IakGTvXeqKKqeh6Bu2TyaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI6Un3/dJMcahJurJr/IakGTvXeqKKqeh6Bu2TyaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI6Un3%2FdJMcahJurJr%2FIakGTvXeqKKqeh6Bu2TyaK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;직접 문의하기&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;연결된 링크를 통해 접속하면 직접 문의를 넣을 수 있는 화면이 나오게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkk64Z/dJMcahip2t5/43K2klvw6OMBMaaetq3bJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkk64Z/dJMcahip2t5/43K2klvw6OMBMaaetq3bJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkk64Z/dJMcahip2t5/43K2klvw6OMBMaaetq3bJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdkk64Z%2FdJMcahip2t5%2F43K2klvw6OMBMaaetq3bJk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;각 영역에 필요한 내용들을 입력한 후 제출했습니다.  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Activate 프로그램 신청을 했으나 거절 이메일을 받았다는 점&lt;/li&gt;
&lt;li&gt;거절 사유에 대한 구체적인 설명 요청&lt;/li&gt;
&lt;li&gt;승인을 위해 추가로 필요한 정보가 무엇인지 문의&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;이메일 소통 및 승인&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;이후 연결된 AWS 계정으로 이메일이 도착했고, AWS 팀과 계속 이메일을 주고받으며 필요한 정보를 추가로 제공했습니다.&lt;br&gt;결국 최종적으로 승인을 받을 수 있었습니다.&lt;/p&gt;
&lt;p&gt;  각자의 상황에 따라 필요한 내용이 다를 수 있으니, 자신의 상황에 맞춰서 이메일을 작성하시면 될 것 같습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;  마무리&lt;/h2&gt;
&lt;p&gt;결국 최종적으로 AWS 크레딧을 받게 되었습니다!&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cePwV0/dJMcahip2uu/qeJwiWxuObG820DhwMeh00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cePwV0/dJMcahip2uu/qeJwiWxuObG820DhwMeh00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cePwV0/dJMcahip2uu/qeJwiWxuObG820DhwMeh00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcePwV0%2FdJMcahip2uu%2FqeJwiWxuObG820DhwMeh00%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;백엔드 개발자로서 서버비를 아끼고 최적화하는 것은 아주 중요한 역량이라고 생각합니다.&lt;br&gt;인프라 구축, 개발, 코드 최적화도 물론 중요하지만, 이러한 방식으로 서버비 문제를 해결하는 것도 좋은 문제 해결 방법이라고 생각합니다.&lt;/p&gt;
&lt;p&gt;이제 충분한 AWS 크레딧을 받았으니 서버 운영 최적화를 마음껏 해볼 수 있어서 기쁘네요.&lt;br&gt;도전적인 사이드 프로젝트를 지속적으로 운영하려면 이런 제도들을 적극 활용하는 것이 중요하다고 생각합니다.  &lt;/p&gt;
&lt;hr&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;  &lt;strong&gt;막간 홍보&lt;/strong&gt;&lt;br&gt;제가 개발한 야구 어플리케이션 &lt;strong&gt;직관어때&lt;/strong&gt;입니다!&lt;br&gt;관심 있으시면 다운로드 받아보세요! ⚾&lt;br&gt;&lt;a href=&quot;https://apps.apple.com/kr/app/%EC%A7%81%EA%B4%80%EC%96%B4%EB%95%8C/id6752529851&quot;&gt;  App Store에서 다운로드&lt;/a&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr&gt;
&lt;h2&gt;  참고 링크&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/startups/credits&quot;&gt;AWS Activate Startups 공식 페이지&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발</category>
      <category>AWS #크레딧 #credit #EC2 #사이드프로젝트 #백엔드 # AWSActivate #스타트업</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/37</guid>
      <comments>https://junmonologue.tistory.com/37#entry37comment</comments>
      <pubDate>Wed, 5 Nov 2025 10:50:34 +0900</pubDate>
    </item>
    <item>
      <title>RESTful API 완벽 가이드</title>
      <link>https://junmonologue.tistory.com/36</link>
      <description>&lt;h1&gt;RESTful API 완벽 가이드 — 백엔드 개발자가 꼭 알아야 할 핵심 정리&lt;/h1&gt;
&lt;p&gt;이 글은 RESTful API의 개념부터 설계 원칙, 실제 예시, 그리고 자주 하는 실수까지 모두 정리한  공부글입니다.&lt;/p&gt;
&lt;h2&gt;1. REST란 무엇인가?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;REST (Representational State Transfer)&lt;/strong&gt; 는 웹 기반 시스템에서 리소스를 효율적으로 관리하고 전달하기 위한 아키텍처 스타일입니다.&lt;/p&gt;
&lt;p&gt;즉, &amp;quot;자원을 URI로 식별하고, 그 자원에 대한 상태를 HTTP 메서드로 표현하며, 서버와 클라이언트가 느슨하게 연결된 구조로 통신하는 방식&amp;quot;입니다.&lt;/p&gt;
&lt;h2&gt;2. REST의 핵심 구성 요소&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구성 요소&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;th&gt;예시&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resource (자원)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;서버가 제공하는 데이터나 기능&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users&lt;/code&gt;, &lt;code&gt;/posts/1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;URI (자원의 식별자)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;각 자원을 식별하는 고유 주소&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://api.example.com/users/1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTTP Method (행위)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;자원에 대해 수행할 동작&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Representation (표현)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;자원의 실제 데이터 형태&lt;/td&gt;
&lt;td&gt;JSON, XML, HTML 등&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2&gt;3. REST의 6가지 제약 조건 (RESTful의 기준)&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;제약 조건&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1. Client-Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;클라이언트와 서버의 역할을 명확히 분리해야 함. (UI ↔ 데이터)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2. Stateless (무상태성)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;각 요청은 독립적이어야 하며, 서버는 클라이언트 상태를 저장하지 않음.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3. Cacheable (캐시 가능)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;서버 응답은 캐싱이 가능해야 함. 성능 향상과 네트워크 부하 감소 목적.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4. Uniform Interface&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;일관된 인터페이스로 설계되어야 함. (URI 규칙, HTTP method 일관성 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;5. Layered System&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;서버는 여러 계층으로 나눠질 수 있으며, 클라이언트는 그 구조를 몰라도 됨.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;6. Code on Demand (Optional)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;서버가 클라이언트에 코드를 전송해 실행시킬 수 있음 (자바스크립트 등).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2&gt;4. RESTful API란?&lt;/h2&gt;
&lt;p&gt;REST의 원칙을 준수하며 설계된 API를 &lt;strong&gt;RESTful API&lt;/strong&gt;라고 합니다.&lt;/p&gt;
&lt;p&gt;즉,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;자원(Resource)을 명확하게 URI로 표현하고,&lt;/li&gt;
&lt;li&gt;행위(Action)는 HTTP 메서드로 구분하며,&lt;/li&gt;
&lt;li&gt;Stateless한 통신을 유지하는 API입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. HTTP 메서드와 CRUD 매핑&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;HTTP Method&lt;/th&gt;
&lt;th&gt;CRUD&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;th&gt;예시&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GET&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;자원 조회&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users&lt;/code&gt;, &lt;code&gt;/users/1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;POST&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Create&lt;/td&gt;
&lt;td&gt;새 자원 생성&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PUT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Update&lt;/td&gt;
&lt;td&gt;자원 전체 수정&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users/1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PATCH&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Update&lt;/td&gt;
&lt;td&gt;자원 일부 수정&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users/1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DELETE&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Delete&lt;/td&gt;
&lt;td&gt;자원 삭제&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users/1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&lt;strong&gt;PUT은 전체 교체, PATCH는 부분 수정에 사용합니다.&lt;/strong&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;6. RESTful URI 설계 원칙&lt;/h2&gt;
&lt;h3&gt;올바른 예시&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;리소스는 명사로 표현할 것&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/users/1/posts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/getUserPosts&lt;/code&gt; (잘못된 예시)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;소문자와 하이픈(-) 사용&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/user-comments&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/UserComments&lt;/code&gt; (잘못된 예시)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;계층 관계는 URI로 표현&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/users/1/orders/2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;파일 확장자 사용 금지&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/users&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/users.json&lt;/code&gt; (잘못된 예시)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;버전은 명시적으로 관리&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/api/v1/users&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;7. RESTful 응답 구조 예시&lt;/h2&gt;
&lt;h3&gt;성공 응답 (200 OK)&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &amp;quot;status&amp;quot;: 200,
  &amp;quot;message&amp;quot;: &amp;quot;User retrieved successfully&amp;quot;,
  &amp;quot;data&amp;quot;: {
    &amp;quot;id&amp;quot;: 1,
    &amp;quot;name&amp;quot;: &amp;quot;austin&amp;quot;,
    &amp;quot;email&amp;quot;: &amp;quot;austin@example.com&amp;quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;에러 응답 (404 Not Found)&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &amp;quot;status&amp;quot;: 404,
  &amp;quot;error&amp;quot;: &amp;quot;User not found&amp;quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&lt;strong&gt;일관된 응답 포맷을 유지하는 것이 매우 중요합니다.&lt;/strong&gt;&lt;br&gt;(예: status, message, data 구조)&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;8. RESTful API 예시 시나리오&lt;/h2&gt;
&lt;h3&gt;회원 관리 API&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;기능&lt;/th&gt;
&lt;th&gt;메서드&lt;/th&gt;
&lt;th&gt;URI&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;회원 목록 조회&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;모든 회원 조회&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;회원 상세 조회&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;특정 회원 조회&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;회원 등록&lt;/td&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;회원 추가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;회원 정보 수정&lt;/td&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;회원 정보 전체 수정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;회원 탈퇴&lt;/td&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;회원 삭제&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2&gt;9. RESTful 하지 않은 예시 (Anti-Pattern)&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;잘못된 예시&lt;/th&gt;
&lt;th&gt;올바른 예시&lt;/th&gt;
&lt;th&gt;이유&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/getUsers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;동작(verb)이 아닌 자원(noun)으로 표현해야 함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/createUser&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users&lt;/code&gt; (POST)&lt;/td&gt;
&lt;td&gt;HTTP 메서드로 행위를 표현해야 함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/updateUser?id=1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users/1&lt;/code&gt; (PUT)&lt;/td&gt;
&lt;td&gt;리소스 ID는 URI 경로로 표현&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/deleteUser/1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/users/1&lt;/code&gt; (DELETE)&lt;/td&gt;
&lt;td&gt;행위는 DELETE로 표현&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2&gt;10. RESTful API의 장점과 한계&lt;/h2&gt;
&lt;h3&gt;장점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;구조가 단순하고 직관적&lt;/li&gt;
&lt;li&gt;클라이언트-서버의 독립성&lt;/li&gt;
&lt;li&gt;확장성 및 유지보수 용이&lt;/li&gt;
&lt;li&gt;HTTP 표준 기반으로 폭넓은 호환성&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;한계&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;복잡한 트랜잭션 처리에는 부적합&lt;/li&gt;
&lt;li&gt;다수의 요청이 필요한 경우 비효율적&lt;/li&gt;
&lt;li&gt;실시간 통신에는 부적합 (→ WebSocket 권장)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;11. REST vs 다른 아키텍처&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;REST&lt;/th&gt;
&lt;th&gt;GraphQL&lt;/th&gt;
&lt;th&gt;gRPC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;통신 방식&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;td&gt;HTTP/2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;데이터 전송&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;JSON&lt;/td&gt;
&lt;td&gt;JSON&lt;/td&gt;
&lt;td&gt;Protocol Buffers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;요청 단위&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;여러 엔드포인트&lt;/td&gt;
&lt;td&gt;단일 엔드포인트&lt;/td&gt;
&lt;td&gt;서비스 메서드 기반&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;주요 장점&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;단순하고 표준화&lt;/td&gt;
&lt;td&gt;필요한 데이터만 요청 가능&lt;/td&gt;
&lt;td&gt;고성능, 이진 데이터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;사용 예시&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;웹/모바일 API&lt;/td&gt;
&lt;td&gt;프론트엔드 최적화&lt;/td&gt;
&lt;td&gt;마이크로서비스 간 통신&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2&gt;12. RESTful API 설계 시 자주 하는 실수&lt;/h2&gt;
&lt;h3&gt;1. HTTP 상태코드를 잘못 사용&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;200 OK만 사용하는 것은 좋지 않음.&lt;/li&gt;
&lt;li&gt;201 Created, 400 Bad Request, 404 Not Found, 500 Internal Server Error 등 명확히 구분 필요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. URI에 동사 포함&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /getUserList&lt;/code&gt; → ❌&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 에러 메시지 비일관성&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트가 일관된 방식으로 에러를 처리할 수 없게 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. Stateless 위반&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;세션 기반 인증을 사용하면 REST 원칙 위반 (→ JWT 권장)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;13. RESTful API 설계 체크리스트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; URI는 명사 기반으로 작성했는가?&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; HTTP 메서드를 적절히 사용했는가?&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 상태 코드를 올바르게 반환하는가?&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; JSON 응답 포맷이 일관적인가?&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 버전 관리(/v1, /v2)를 하고 있는가?&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 예외 및 에러 처리가 명확한가?&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 캐시, 보안(HTTPS), 인증(JWT)을 고려했는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;14. 마무리 — &amp;quot;RESTful하게&amp;quot; 설계한다는 것&lt;/h2&gt;
&lt;p&gt;RESTful API는 단순히 GET/POST를 사용하는 것이 아닙니다.&lt;br&gt;자원의 구조, 행위의 표현, 일관성, 확장성을 고려한 하나의 규칙입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&lt;strong&gt;결국 좋은 API는 &amp;quot;개발자가 직관적으로 이해할 수 있는 API&amp;quot;입니다.&lt;/strong&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;</description>
      <category>개발</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/36</guid>
      <comments>https://junmonologue.tistory.com/36#entry36comment</comments>
      <pubDate>Thu, 16 Oct 2025 14:36:44 +0900</pubDate>
    </item>
    <item>
      <title>야구어플 개발 #2  JPA 엔티티에 @Setter, @AllArgsConstructor, @Builder를 쓰면 안 되는 이유</title>
      <link>https://junmonologue.tistory.com/35</link>
      <description>&lt;h1&gt;[야구앱 개발기 #2] JPA 엔티티에 @Setter, @AllArgsConstructor, @Builder를 쓰면 안 되는 이유&lt;/h1&gt;
&lt;h2&gt;들어가며&lt;/h2&gt;
&lt;p&gt;야구앱 개발 중 &lt;code&gt;@Builder&lt;/code&gt;를 엔티티에 사용하다가 NPE(NullPointerException)를 겪었습니다.&lt;br&gt;이 문제를 해결하기 위해 어노테이션을 찾아보면서 &lt;code&gt;@Setter&lt;/code&gt;, &lt;code&gt;@AllArgsConstructor&lt;/code&gt;, &lt;code&gt;@Builder&lt;/code&gt;를 엔티티에 사용하면 안 되는 이유를 깊이 있게 알아보게 되었습니다.&lt;/p&gt;
&lt;p&gt;이 글에서는 각 어노테이션의 문제점과 대안을 체계적으로 설명해보겠습니다.&lt;/p&gt;
&lt;h2&gt;어노테이션 한눈에 정리&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;@Setter&lt;/strong&gt;: 모든 필드에 세터 메서드를 생성. 외부에서 엔티티 상태를 임의로 변경할 수 있어 도메인 규칙을 우회하기 쉬움.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;@AllArgsConstructor&lt;/strong&gt;: 모든 필드를 받는 생성자를 생성. JPA의 프록시/리플렉션, 기본 생성자 요구사항과 충돌하거나, 유효하지 않은 상태의 객체를 쉽게 만들 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;@Builder&lt;/strong&gt;: 빌더 패턴 생성. 가독성은 좋지만, 필드 초기화를 무시하거나(특히 컬렉션), 도메인 검증을 건너뛰는 등 엔티티에 부적합. DTO/Command에는 유용.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;핵심: 세 어노테이션 모두 “편의성”을 주지만, 엔티티의 일관성과 불변식을 깨뜨리거나 JPA 런타임 모델(프록시, 지연 로딩)과 충돌하기 쉽습니다. 엔티티에는 생성자/정적 팩토리, 도메인 메서드, 제한된(또는 비공개) 세터가 적합합니다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;@Builder의 문제점&lt;/h2&gt;
&lt;h3&gt;1. 필드 초기화 무시 문제&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Post {
    private String title;
    private String content;
    private List&amp;lt;Comment&amp;gt; comments = new ArrayList&amp;lt;&amp;gt;(); // 여기서 초기화

    public void addComment(Comment comment) {
        this.comments.add(comment); // NPE 발생 가능
    }
}

// 사용할 때
Post post = Post.builder()
    .title(&amp;quot;제목&amp;quot;)
    .content(&amp;quot;내용&amp;quot;)
    .build();
post.addComment(new Comment(&amp;quot;hi&amp;quot;)); // NPE!&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;빌더는 내부적으로 “생성자 + 빌더 내부 필드”로 값을 주입합니다. 필드에서 한 기본 초기화가 무시되어 컬렉션이 &lt;code&gt;null&lt;/code&gt;이 될 수 있습니다. (&lt;code&gt;@Builder.Default&lt;/code&gt;는 보조 수단이지만, &lt;code&gt;new&lt;/code&gt;로 만들면 여전히 null 이슈가 발생할 수 있습니다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 도메인 불변성(invariant) 위반&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Order.builder()
    .orderNumber(&amp;quot;ORD-1&amp;quot;)
    .totalAmount(BigDecimal.valueOf(-100)) // 음수
    .status(OrderStatus.PENDING)
    .build(); // 검증 없이 생성됨&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;엔티티 생성 시 반드시 지켜야 하는 제약을 빌더가 우회합니다. 객체가 유효하지 않은 상태로 생성되면 이후 모든 로직이 위험해집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. JPA와의 요구사항 충돌(기본 생성자/프록시)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JPA는 프록시/리플렉션을 사용하며 “기본 생성자(가시성: public/protected)”를 필요로 합니다. 빌더 조합(+ &lt;code&gt;@NoArgsConstructor&lt;/code&gt;/&lt;code&gt;@AllArgsConstructor&lt;/code&gt;)을 잘못 쓰면 런타임 예외가 날 수 있습니다.   &lt;/li&gt;
&lt;li&gt;또한 빌더가 만드는 강한결합 생성자는 잘못된 매개변수로 유효하지 않은 객체를 만들기 쉽습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. equals/hashCode, toString과 결합 시 추가 문제&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;@Data나 @EqualsAndHashCode(기본)와 함께 쓰면 “모든 필드 비교”가 적용되어&lt;ul&gt;
&lt;li&gt;지연 로딩 필드 접근으로 예상치 못한 쿼리/&lt;code&gt;LazyInitializationException&lt;/code&gt; 발생&lt;/li&gt;
&lt;li&gt;양방향 연관에서 &lt;code&gt;toString()&lt;/code&gt; 순환 호출로 &lt;code&gt;StackOverflowError&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Set에 넣은 뒤 영속화되어 id가 바뀌면 &lt;code&gt;hashCode&lt;/code&gt;가 변해 조회 실패&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;대안&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;엔티티에는 빌더를 쓰지 말고 정적 팩토리/생성자 + 내부 검증 + 컬렉션 필드 즉시 초기화(final)를 사용합니다.&lt;/li&gt;
&lt;li&gt;빌더는 &lt;strong&gt;DTO/Command/Query 모델&lt;/strong&gt;에 쓰고, Jackson과 함께라면 &lt;code&gt;@Jacksonized&lt;/code&gt;를 함께 사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Builder
@lombok.extern.jackson.Jacksonized
public class CreatePostCommand {
    private String title;
    private String content;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;@AllArgsConstructor의 문제점&lt;/h2&gt;
&lt;h3&gt;1. JPA 프록시/리플렉션, 기본 생성자 요구사항과 불협화음&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Entity
@AllArgsConstructor // 모든 필드 생성자 생성
@NoArgsConstructor  // 기본 생성자도 필요해서 추가
public class User { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;조합을 잘못하면 빌더/생성자 시그니처 충돌, 혹은 JPA가 요구하는 기본 생성자 가시성 불일치로 런타임 오류가 납니다. 또한 모든 필드를 받는 생성자는 유효하지 않은 상태(예: 음수 가격, null 연관)를 손쉽게 허용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 매개변수 폭발/순서 오류로 가독성·안전성 저하&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;필드가 많은 엔티티에서 모든 필드 생성자는 실수 유발(순서 기억 필요). 도메인 규칙이 생성자 외부로 밀려나며, 테스트/유지보수가 어려워집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;대안&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;엔티티: &lt;code&gt;protected&lt;/code&gt; 기본 생성자 + &lt;strong&gt;의미 있는 소수의 필드만 받는 private 생성자&lt;/strong&gt; + &lt;strong&gt;정적 팩토리&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;값 타입/DTO 등에서만 선택적으로 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Entity
public class Post {
    @Id @GeneratedValue
    private Long id;

    private String title;
    private String content;

    @OneToMany(mappedBy = &amp;quot;post&amp;quot;, cascade = ALL, orphanRemoval = true)
    private final List&amp;lt;PostImage&amp;gt; images = new ArrayList&amp;lt;&amp;gt;();

    protected Post(){} // JPA
    private Post(String title, String content){
        validate(title, content);
        this.title = title;
        this.content = content;
    }
    public static Post create(String title, String content){
        return new Post(title, content);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;@Setter의 문제점&lt;/h2&gt;
&lt;h3&gt;1. 도메인 규칙 우회(DDD 관점에서 캡슐화 파괴)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;어디서든 상태를 바꾸게 되어 aggregate 불변식이 깨집니다.  &lt;/li&gt;
&lt;li&gt;연관관계 세팅 순서 문제가 생기고 양방향 관계에선 한쪽만 세팅되는 버그가 잦습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 변경 가능성으로 인한 테스트/버그 비용 증가&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;엔티티가 언제 어디서든 바뀔 수 있으면 디버깅이 어려워지고, 스레드 간 전달 시 가시성/일관성 문제가 생깁니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;대안&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;세터는 private/protected로 두고 의도가 있는 &lt;strong&gt;도메인 메서드&lt;/strong&gt;를 노출합니다.&lt;/li&gt;
&lt;li&gt;컬렉션은 &lt;code&gt;final&lt;/code&gt;로 필드에서 즉시 초기화하고, 교체가 아닌 추가/제거 메서드로만 조작합니다. &lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public void changeTitle(String title){
    if(title == null || title.isBlank()) throw new IllegalArgumentException();
    this.title = title;
}
public void addImage(PostImage image){
    Objects.requireNonNull(image);
    image.setPost(this);
    this.images.add(image);
}
public List&amp;lt;PostImage&amp;gt; getImages(){
    return Collections.unmodifiableList(images);
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;엔티티엔 이렇게 사용해보자&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;생성&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;protected&lt;/code&gt; 기본 생성자 + &lt;strong&gt;정적 팩토리/전용 생성자&lt;/strong&gt;로 유효한 상태만 생성&lt;/li&gt;
&lt;li&gt;컬렉션은 필드에서 &lt;code&gt;final&lt;/code&gt;로 즉시 초기화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;변경&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;세터 금지(또는 비공개). 의도 드러나는 도메인 메서드 제공&lt;/li&gt;
&lt;li&gt;양방향 연관은 편의 메서드에서 양쪽 동기화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;동등성/문자열화&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;@Data 금지. equals/hashCode는 id 또는 자연키 기반, toString에서 연관 제외&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;어노테이션 사용 지침&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;엔티티: &lt;code&gt;@Setter&lt;/code&gt;(전역) X, &lt;code&gt;@AllArgsConstructor&lt;/code&gt; X, &lt;code&gt;@Builder&lt;/code&gt; X&lt;/li&gt;
&lt;li&gt;DTO/Command: &lt;code&gt;@Builder&lt;/code&gt; O, 필요 시 &lt;code&gt;@AllArgsConstructor&lt;/code&gt; O, &lt;code&gt;@Jacksonized&lt;/code&gt;(빌더 기반 역직렬화) O&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;읽기 전용 요구&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;엔티티 전체: &lt;code&gt;@org.hibernate.annotations.Immutable&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;컬럼 단위: &lt;code&gt;@Column(updatable = false)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;  언제 Lombok을 쓰면 좋은가?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DTO/Record/조회 전용 뷰&lt;/strong&gt;: &lt;code&gt;@Builder&lt;/code&gt;, &lt;code&gt;@AllArgsConstructor&lt;/code&gt;, &lt;code&gt;@Getter&lt;/code&gt; 적극 활용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;입출력 계층(Jackson)&lt;/strong&gt;: 빌더 사용 시 &lt;code&gt;@Jacksonized&lt;/code&gt;도 함께&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MapStruct/ModelMapper DTO 매핑&lt;/strong&gt;: Lombok과 잘 결합됨&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;참조 자료&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Lombok @Builder와 JPA 기본 생성자 이슈: &lt;a href=&quot;https://stackoverflow.com/questions/34241718/lombok-builder-and-jpa-default-constructor&quot;&gt;StackOverflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Lombok+JPA 모범사례/함정: &lt;a href=&quot;https://jpa-buddy.com/guides/best-practices-and-common-pitfalls-of-using-lombok-with-jpa/&quot;&gt;JPA Buddy Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;@Data와 엔티티의 equals/hashCode 문제: &lt;a href=&quot;https://medium.com/@jonas.friedli/lombok-data-and-jpa-entities-deep-dive-d955de9647e3&quot;&gt;Medium: Lombok @Data and JPA Entities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;@Builder.Default 컬렉션 null 이슈: &lt;a href=&quot;https://github.com/projectlombok/lombok/issues/1347&quot;&gt;Lombok Issue #1347&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hibernate 엔티티 요구사항: &lt;a href=&quot;https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/domain/entity.html&quot;&gt;Hibernate User Guide(Entities)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;불변 엔티티 매핑: &lt;a href=&quot;https://vladmihalcea.com/immutable-entity-jpa-hibernate/&quot;&gt;Vlad Mihalcea - Immutable Entity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Set/hashCode와 식별자 변경 문제: &lt;a href=&quot;https://www.innoq.com/en/blog/2023/12/rooting-out-issues-jpa-and-lombok/&quot;&gt;INNOQ Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프로젝트/야구어플</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/35</guid>
      <comments>https://junmonologue.tistory.com/35#entry35comment</comments>
      <pubDate>Fri, 8 Aug 2025 17:28:38 +0900</pubDate>
    </item>
    <item>
      <title>개발 기초 지식</title>
      <link>https://junmonologue.tistory.com/34</link>
      <description>&lt;h2&gt;목차&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#api&quot;&gt;API (Application Programming Interface)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%BB%B4%ED%93%A8%ED%8C%85&quot;&gt;클라우드 컴퓨팅&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%EC%84%9C%EB%B2%84-%EC%9A%B4%EC%98%81-%EB%B0%A9%EC%8B%9D&quot;&gt;서버 운영 방식&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%AA%A8%EB%8D%B8&quot;&gt;클라우드 서비스 모델&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EB%8F%84%EC%BB%A4&quot;&gt;컨테이너와 도커&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#cicd&quot;&gt;CI/CD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EA%B8%B0%EC%B4%88&quot;&gt;객체지향 프로그래밍 기초&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%95%B5%EC%8B%AC-%EA%B0%9C%EB%85%90&quot;&gt;프로그래밍 핵심 개념&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A4%EA%B3%84-%ED%8C%A8%ED%84%B4&quot;&gt;소프트웨어 설계 패턴&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;API&lt;/h2&gt;
&lt;p&gt;API(Application Programming Interface)는 소프트웨어 간의 통신을 위한 인터페이스입니다.&lt;/p&gt;
&lt;h3&gt;주요 특징&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컴퓨터 간 통신을 위한 중계 계층 역할&lt;/li&gt;
&lt;li&gt;HTTP/HTTPS 프로토콜과 GET, POST 등의 메서드를 통한 통신 방식 정의&lt;/li&gt;
&lt;li&gt;서비스 구현 세부사항을 숨기고 필요한 기능만 노출&lt;/li&gt;
&lt;li&gt;프론트엔드와 백엔드 간의 효율적인 통신 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;API의 장점&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;구현 세부사항 은닉&lt;/li&gt;
&lt;li&gt;명확한 인터페이스 제공&lt;/li&gt;
&lt;li&gt;유지보수 용이성&lt;/li&gt;
&lt;li&gt;재사용성 향상&lt;/li&gt;
&lt;li&gt;비즈니스 로직 변경 시 API 인터페이스 유지 가능&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;클라우드 컴퓨팅&lt;/h2&gt;
&lt;h3&gt;가상화 기술&lt;/h3&gt;
&lt;p&gt;가상화는 물리적 컴퓨팅 자원을 논리적으로 분할하여 사용하는 기술입니다.&lt;/p&gt;
&lt;h4&gt;주요 특징&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;하나의 물리적 서버에서 여러 가상 머신 운영 가능&lt;/li&gt;
&lt;li&gt;자원의 효율적인 분배와 활용&lt;/li&gt;
&lt;li&gt;유연한 확장성과 관리 용이성&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;실제 사용 예시&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Parallels나 VMware를 통한 맥북에서의 윈도우 운영&lt;/li&gt;
&lt;li&gt;클라우드 서비스에서의 가상 서버 인스턴스 운영&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;서버 운영 방식&lt;/h2&gt;
&lt;h3&gt;온프레미스 (On-Premises)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;자체 데이터센터나 서버실에서 직접 서버 운영&lt;/li&gt;
&lt;li&gt;완전한 제어권과 보안성&lt;/li&gt;
&lt;li&gt;초기 투자비용이 높고 유지보수 부담&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;오프프레미스 (Off-Premises)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AWS, GCP 등 클라우드 서비스 활용&lt;/li&gt;
&lt;li&gt;탄력적인 자원 운영&lt;/li&gt;
&lt;li&gt;초기 비용 절감과 빠른 서비스 구축&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;클라우드 서비스 모델&lt;/h2&gt;
&lt;h3&gt;IaaS (Infrastructure as a Service)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;가상화된 컴퓨팅 자원 제공&lt;/li&gt;
&lt;li&gt;사용자가 직접 인프라 구성&lt;/li&gt;
&lt;li&gt;예시: AWS EC2, Google Compute Engine&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;PaaS (Platform as a Service)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;개발 플랫폼 환경 제공&lt;/li&gt;
&lt;li&gt;인프라 관리 없이 애플리케이션 개발에 집중&lt;/li&gt;
&lt;li&gt;예시: Heroku, Google App Engine&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SaaS (Software as a Service)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;완성된 소프트웨어 서비스 제공&lt;/li&gt;
&lt;li&gt;별도 설치 없이 웹에서 바로 사용&lt;/li&gt;
&lt;li&gt;예시: Notion, Google Workspace&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;컨테이너와 도커&lt;/h2&gt;
&lt;h3&gt;컨테이너 기술&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션과 의존성을 패키징&lt;/li&gt;
&lt;li&gt;일관된 실행 환경 제공&lt;/li&gt;
&lt;li&gt;가볍고 빠른 배포 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;도커 (Docker)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 기술의 사실상 표준&lt;/li&gt;
&lt;li&gt;간편한 애플리케이션 패키징과 배포&lt;/li&gt;
&lt;li&gt;개발-테스트-운영 환경의 일관성 보장&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;도커 작업 흐름&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Dockerfile 작성 (컨테이너 정의)&lt;/li&gt;
&lt;li&gt;도커 이미지 빌드&lt;/li&gt;
&lt;li&gt;도커 컨테이너 실행&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;CI/CD&lt;/h2&gt;
&lt;h3&gt;CI (Continuous Integration)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;지속적인 코드 통합&lt;/li&gt;
&lt;li&gt;자동화된 빌드와 테스트&lt;/li&gt;
&lt;li&gt;코드 품질 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;CD (Continuous Delivery/Deployment)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;지속적인 배포&lt;/li&gt;
&lt;li&gt;자동화된 릴리스 프로세스&lt;/li&gt;
&lt;li&gt;신속한 서비스 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;주요 구성 요소&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;테스트 자동화&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;단위 테스트&lt;/li&gt;
&lt;li&gt;통합 테스트&lt;/li&gt;
&lt;li&gt;E2E 테스트&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;배포 파이프라인&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;코드 병합&lt;/li&gt;
&lt;li&gt;빌드 자동화&lt;/li&gt;
&lt;li&gt;테스트 실행&lt;/li&gt;
&lt;li&gt;배포 자동화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;도구&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Jenkins (기업용)&lt;/li&gt;
&lt;li&gt;GitHub Actions (개인/소규모 프로젝트)&lt;/li&gt;
&lt;li&gt;GitLab CI/CD&lt;/li&gt;
&lt;li&gt;CircleCI&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;객체지향 프로그래밍 기초&lt;/h2&gt;
&lt;h3&gt;클래스와 객체&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클래스: 객체의 설계도&lt;/li&gt;
&lt;li&gt;객체: 클래스의 인스턴스&lt;/li&gt;
&lt;li&gt;인스턴스: 메모리에 할당된 객체&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Static 키워드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클래스 레벨의 멤버 정의&lt;/li&gt;
&lt;li&gt;공유 자원 관리&lt;/li&gt;
&lt;li&gt;메모리 효율성 고려 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;프로그래밍 핵심 개념&lt;/h2&gt;
&lt;h3&gt;추상화&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;복잡한 시스템의 핵심 기능 추출&lt;/li&gt;
&lt;li&gt;사용자 친화적 인터페이스 제공&lt;/li&gt;
&lt;li&gt;시스템 복잡도 감소&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;컴파일러와 인터프리터&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;고급 언어를 기계어로 변환&lt;/li&gt;
&lt;li&gt;실행 시점의 차이&lt;/li&gt;
&lt;li&gt;각각의 장단점 존재&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/34</guid>
      <comments>https://junmonologue.tistory.com/34#entry34comment</comments>
      <pubDate>Thu, 24 Jul 2025 15:24:09 +0900</pubDate>
    </item>
    <item>
      <title>야구어플 개발 #1 (KBO 경기결과 크롤링)</title>
      <link>https://junmonologue.tistory.com/33</link>
      <description>&lt;h1&gt;[야구앱 개발기 #1] KBO 경기 일정 크롤러 구현&lt;/h1&gt;
&lt;p&gt;야구 관련 애플리케이션을 개발하기 시작했다.&lt;br&gt;프론트쪽에서 실제 경기 일정을 제공해 주는 것을 원해서 여러 검색을 통해 KBO 공식 홈페이지에서 경기 일정을 크롤링하는 기능을 구현하기로 했다.&lt;/p&gt;
&lt;p&gt;이번 포스팅에서는 KBO 경기 결과 크롤링 기능을 어떻게 구현했는지 기록해보려고 한다.&lt;/p&gt;
&lt;h2&gt;요구사항 분석&lt;/h2&gt;
&lt;p&gt;KBO 공식 홈페이지(&lt;a href=&quot;https://www.koreabaseball.com/Schedule/Schedule.aspx)%EC%97%90%EC%84%9C&quot;&gt;https://www.koreabaseball.com/Schedule/Schedule.aspx)에서&lt;/a&gt; 다음 정보들을 수집해야 했다&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;경기 날짜/시간&lt;/li&gt;
&lt;li&gt;홈팀/원정팀&lt;/li&gt;
&lt;li&gt;경기장&lt;/li&gt;
&lt;li&gt;TV 중계 채널&lt;/li&gt;
&lt;li&gt;경기 상태 (예정/완료)&lt;/li&gt;
&lt;li&gt;경기 결과 (완료된 경우 점수)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;기술적 제약사항&lt;/h3&gt;
&lt;p&gt;KBO 홈페이지를 분석해보니 월별 일정을 보려면 드롭다운 메뉴를 조작해야 했다.&lt;br&gt; 이는 JavaScript로 동적으로 처리되기 때문에 정적 크롤링으로는 불가능했다. 따라서 Selenium을 사용한 동적 크롤링이 필요했다.&lt;/p&gt;
&lt;h3&gt;의존성 설정&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;build.gradle&lt;/code&gt;에 Selenium 관련 의존성을 추가했다&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-gradle&quot;&gt;// Selenium
implementation &amp;#39;org.seleniumhq.selenium:selenium-java:4.8.0&amp;#39;
implementation &amp;#39;io.github.bonigarcia:webdrivermanager:5.3.2&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;webdrivermanager&lt;/code&gt;는 Chrome 드라이버를 자동으로 관리해주는 라이브러리다. 예전에는 Chrome 버전에 맞는 드라이버를 수동으로 다운받아야 했는데, 이제는 자동으로 처리해준다.&lt;/p&gt;
&lt;h2&gt;문제 발생&lt;/h2&gt;
&lt;h3&gt;초기 구현의 한계&lt;/h3&gt;
&lt;p&gt;처음에는 단순히 &lt;code&gt;row.getText()&lt;/code&gt;로 전체 텍스트를 가져와서 공백으로 split하는 방식으로 구현했다&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;String[] cols = text.split(&amp;quot;\\s+&amp;quot;);
String timeStr = cols[idx++];
String match = cols[idx++];
String tv = cols[idx++];&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 방식은 언뜻 보기에는 동작하는 것 같았지만, 실제 데이터를 확인해보니 문제들이 발견되었다&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;스타디움 파싱 오류&lt;/strong&gt;: 스타디움 결과에 하이라이트 값이 들어갔다. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tv_channel 결과 값과 비고 값 오류&lt;/strong&gt;: 티비채널의 결과값이 비고 값으로 들어가고 티비 채널결과에 비고 값이 들어갔다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 누락&lt;/strong&gt;: TV 채널, 경기장 등의 정보가 제대로 추출되지 않음&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;문제 인식&lt;/h2&gt;
&lt;h3&gt;근본 원인 분석&lt;/h3&gt;
&lt;p&gt;문제의 근본 원인은 &lt;strong&gt;HTML 구조를 제대로 파악하지 않고 텍스트 기반으로만 파싱을 시도한 것&lt;/strong&gt;이었다.&lt;br&gt; KBO 홈페이지의 실제 테이블 구조는 다음과 같이 복잡했다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;날짜는 &lt;code&gt;rowspan&lt;/code&gt; 속성으로 여러 행에 걸쳐 표시&lt;/li&gt;
&lt;li&gt;팀명과 스코어는 별도의 &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;과 &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt; 태그로 구조화&lt;/li&gt;
&lt;li&gt;각 컬럼이 명확한 CSS 클래스로 구분됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;단순 텍스트 파싱으로는 이런 구조화된 데이터를 정확히 추출할 수 없었다.&lt;/p&gt;
&lt;h2&gt;문제 해결을 위한 방법&lt;/h2&gt;
&lt;h3&gt;HTML 구조 분석 도구 개발&lt;/h3&gt;
&lt;p&gt;정확한 파싱을 위해 먼저 실제 HTML 구조를 상세히 분석하는 디버거 도구를 개발했다&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public class GameScheduleCrawlerDebugger {
    public static void main(String[] args) throws Exception {
        int month = args.length &amp;gt; 0
                ? Integer.parseInt(args[0])
                : LocalDate.now().getMonthValue();

        ChromeOptions opts = new ChromeOptions();
        opts.addArguments(&amp;quot;--headless&amp;quot;, &amp;quot;--no-sandbox&amp;quot;, &amp;quot;--disable-gpu&amp;quot;, &amp;quot;--window-size=1920,1080&amp;quot;);
        WebDriver driver = new ChromeDriver(opts);

        try {
            // 페이지 접근 및 월 선택
            driver.get(&amp;quot;https://www.koreabaseball.com/Schedule/Schedule.aspx&amp;quot;);
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            new Select(wait.until(
                    ExpectedConditions.elementToBeClickable(By.id(&amp;quot;ddlMonth&amp;quot;))
            )).selectByValue(String.format(&amp;quot;%02d&amp;quot;, month));

            // 테이블 분석
            WebElement table = wait.until(
                    ExpectedConditions.visibilityOfElementLocated(By.className(&amp;quot;tbl-type06&amp;quot;))
            );
            WebElement tbody = table.findElement(By.tagName(&amp;quot;tbody&amp;quot;));
            List&amp;lt;WebElement&amp;gt; rows = tbody.findElements(By.tagName(&amp;quot;tr&amp;quot;));

            ObjectMapper om = new ObjectMapper();
            int rowNum = 0;

            for (WebElement row : rows) {
                if (row.getText().contains(&amp;quot;데이터가 없습니다&amp;quot;)) continue;

                Map&amp;lt;String, String&amp;gt; debug = new LinkedHashMap&amp;lt;&amp;gt;();

                // HTML 원본 저장
                debug.put(&amp;quot;_innerHTML&amp;quot;, row.getAttribute(&amp;quot;innerHTML&amp;quot;));

                // 구조화된 데이터 추출
                List&amp;lt;WebElement&amp;gt; dayTd = row.findElements(By.cssSelector(&amp;quot;td.day&amp;quot;));
                debug.put(&amp;quot;date&amp;quot;, dayTd.isEmpty() ? &amp;quot;&amp;quot; : dayTd.get(0).getText().trim());

                debug.put(&amp;quot;time&amp;quot;, row.findElement(By.cssSelector(&amp;quot;td.time b&amp;quot;)).getText().trim());

                // 팀명과 스코어 정확히 분리
                WebElement play = row.findElement(By.cssSelector(&amp;quot;td.play&amp;quot;));
                List&amp;lt;WebElement&amp;gt; spans = play.findElements(By.tagName(&amp;quot;span&amp;quot;));
                debug.put(&amp;quot;away&amp;quot;, spans.size() &amp;gt; 0 ? spans.get(0).getText().trim() : &amp;quot;&amp;quot;);
                debug.put(&amp;quot;home&amp;quot;, spans.size() &amp;gt; 1 ? spans.get(1).getText().trim() : &amp;quot;&amp;quot;);
                List&amp;lt;WebElement&amp;gt; ems = play.findElements(By.tagName(&amp;quot;em&amp;quot;));
                debug.put(&amp;quot;score&amp;quot;, ems.isEmpty() ? &amp;quot;&amp;quot; : ems.get(0).getText().trim());

                // 나머지 컬럼들
                WebElement relay = row.findElement(By.cssSelector(&amp;quot;td.relay&amp;quot;));
                debug.put(&amp;quot;col2_tv&amp;quot;, relay.findElement(By.xpath(&amp;quot;following-sibling::td[2]&amp;quot;)).getText().trim());
                debug.put(&amp;quot;col4_stadium&amp;quot;, relay.findElement(By.xpath(&amp;quot;following-sibling::td[4]&amp;quot;)).getText().trim());
                debug.put(&amp;quot;col5_note&amp;quot;, relay.findElement(By.xpath(&amp;quot;following-sibling::td[5]&amp;quot;)).getText().trim());

                System.out.println(&amp;quot;=== ROW &amp;quot; + (++rowNum) + &amp;quot; ===&amp;quot;);
                System.out.println(om.writerWithDefaultPrettyPrinter().writeValueAsString(debug));
            }
        } finally {
            driver.quit();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;분석 결과&lt;/h3&gt;
&lt;p&gt;디버거 실행 결과, 실제 데이터 구조가 명확해졌다 &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &amp;quot;date&amp;quot; : &amp;quot;07.01(화)&amp;quot;,
  &amp;quot;time&amp;quot; : &amp;quot;18:30&amp;quot;,
  &amp;quot;away&amp;quot; : &amp;quot;삼성&amp;quot;,
  &amp;quot;home&amp;quot; : &amp;quot;두산&amp;quot;,
  &amp;quot;score&amp;quot; : &amp;quot;4vs1&amp;quot;,
  &amp;quot;col2_tv&amp;quot; : &amp;quot;SPO-2T&amp;quot;,
  &amp;quot;col4_stadium&amp;quot; : &amp;quot;잠실&amp;quot;,
  &amp;quot;col5_note&amp;quot; : &amp;quot;-&amp;quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;핵심 발견사항:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;팀명은 &lt;code&gt;td.play&lt;/code&gt; 내의 &lt;code&gt;span&lt;/code&gt; 태그로 분리되어 있음 (첫 번째가 원정팀, 마지막이 홈팀)&lt;/li&gt;
&lt;li&gt;스코어는 &lt;code&gt;em&lt;/code&gt; 태그 내에 &amp;quot;4vs1&amp;quot; 형태로 저장&lt;/li&gt;
&lt;li&gt;TV 채널은 3번째 sibling, 경기장은 5번째 sibling 위치&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;해결 완료&lt;/h2&gt;
&lt;h3&gt;새로운 크롤러 구현&lt;/h3&gt;
&lt;p&gt;분석 결과를 바탕으로 정확한 크롤러를 구현했다&lt;/p&gt;
&lt;h4&gt;1. 엔티티 설계&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Entity
@Table(
    name = &amp;quot;games&amp;quot;,
    uniqueConstraints = @UniqueConstraint(
        columnNames = {&amp;quot;game_date&amp;quot;,&amp;quot;game_time&amp;quot;,&amp;quot;home_team&amp;quot;,&amp;quot;away_team&amp;quot;}
    )
)
@Getter @Setter @NoArgsConstructor
public class KboGame {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = &amp;quot;game_date&amp;quot;, nullable = false)
    private LocalDate gameDate;

    @Column(name = &amp;quot;game_time&amp;quot;, nullable = false)
    private LocalTime gameTime;

    @Column(name = &amp;quot;home_team&amp;quot;, length = 50, nullable = false)
    private String homeTeam;

    @Column(name = &amp;quot;away_team&amp;quot;, length = 50, nullable = false)
    private String awayTeam;

    @Column(length = 50)
    private String stadium;

    @Column(name = &amp;quot;tv_channel&amp;quot;, length = 20)
    private String tvChannel;

    @Column(length = 100)
    private String note;

    @Column(name = &amp;quot;home_score&amp;quot;)
    private Integer homeScore;

    @Column(name = &amp;quot;away_score&amp;quot;)
    private Integer awayScore;

    @Enumerated(EnumType.STRING)
    private Status status;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 정확한 파싱 로직&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Component
public class GameScheduleCrawler {
    private final KboGameRepository gameRepo;

    public void crawlAndUpsert(int month) {
        ChromeOptions opts = new ChromeOptions();
        opts.addArguments(&amp;quot;--headless&amp;quot;, &amp;quot;--no-sandbox&amp;quot;, &amp;quot;--disable-gpu&amp;quot;, &amp;quot;--window-size=1920,1080&amp;quot;);
        WebDriver driver = new ChromeDriver(opts);

        try {
            // 페이지 접근 및 월 선택
            driver.get(&amp;quot;https://www.koreabaseball.com/Schedule/Schedule.aspx&amp;quot;);
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            new Select(wait.until(
                    ExpectedConditions.elementToBeClickable(By.id(&amp;quot;ddlMonth&amp;quot;))
            )).selectByValue(String.format(&amp;quot;%02d&amp;quot;, month));

            WebElement table = wait.until(
                    ExpectedConditions.visibilityOfElementLocated(By.className(&amp;quot;tbl-type06&amp;quot;))
            );
            WebElement tbody = table.findElement(By.tagName(&amp;quot;tbody&amp;quot;));
            List&amp;lt;WebElement&amp;gt; rows = tbody.findElements(By.tagName(&amp;quot;tr&amp;quot;));

            LocalDate currentDate = null;

            for (WebElement row : rows) {
                if (row.getText().contains(&amp;quot;데이터가 없습니다&amp;quot;)) continue;

                // 1. 날짜 처리 (rowspan으로 첫 경기에만 표시)
                List&amp;lt;WebElement&amp;gt; dayTd = row.findElements(By.cssSelector(&amp;quot;td.day&amp;quot;));
                if (!dayTd.isEmpty()) {
                    String dateText = dayTd.get(0).getText().trim(); // &amp;quot;07.01(화)&amp;quot;
                    String mmdd = dateText.substring(0, 5); // &amp;quot;07.01&amp;quot;
                    int m = Integer.parseInt(mmdd.substring(0, 2));
                    int d = Integer.parseInt(mmdd.substring(3, 5));
                    currentDate = LocalDate.of(LocalDate.now().getYear(), m, d);
                }

                // 2. 시간
                LocalTime gameTime = LocalTime.parse(
                    row.findElement(By.cssSelector(&amp;quot;td.time b&amp;quot;)).getText().trim()
                );

                // 3. 팀명과 스코어
                WebElement play = row.findElement(By.cssSelector(&amp;quot;td.play&amp;quot;));
                List&amp;lt;WebElement&amp;gt; spans = play.findElements(By.tagName(&amp;quot;span&amp;quot;));
                String awayTeam = spans.get(0).getText().trim();
                String homeTeam = spans.get(spans.size() - 1).getText().trim();

                // 4. 스코어 및 상태
                Integer homeScore = null, awayScore = null;
                Status status;
                List&amp;lt;WebElement&amp;gt; ems = play.findElements(By.tagName(&amp;quot;em&amp;quot;));

                if (!ems.isEmpty()) {
                    String scoreText = ems.get(0).getText().trim(); // &amp;quot;4vs1&amp;quot;
                    if (scoreText.contains(&amp;quot;vs&amp;quot;)) {
                        String[] scores = scoreText.split(&amp;quot;vs&amp;quot;);
                        awayScore = Integer.parseInt(scores[0]);
                        homeScore = Integer.parseInt(scores[1]);
                        status = Status.PLAYED;
                    } else {
                        status = Status.SCHEDULED;
                    }
                } else {
                    status = Status.SCHEDULED;
                }

                // 5. 기타 정보
                WebElement relay = row.findElement(By.cssSelector(&amp;quot;td.relay&amp;quot;));
                String tvChannel = relay.findElement(By.xpath(&amp;quot;following-sibling::td[2]&amp;quot;)).getText().trim();
                String stadium = relay.findElement(By.xpath(&amp;quot;following-sibling::td[4]&amp;quot;)).getText().trim();
                String note = relay.findElement(By.xpath(&amp;quot;following-sibling::td[5]&amp;quot;)).getText().trim();

                // 6. 중복 체크 및 저장
                Optional&amp;lt;KboGame&amp;gt; existing = gameRepo.findByGameDateAndGameTimeAndHomeTeamAndAwayTeam(
                        currentDate, gameTime, homeTeam, awayTeam);

                KboGame game = existing.orElse(new KboGame());
                game.setGameDate(currentDate);
                game.setGameTime(gameTime);
                game.setHomeTeam(homeTeam);
                game.setAwayTeam(awayTeam);
                game.setStadium(stadium);
                game.setTvChannel(tvChannel);
                game.setNote(note.equals(&amp;quot;-&amp;quot;) ? null : note);
                game.setHomeScore(homeScore);
                game.setAwayScore(awayScore);
                game.setStatus(status);

                gameRepo.save(game);
            }
        } finally {
            driver.quit();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3. API 엔드포인트&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@RestController
@RequestMapping(&amp;quot;/api&amp;quot;)
public class KboGameController {
    private final KboGameRepository repo;
    private final GameScheduleCrawler crawler;

    @GetMapping(&amp;quot;/games&amp;quot;)
    public List&amp;lt;KboGame&amp;gt; getByTeam(@RequestParam String team) {
        return repo.findByHomeTeamContainingOrAwayTeamContainingOrderByGameDateAscGameTimeAsc(team, team);
    }

    @GetMapping(&amp;quot;/month/{month}&amp;quot;)
    public ResponseEntity&amp;lt;String&amp;gt; crawlMonth(@PathVariable int month) {
        if (month &amp;lt; 1 || month &amp;gt; 12) {
            return ResponseEntity.badRequest().body(&amp;quot;month는 1~12 사이&amp;quot;);
        }
        crawler.crawlAndUpsert(month);
        return ResponseEntity.ok(&amp;quot;크롤링 완료: &amp;quot; + month + &amp;quot;월&amp;quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;최종 결과&lt;/h3&gt;
&lt;p&gt;새로운 구현으로 다음과 같은 정확한 데이터 수집이 가능해졌다&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;정확한 팀명&lt;/strong&gt;: &amp;quot;삼성&amp;quot; vs &amp;quot;두산&amp;quot; (기존: &amp;quot;삼성&amp;quot; vs &amp;quot;4&amp;quot;)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;정확한 스코어&lt;/strong&gt;: 원정팀 4점, 홈팀 1점 (기존: 파싱 실패)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;완전한 메타데이터&lt;/strong&gt;: TV 채널, 경기장, 비고 모두 수집&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;중복 방지&lt;/strong&gt;: 유니크 제약조건으로 동일 경기 중복 저장 방지&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;API 제공&lt;/strong&gt;: 팀별 경기 조회 및 수동 크롤링 트리거&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;이해한 점&lt;/strong&gt;: 웹 크롤링에서는 단순 텍스트 파싱보다 &lt;strong&gt;HTML 구조를 정확히 이해하고 CSS 셀렉터를 활용한 구조화된 접근&lt;/strong&gt;이 훨씬 안정적이고 정확하다는 것을 확인했다.&lt;/p&gt;</description>
      <category>프로젝트/야구어플</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/33</guid>
      <comments>https://junmonologue.tistory.com/33#entry33comment</comments>
      <pubDate>Sat, 19 Jul 2025 17:15:31 +0900</pubDate>
    </item>
    <item>
      <title>BoLD: 진정한 탈중앙화 네트워크를 향해가고 있는 아비트럼</title>
      <link>https://junmonologue.tistory.com/31</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;BoLD: 진정한 탈중앙화 네트워크를 향해가고 있는&amp;nbsp;아비트럼&lt;/b&gt;&lt;/h3&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6qk1b/btsMfaBnDFP/tueB1BQTOqLGZz5C5KHytk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6qk1b/btsMfaBnDFP/tueB1BQTOqLGZz5C5KHytk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6qk1b/btsMfaBnDFP/tueB1BQTOqLGZz5C5KHytk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6qk1b%2FbtsMfaBnDFP%2FtueB1BQTOqLGZz5C5KHytk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;362&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;목차&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;아비트럼과 레이어 2 솔루션이란?&lt;/li&gt;
&lt;li&gt;Arbitrum Classic: 초기 프로토콜의 역할과 한계&lt;/li&gt;
&lt;li&gt;BoLD(Bounded Liquidity Delay)의 필요성과 혁신적 접근&lt;/li&gt;
&lt;li&gt;BoLD의 작동 원리: 어떻게 분쟁을 해결하는가?&lt;/li&gt;
&lt;li&gt;BoLD의 주요 특징과 기술적 장점&lt;/li&gt;
&lt;li&gt;BoLD의 경제적 설계와 네트워크 안정성 강화&lt;/li&gt;
&lt;li&gt;BoLD가 가져올 변화와 미래 전망&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 아비트럼과 레이어 2&amp;nbsp;솔루션이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인 기술은 탈중앙화와 투명성, 신뢰성을 기반으로 혁신적인 가능성을 열어가고 있습니다. 그러나 이더리움과 같은 주요 네트워크는 높은 가스비와 느린 처리 속도로 인해 확장성 문제가 지속적으로 제기되었습니다. 이러한 문제를 해결하기 위해 등장한 것이 &lt;b&gt;레이어 2 솔루션&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이어 2 솔루션은 Layer 1 네트워크의 보안성을 유지하면서도 트랜잭션을 Layer 2에서 처리하여 성능을 개선하는 기술입니다. &lt;b&gt;아비트럼(Arbitrum)&lt;/b&gt;은 대표적인 레이어 2 솔루션으로, &lt;b&gt;Optimistic Rollup&lt;/b&gt; 기술을 통해 빠른 트랜잭션 처리와 낮은 가스비를 제공합니다. 현재 아비트럼은 높은 TVL(Total Value Locked)과 넓은 사용자 기반을 확보하며 레이어 2 시장을 선도하고 있습니다. 다만, 아비트럼은 확장성 문제를 해결하기 위한 중요한 역할을 수행하고 있으나, 허가된 검증자 시스템과 지연 공격의 위험성이라는 구조적 문제를 안고 있으며 볼드 이전 아비트럼 네트워크가 가진 문제점은 아래와 같습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. Arbitrum Classic: 초기 프로토콜의 역할과&amp;nbsp;한계&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Arbitrum Classic&lt;/b&gt;은 아비트럼의 초기 분쟁 해결 프로토콜로, 검증자들이 네트워크 상태를 주장하고 이의가 있을 경우 분쟁을 해결하도록 설계되었습니다. 이 프로토콜은 네트워크 무결성을 유지하는 데 중요한 역할을 했지만, 몇 가지 한계를 드러냈습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1) 지연 공격(Delay Attack)의&amp;nbsp;취약성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재의 Arbitrum Classic 프로토콜은 Delay Attack에 취약한 구조를 가지고 있습니다. 이 공격은 악의적인 검증자가 충분한 자금을 활용하여 상태 확정을 반복적으로 지연시킴으로써 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Delay Attack이 초래하는 주요 문제는 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용자 경험 악화&lt;br /&gt;L2에서 L1으로 자산 인출이 지연됨에 따라 사용자는 거래가 확정되기까지 오랜 시간을 기다려야 합니다.&lt;/li&gt;
&lt;li&gt;네트워크 효율성 저하&lt;br /&gt;검증이 지연됨에 따라 네트워크 전체의 효율성과 안정성이 약화됩니다.&lt;/li&gt;
&lt;li&gt;신뢰성 저하&lt;br /&gt;이러한 공격은 아비트럼 네트워크의 신뢰도를 낮추는 요인으로 작용하며, 사용자와 투자자의 신뢰를 약화시킬수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2) 허가된 검증자&amp;nbsp;시스템&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Arbitrum은 Optimistic Rollup 기술을 통해 이더리움의 확장성 문제를 해결하고자 합니다. 이를 위해 L2에서 트랜잭션을 처리한 후, 결과를 요약하여 L1 이더리움에 기록하는 방식을 채택하고 있습니다. 그러나 현재 검증 시스템은 permitted구조로 운영되며 일부 검증자 그룹만이 체인의 상태를 확인하고 분쟁 해결에 참여할 수 있습니다. 이러한 허가된 검증자 시스템은 네트워크의 탈중앙화 수준을 낮추게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇듯 현재 아비트럼은 확장성 문제를 해결하기 위한 중요한 역할을 수행하고 있으나, 허가된 검증자 시스템과 지연 공격의 위험성이라는 구조적 문제를 안고 있습니다. L2Beat 기준으로 Stage 2 롤업 달성을 위한 기술적 과제가 남아 있으며, 이를 해결하기 위해 아비트럼은 BoLD를 내놓으며 다음 단계의 L2로 나아가기 위한 스텝을 밟고 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. BoLD(Bounded Liquidity Delay)의 필요성과 혁신적&amp;nbsp;접근&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 Classic의 한계를 극복하고 아비트럼 네트워크를 한 단계 더 발전시키기 위해 설계된 차세대 분쟁 해결 프로토콜입니다. BoLD는 다음과 같은 목표를 통해 혁신적인 접근을 제시합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1) 시간 제한을 통한 지연 공격&amp;nbsp;방지&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 모든 분쟁이 &lt;b&gt;최대 6.4일&lt;/b&gt; 이내에 해결되도록 보장합니다. 분쟁 해결 과정에서 엄격한 시간 제한을 설정해, 악의적인 검증자가 의도적으로 분쟁을 연장하는 가능성을 원천적으로 차단합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2) Permissionless Validation 실현&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 누구나 네트워크 상태를 검증하고 분쟁 해결에 참여할 수 있는 환경을 제공합니다. 이는 특정 검증자 집단에 의존하지 않는 완전한 탈중앙화를 가능하게 하며, 네트워크 투명성과 신뢰도를 강화합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3) Stage 2 Rollup 목표&amp;nbsp;달성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 비탈릭 부테린이 제시한 Stage 2 Rollup 기준을 충족하는 데 중요한 역할을 합니다. 이는 네트워크 상태 검증과 이의 제기가 누구나 가능하며, 네트워크가 특정 엔티티의 통제에서 벗어나는 완전한 탈중앙화를 의미합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. BoLD의 작동 원리: 어떻게 분쟁을&amp;nbsp;해결하는가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 분쟁을 단계적으로 해결하는 체계적인 과정을 따릅니다. 이를 통해 분쟁의 범위를 좁히고, 효율적이고 공정한 해결을 보장합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1) 상태 주장(Assertion)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검증자는 가장 최근 확정된 RBlock(Block A)에서 시작해 Nitro의 **결정론적 상태 전환 함수(State Transition Function, STF)**를 사용해 최종 상태(Block Z)를 계산합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;검증자는 Block Z가 올바른 상태라고 판단되면 자금을 본딩하고 이를 이더리움 네트워크에 게시합니다.&lt;/li&gt;
&lt;li&gt;일정 시간(챌린지 기간) 동안 이의가 없으면 Block Z는 체인의 올바른 상태로 확정됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2) 도전(Challenge)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 검증자가 Block Z의 상태에 이의를 제기할 경우, BoLD는 분쟁 해결 메커니즘을 작동시킵니다. 이의 제기자는 새로운 상태(Block Y)를 주장하며 자금을 본딩합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3) 다단계 분쟁 해결&amp;nbsp;과정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 모든 트랜잭션을 처음부터 확인하지 않고, 분쟁의 범위를 점진적으로 좁히는 방식을 채택합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;블록 챌린지(Block Challenge)&lt;/b&gt;: 분쟁의 범위를 특정 블록으로 좁힙니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빅 스텝 챌린지(Big Step Challenge)&lt;/b&gt;: 블록 내에서 상태 전환 함수의 명령어 범위를 줄입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;원 스텝 챌린지(One Step Challenge)&lt;/b&gt;: 단일 명령어 수준으로 좁혀 최종 상태를 결정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4) 원 스텝 증명(One Step&amp;nbsp;Proof)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검증자들은 단일 명령어의 결과를 증명하는 자료를 &lt;b&gt;OneStepProof 스마트 컨트랙트&lt;/b&gt;에 제출합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스마트 컨트랙트는 제출된 자료를 검증하여 정직한 검증자의 주장을 채택합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. BoLD의 주요 특징과 기술적&amp;nbsp;장점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 아비트럼 네트워크에서 발생하는 분쟁 해결 방식을 혁신적으로 개선한 프로토콜로, 네트워크의 안정성과 효율성을 획기적으로 높입니다. 기존 Arbitrum Classic이 가지고 있던 한계를 넘어, BoLD는 시간 제한, 병렬 처리, 정직한 검증자의 보호 등 기술적 장점을 통해 완전한 탈중앙화와 보안성을 실현합니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJFy89/btsMeb2hKpZ/hz9e2KsVuu0SgdKx0Xxns1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJFy89/btsMeb2hKpZ/hz9e2KsVuu0SgdKx0Xxns1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJFy89/btsMeb2hKpZ/hz9e2KsVuu0SgdKx0Xxns1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJFy89%2FbtsMeb2hKpZ%2Fhz9e2KsVuu0SgdKx0Xxns1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;450&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;첫 번째 특징은 분쟁 해결 시간의 상한을 설정한 점&lt;/b&gt;입니다. BoLD는 모든 분쟁이 &lt;b&gt;최대 6.4일 이내&lt;/b&gt;에 해결되도록 설계되었습니다. 이는 기존 Classic에서 악의적인 검증자가 분쟁을 반복적으로 연장하며 지연 공격(Delay Attack)을 수행할 수 있었던 취약점을 근본적으로 해결합니다. BoLD는 각 단계별로 제한 시간을 설정해 분쟁이 장기화되는 일을 방지하며, 사용자가 L2에서 L1으로 자산을 인출할 때 빠르고 안정적인 경험을 제공합니다. 이러한 시간 제한은 BoLD가 분쟁 해결 과정을 효율적으로 설계한 결과이며, 네트워크 전체의 처리 속도를 크게 향상시킵니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQtK5r/btsMfi6ZEcP/1seGIgjdxakZsDV2MSXWXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQtK5r/btsMfi6ZEcP/1seGIgjdxakZsDV2MSXWXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQtK5r/btsMfi6ZEcP/1seGIgjdxakZsDV2MSXWXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQtK5r%2FbtsMfi6ZEcP%2F1seGIgjdxakZsDV2MSXWXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;450&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;두 번째로, BoLD는 정직한 검증자(Honesty Party)가 항상 승리하도록 설계된 프로토콜입니다.&lt;/b&gt; 아비트럼의 상태는 결정론적(deterministic)이기 때문에, 주어진 입력과 트랜잭션에 대해 항상 단 하나의 올바른 상태만이 존재합니다. BoLD는 이러한 결정론적 특성을 기반으로, 단일 정직한 검증자라도 악의적인 다수의 검증자를 상대로 분쟁에서 승리할 수 있도록 보장합니다. 이는 네트워크의 무결성을 유지할 뿐만 아니라, 정직한 참여자가 네트워크에서 더 많은 신뢰와 권한을 부여받을 수 있는 환경을 조성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세 번째로, BoLD는 분쟁을 병렬로 처리할 수 있는 구조를 도입했습니다.&lt;/b&gt; 기존 Arbitrum Classic에서는 분쟁이 순차적으로 진행되었기 때문에, 다수의 분쟁이 동시에 발생할 경우 처리 속도가 느려지고 네트워크 효율성이 저하되는 문제가 있었습니다. 반면 BoLD는 병렬 처리를 통해 여러 분쟁을 동시에 해결할 수 있으며, 검증자들 간의 논쟁이 네트워크 성능에 미치는 영향을 최소화합니다. 예를 들어, 하나의 상태에 대해 여러 검증자가 이의를 제기하더라도 BoLD는 이를 동시에 처리하여 더 빠르게 결론에 도달할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD의 설계는 단순함 속에서 강력한 효율성을 발휘합니다. Nitro의 결정론적 상태 전환 함수(State Transition Function, STF)를 기반으로 동작하는 BoLD는 모든 상태 주장이 단일한 결과를 보장합니다. 이는 스마트 컨트랙트가 올바른 주장을 신속히 판단할 수 있도록 하며, 네트워크의 보안성과 신뢰도를 더욱 강화합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. BoLD의 경제적 설계와 네트워크 안정성&amp;nbsp;강화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 단순히 기술적 측면에서만 혁신적인 것이 아닙니다. 이 프로토콜은 경제적 메커니즘을 통해 네트워크의 안정성을 유지하고 악의적인 검증자를 효과적으로 억제합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD의 핵심 경제적 요소는 &lt;b&gt;검증자 본딩 시스템&lt;/b&gt;입니다. 모든 검증자는 자신이 주장하는 상태에 자금을 본딩해야 하며, 이는 주장된 상태의 정확성을 보장하기 위한 강력한 경제적 동기부여 역할을 합니다. 초기 본딩 금액은 &lt;b&gt;3,600 ETH&lt;/b&gt;(2024년 기준 약 125억 원 상당)로 설정되어 있으며, 이 금액은 악의적인 검증자가 잘못된 주장을 통해 네트워크를 방해하기 어렵도록 높은 장벽을 제공합니다. 뿐만 아니라, 빅 스텝 챌린지나 원 스텝 챌린지와 같은 세부 단계에서도 추가 본딩이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 본딩 시스템은 악의적인 검증자가 잘못된 주장을 통해 네트워크를 방해할 경우 큰 경제적 손실을 입게 만듭니다. 잘못된 주장이 기각되면, 검증자는 본딩한 자금을 몰수당하며, 해당 자금은 아비트럼 DAO에 귀속됩니다. 반면, 정직한 검증자는 분쟁에서 승리하면 자신의 본딩 자금을 회수할 뿐만 아니라, 몰수된 자금의 일부를 보상으로 받을 수 있습니다. 이 보상 체계는 정직한 검증자가 네트워크 무결성을 유지하고 적극적으로 참여하도록 유도하는 효과를 가집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, BoLD는 &lt;b&gt;시간 초과 규정&lt;/b&gt;을 통해 불필요한 시간 낭비를 방지합니다. 각 분쟁 단계에는 제한 시간이 설정되어 있으며, 상대 검증자가 정해진 시간 내에 응답하지 않으면 타이머가 종료되고 정직한 검증자의 주장이 자동으로 확정됩니다. 이 설계는 신속한 분쟁 해결을 촉진하며, 네트워크 효율성을 극대화합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD의 경제적 설계는 네트워크의 안정성을 유지하고 검증 생태계를 건전하게 유지하는 데 중요한 역할을 합니다. 이는 아비트럼 네트워크가 신뢰받는 플랫폼으로 자리 잡는 데 필수적인 요소로 작용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7. BoLD가 가져올 변화와 미래&amp;nbsp;전망&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 단순히 새로운 기술 도입을 넘어, 아비트럼 네트워크와 레이어 2 생태계에 중요한 변화를 가져올 것으로 기대됩니다. 가장 큰 변화는 &lt;b&gt;Permissionless Validation&lt;/b&gt;의 실현입니다. 기존 Arbitrum Classic에서는 검증에 참여할 수 있는 주체가 제한되어 있었으나, BoLD는 누구나 네트워크 상태를 검증하고 분쟁 해결 과정에 참여할 수 있도록 허용합니다. 이는 특정 검증자 집단에 의존하지 않는 완전한 탈중앙화를 가능하게 하며, 네트워크의 투명성과 신뢰성을 강화합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BoLD는 또한 네트워크의 &lt;b&gt;보안성과 신뢰성&lt;/b&gt;을 한 단계 끌어올립니다. 분쟁이 병렬로 처리되고, 정직한 검증자가 항상 승리하도록 보장되며, 악의적인 검증자는 경제적 페널티를 받는 구조는 네트워크의 안정성을 더욱 강화합니다. 이로 인해 사용자들은 더 빠르고 안정적인 네트워크를 경험할 수 있으며, 투자자들은 아비트럼의 신뢰성에 대해 확신을 가질 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로, BoLD는 아비트럼이 비탈릭 부테린이 제시한 Stage 2 Rollup 목표를 달성하는 데 중요한 역할을 합니다. Stage 2는 누구나 네트워크 상태를 검증하고 이더리움에 사기 증명을 게시할 수 있는 완전한 탈중앙화 상태를 의미합니다. BoLD는 이러한 목표를 실현하기 위한 핵심 기술로 작용하며, 아비트럼을 Layer 2 시장에서 가장 선도적인 플랫폼으로 자리 잡게 할 것입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>블록체인/기술</category>
      <category>가상화폐</category>
      <category>레이어2</category>
      <category>블록체인</category>
      <category>아비트럼</category>
      <category>테크</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/31</guid>
      <comments>https://junmonologue.tistory.com/31#entry31comment</comments>
      <pubDate>Tue, 11 Feb 2025 14:31:19 +0900</pubDate>
    </item>
    <item>
      <title>비잔틴 장군 문제와 블록체인</title>
      <link>https://junmonologue.tistory.com/30</link>
      <description>&lt;h2&gt;비잔틴 장군 문제란?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;비잔틴 장군 문제의 시나리오&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;비잔틴 제국의 여러 장군들이 적을 포위하고 있고. 이 장군들은 공격 또는 후퇴와 같은 행동을 통일되게 결정해야 한다. 그러나 장군들은 서로 멀리 떨어져 있어 메신저를 통해서만 소통할 수 있다. &lt;ol&gt;
&lt;li&gt;일부 장군들은 배신자일 수 있고, 의도적으로 잘못된 정보를 보내 다른 장군들이 혼란에 빠지게 할 수 있다. &lt;/li&gt;
&lt;li&gt;모든 충성스러운 장군들은 동일한 결정을 내리도록 해야한다. &lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;이 문제는 네트워크에 장애가 발생하거나 악의적인 노드가 있을 때, 분산 시스템이 어떻게 신뢰할 수 있는 결정을 내릴 수 있는지와 같은 문제이다. &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;블록체인과 비잔틴 장군 문제&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;블록체인은 분산된 데이터베이스 시스템으로 노드 간의 신뢰성 문제를 해결하기 위해 고안된 합의 알고리즘을 사용한다. 이러한 알고리즘은 비잔틴 장애 에서도 네트워크가 정확한 상태를 유지하도록 한다. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;블록체인에서 비잔틴 장애를 해결하는 방법&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;합의 알고리즘 : 블록체인은 비잔틴 장애를 해결하기 위해 다양한 합의 알고리즘을 사용할 수 있다. 대표적으로 Proof of Work(PoW), Proof of. Take(PoS)등이 있다. 이러한 알고리즘은 참여 노드들이 동일한 블록을 선택하고, 이를 추가하는 과정에서 다수결 원리 또는 다른 규칙에 따라 결정을 내린다.&lt;/li&gt;
&lt;li&gt;분산 기록 : 블록체인은 모든 트랜잭션을 블록에 기록해서 변경 불가능한 형태로 유지한다. 여러 노드에 동일한 데이터가 분산되어 있기 때문에, 일부 노드가 악의적으로 행동해도 다수의 노드가 올바른 정보를 가지고 있어 시스템의 신뢰성을 유지할 수 있다.&lt;/li&gt;
&lt;li&gt;암호화와 해시 함수 : 블록체인은 각 블록에 암호화된 해시 값을 포함시켜, 블록 간의 연결성을 유지하고 데이터 위변조를 방지한다. 이 암호화는 비잔틴 장애를 방지할 수 있습니다. &lt;/li&gt;
&lt;li&gt;검증 : 새로운 블록이 네트워크에 추가되기 전에 모든 참여 노드에 의해 검증된다. 이 과정에서 잘못된 정보가 포함된 블록은 거부될 수 있다. &lt;/li&gt;
&lt;/ol&gt;</description>
      <category>블록체인/기술</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/30</guid>
      <comments>https://junmonologue.tistory.com/30#entry30comment</comments>
      <pubDate>Sat, 14 Dec 2024 21:51:03 +0900</pubDate>
    </item>
    <item>
      <title>이더리움의 확장성 해결책</title>
      <link>https://junmonologue.tistory.com/29</link>
      <description>&lt;h1&gt;이더리움의 확장성 해결책&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;플라즈마와 토카막 네트워크의 역할과 기대효과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;목 차&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;서론
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;보고서의 목적&lt;/li&gt;
&lt;li&gt;이더리움과 블록체인 기술의 기본 개념&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;이더리움의 확장성 문제
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;이더리움 확장성 문제&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;플라즈마 알고리즘
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;플라즈마 알고리즘의 기본 원리&lt;/li&gt;
&lt;li&gt;플라즈마 알고리즘의 한계와 가능성&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;플라즈마를 활용한 토카막 네트워크
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;토카막 네트워크&lt;/li&gt;
&lt;li&gt;토카막 네트워크의 구조 및 기능&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;토카막 네트워크를 진행하는 블록체인 회사
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;온더&lt;/li&gt;
&lt;li&gt;토카막 네트워크에 대한 온더의 기여와 역할&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;온더가 발행한 TON
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;TON의 역할과 기능&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;결론
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;토카막 프로젝트의 현재 상태와 성과&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;참고 문헌&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 서론&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.1 &lt;b&gt;보고서의 목적&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디지털 경제의 핵심 요소로 자리잡고 있는 블록체인 기술은 그 중심에서 이더리움이 중추적 역할을 하고 있습니다. 이더리움은 글로벌 금융 거래, 스마트 컨트랙트 , 분산형 애플리케이션(dApps) 구축을 가능하게 하는 핵심 기술로 널리 사용되고 있습니다. 하지만, 이더리움의 네트워크는 그 사용자와 거래량의 급격한 증가에 따라 성능 및 확장성의 한계에 직면하고 있습니다. 이러한 확장성 문제는 네트워크의 지속 가능한 성장과 발전을 위협하며, 이를 해결하기 위한 다양한 기술적 접근이 시도되고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 보고서의 주요 목적은 이더리움의 확장성 한계를 짚어보고, 플라즈마 알고리즘을 활용하여 이 한계를 어떻게 극복하고 있는지에 대해 알아보는 것입니다. 특히, 한국의 블록체인 기업인 온더가 진행하는 토카막 네트워크를 중심으로, 이 기술이 실제로 어떻게 구현되고 있는지를 분석합니다. 이 과정을 통해, 토카막 프로젝트가 이더리움 네트워크의 확장성 향상에 기여하고 있는 방식과 그 결과를 체계적으로 분석하고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.2 &lt;b&gt;이더리움과 블록체인 기술의 기본 개념&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인은 &lt;b&gt;분산형 디지털 원장 기술&lt;/b&gt;로 트랜잭션의 데이터베이스 입니다.블록체인은 네트워크 상의 모든 참여자가 공유하는 투명하고 변조가 불가능한 거래 기록을 유지합니다. 이 기술은 데이터 블록들을 시간 순서대로 체인처럼 연결하여, 각 거래가 공정하고 투명하게 처리됨을 보장합니다. 블록체인의 이러한 특성은 중앙 집중식 기관이나 중개자 없이도 데이터의 신뢰성과 보안을 확보할 수 있게 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더리움은 블록체인 기술을 기반으로 한 플랫폼으로, 비트코인과 유사하지만 몇 가지 차이점이 있습니다. 가장 두드러진 차이점은 이더리움이 단순한 거래를 넘어 '스마트 컨트랙트'의 실행을 가능하게 한다는 점입니다. 스마트 컨트랙트는 계약 조건이 충족되면 자동으로 실행되는 자체 실행 가능한 코드 조각으로, 복잡한 금융, 법률, 그리고 다양한 종류의 계약을 디지털화하고 자동화하는데 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더리움은 이러한 스마트 컨트랙트를 사용하여 사용자가 자신만의 분산 애플리케이션(DApps)을 개발하고 운영할 수 있는 환경을 제공합니다. 이 애플리케이션들은 이더리움 네트워크 상에서 자동으로 작동하며, 중앙 집중식 서버가 없어도 네트워크를 통해 분산되어 관리됩니다. 이더리움의 이러한 기능은 디지털 아이덴티티, 자산 소유권 증명, 그리고 자동화된 거래 등 다양한 분야에서 혁신적인 솔루션을 제공할 가능성을 열어줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 이더리움의 확장성 문제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.1 &lt;b&gt;이더리움의 확장성 문제와 한계&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확장성이란 사용자 수의 증대에 유연하게 대응할 수 있는 정도입니다. 블록체인에서는 자원증가에 따라 트랜잭션의 처리속도가 증가하지 않는 문제를 뜻합니다. 암호화폐 초기에는 사용자가 많지 않아서 한 블록에 모든 거래를 담기에 충분했으나 점점 대중화 되면서 처리해야 할 거래량이 증가하게 되어 모든 데이터를 블록체인에 결합시키기엔 블록의 용량이 너무 커지게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 이더리움 블록체인의 구조는 초당 약 15개의 트랜잭션만 처리할 수 있어, 대규모 사용자 참여가 필요한 애플리케이션에는 부적합합니다. 이는 초당 약 200건의 거래를 처리하는 페이팔, 약 2000건의 거래를 처리하는 비자카드와 대조하면 현저히 느린 속도입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더리움 네트워크는 모든 노드가 각 트랜잭션을 처리해야 하기 때문에, 네트워크 확장 시 트랜잭션 지연과 병목 현상이 발생하고, 이는 사용자 간의 경쟁을 유발하여 가스비를 급등시킵니다. 사용자는 자신의 트랜잭션이 우선 처리되기를 바라면서 높은 가스비를 지불하게 되며, 이는 소액 거래나 실험적인 dApps의 접근성을 제한하고 이더리움 네트워크의 포괄적인 채택을 방해하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 이더리움의 확장성 문제는 플랫폼의 지속 가능한 성공을 제한하게 되며 블록체인 기술의 실제 서비스 적용의 한계를 가져올 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 플라즈마 알고리즘&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.1 &lt;b&gt;플라즈마 알고리즘의 기본원리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플라즈마 구조의 핵심은 루트 체인에 여러 자식 체인을 계층적으로 연결하는 것입니다. 이더리움 같은 루트 체인은 전체 플라즈마 체인의 상태를 감시하며, 각 자식 체인은 루트 체인에 대한 약속(커밋먼트)을 주기적으로 제공합니다. 이러한 계층적인 연결 구조는 루트 체인에서 발생하는 데이터의 부담을 줄이며, 각 자식 체인이 독립적인 블록체인으로서 특정 애플리케이션에 최적화된 처리를 수행할 수 있게 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image-20240706235225311.png&quot; data-origin-width=&quot;244&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzDJCX/btsIo8I2zXZ/CS4vdyh9KYBE1Isxf8Ipn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzDJCX/btsIo8I2zXZ/CS4vdyh9KYBE1Isxf8Ipn0/img.png&quot; data-alt=&quot;​&amp;amp;nbsp; 그림 1. 플라즈마 구조(출처: 플라즈마 백서)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzDJCX/btsIo8I2zXZ/CS4vdyh9KYBE1Isxf8Ipn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzDJCX%2FbtsIo8I2zXZ%2FCS4vdyh9KYBE1Isxf8Ipn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;223&quot; data-filename=&quot;image-20240706235225311.png&quot; data-origin-width=&quot;244&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;​&amp;nbsp; 그림 1. 플라즈마 구조(출처: 플라즈마 백서)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림1과 같이 플라즈마에서는 수많은 블록체인들이 트리 구조로 연결되며 그 끝에는 루트 체인이 위치해 있습니다. 이 하위 체인들은 메인 체인으로부터 독립적으로 트랜잭션을 처리하며 각기 다른 규칙이나 로직을 가질 수 있습니다. 모든 플라즈마 체인의 상세한 데이터가 루트 체인에 저장되지 않음으로써 메인 체인의 부담을 줄이고 스케일링 효과를 극대화합니다. 또한 각 플라즈마 체인의 요약된 정보만 루트 체인에 저장되어 이를 통해 보안성과 데이터 무결성을 보장합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image-20240706235352318.png&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3xnpF/btsIrupMAWm/Z7k2k6Jjkcrkt7bSD9e05K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3xnpF/btsIrupMAWm/Z7k2k6Jjkcrkt7bSD9e05K/img.png&quot; data-alt=&quot;그림 2. 이더리움 네트워크의 플라즈마 알고리즘(출처: 플라즈마 백서)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3xnpF/btsIrupMAWm/Z7k2k6Jjkcrkt7bSD9e05K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3xnpF%2FbtsIrupMAWm%2FZ7k2k6Jjkcrkt7bSD9e05K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;118&quot; data-filename=&quot;image-20240706235352318.png&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 2. 이더리움 네트워크의 플라즈마 알고리즘(출처: 플라즈마 백서)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플라즈마에서는 누구나 블록체인을 만들어 루트 체인에 연결이 가능합니다. 플라즈마가 도입되기 전의 이더리움의 DApp은 이더리움 메인 체인 위에서 동작했습니다. 허나 플라즈마의 도입 이후 그림처럼 사용 목적 별로 별도의 블록체인이 형성되어 규모있는 Dapp들이 개별적인 블록체인 위에서 동작하게 될 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.2 &lt;b&gt;플라즈마 알고리즘의 한계와 가능성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플라즈마 알고리즘은 블록체인의 확장성을 개선하려는 방법에서 새로운 실마리를 발견했지만, 몇 가지 한계를 가지고 있습니다. 첫째, 무거운 검증 과정으로 인해 리소스 소비가 많다는 점입니다. 복수의 체인이 계층적으로 연결되어 있음에도 불구하고, 안전성을 보장하기 위한 검증 과정이 많은 리소스를 요구합니다. 둘째, 거래 승인 과정이 복잡하다는 점입니다. 거래를 생성하고 블록을 생성하여 루트 체인에 올리는 과정이 여러 단계를 거치며, 이는 사용자에게 번거로움을 초래합니다. 셋째, Operator의 부정 행위에 대응하는 방법이 출금(exit) 과정에 의존한다는 점입니다. 부정한 출금 시도에 대해 다른 참여자들은 그저 자신의 출금을 요청하여 대응할 수밖에 없으며, 이는 네트워크를 마비시킬 수 있습니다. 이러한 한계는 플라즈마 네트워크의 안전성과 사용성에 중대한 영향을 미칠 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플라즈마 알고리즘은 한때 블록체인 확장성 문제에 대한 해결책으로 주목받았으나, 이러한 한계점 때문에 인기가 감소했습니다.그럼에도 불구하고, 최신의 영지식증명(ZK-SNARKs) 기술의 발전은 플라즈마를 다시금 중요한 대화의 주제로 만들고 있습니다. 비탈릭 부테린이 작성한 Exit games for EVM validiums: the return of Plasma에서 비탈릭은 영지식 기반 EVM 개발팀은 영지식증명이 이러한 한계를 극복하고 EVM과 같은 복잡한 시스템을 실행할 수 있는 플라즈마 체인을 가능하게 할 수 있는 도구를 제공할 수 있다고 말합니다. 이로 인해 플라즈마가 블록체인 기술의 미래에 다시 한번 핵심 역할을 할 수 있을지에 대한 기대가 커지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 플라즈마를 활용한 토카막 네트워크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.1 &lt;b&gt;토카막 네트워크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토카막 네트워크(Tokamak Network)는 온더(Onther)가 만든 이더리움 플라즈마 개발 프로젝트입니다. 토카막 네트워크는 플라즈마EVM(Plasma EVM) 기술을 기반으로 이더리움 메인체인과 연결되어 있으며, 탈중앙화되고 튜링완전한 플라즈마 블록체인입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토카막 네트워크는 플라즈마 체인 구축 플랫폼으로 Dapp 구축 시 토카막을 사용하면 자신만의 커스터마이징 가능한 플라즈마 체인을 구축할 수 있습니다. 토카막 네트워크는 이더리움과 동일 수준의 탈중앙성, 이더리움과 동일 수준의 안정성, 플라즈마 체인을 통한 높은 확장성을 제공하는 특징을 가지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.2 &lt;b&gt;토카막 네트워크의 구조 및 기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토카막 네트워크는 플라즈마 기술을 이더리움 가상 머신(EVM)과 통합한 플라즈마 EVM을 기반으로 작동합니다. 플라즈마 EVM은 토카막의 핵심 개념이라고 볼 수 있습니다. 플라즈마 EVM은 온더에서 제안한 튜링 완전한 플라즈마를 구동하기 위한 아키텍처로, 이더리움의 EVM과 마찬가지로 플라즈마 체인에 EVM을 실행하는 새로운 개념의 플라즈마입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플라즈마 EVM은 루트체인, 자식체인, 오퍼레이터 세 가지의 핵심 요소로 구성되며 루트체인에 연결된 여러 개의 자식체인이 존재합니다. 각 자식체인은 오퍼레이터에 의해 운영되며 오퍼레이터가 자식체인의 블록을 마이닝하고 루트체인의 컨트랙트에 해당 정보를 주기적으로 제출하는 과정으로 작동됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토카막 네트워크는 이더리움 메인체인과 동일한 구조이므로 이더리움의 스마트컨트랙트가 동일하게 실행 가능합니다. 이는 개발자들이 이더리움과 같은 환경에서 개발을 가능하게 만들 수 있습니다. 또한 합의가 필요없으므로 보다 빠른 Dapp 구동이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 토카막 네트워크를 진행하는 회사&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5.1 &lt;b&gt;(주)온더&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온더(Onther)는 이더리움 기반 레이어 2 스케일링 솔루션인 토카막 네트워크를 개발하고 운영하는 기업입니다. 이 회사는 플라즈마 기술을 기반으로 한 다양한 블록체인 프로젝트를 추진하며, 특히 토카막 네트워크를 통해 이더리움의 처리량과 속도 문제를 해결하고자 하는 기업입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온더(Onther)는 온 이더리움(On Ethereum)의 줄임말으로 이더리움 기반의 블록체인 플랫폼 구축을 통해 암호경제 생태계와 현실경제 간의 갭을 줄이고 사람과 디앱을 연결하고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5.2 &lt;b&gt;토카막 네트워크에 대한 온더의 기여와 역할&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토카막 네트워크는 온더(Onther)가 개발한 이더리움 기반의 플라즈마 프로젝트로, 이더리움과 동일한 사양을 갖춘 사이드체인을 통해 공개 이더리움 블록체인의 애플리케이션 서비스를 위한 확장성 문제를 해결하는 혁신적인 솔루션을 제공합니다. 이 네트워크는 이더리움의 확장 가능성을 크게 향상시키기 위해 설계되었으며, 온더의 플라즈마 EVM은 토큰을 다른 사용자에게 전송하는 기능을 포함하여 이론적 타당성을 실제로 입증하는 데 성공했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온더의 정순형 대표는 이러한 혁신적인 기술 개발로 인하여 이더리움 재단으로부터 장려금을 수여받을 정도로 국제적인 인정을 받고 있습니다. 이는 토카막 네트워크가 글로벌 블록체인 커뮤니티 내에서 뛰어난 기술적 기여를 한 것을 증명하며, 향후 블록체인 확장성에 대한 지속적인 발전을 이끌어 갈 주요 기술로 평가 받을 수 있다고 생각됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. 온더가 발행한 TON&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6.1 &lt;b&gt;TON의 역할과 기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토카막 네트워크에서 TON(Tokamak Network Token)은 네트워크의 기본적인 운영 통화로 사용되며, 다양한 역할과 기능을 수행합니다. 플라즈마 EVM에 합의가 존재하지 않아 빠른 속도를 유지하면서 토큰인 TON을 통해 탈중앙화를 유지할 수 있습니다. TON의 활용처는 아래와 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;스테이킹 : 토카막 플라즈마 체인을 탈중앙화 시키는 인센티브로 사용되며 서비스 운영자는 플라즈마 체인 오픈 시 이더리움 메인 체인에 최소한의 TON을 예치해야 합니다.&lt;/li&gt;
&lt;li&gt;챌린지 : 운영자들로부터 쌓인 TON은 체인이 비정상적으로 운영 시 문제를 제기한 사람에게 지급됩니다.&lt;/li&gt;
&lt;li&gt;스테미나 : 예치된 TON은 네트워크 내 수수료로 사용되는 스테미나 충전 시 사용됩니다.&lt;/li&gt;
&lt;li&gt;파워톤 : 네트워크 자체에서 운영되는 게임에 사용됩니다.TON 토큰은 토카막 네트워크에서 다양한 기능을 수행하며 네트워크의 안정성과 성장을 위한 핵심 요소로 작용합니다. 이는 토카막 네트워크의 블록체인 확장성 솔루션의 일환으로 이더리움과 같은 기존 블록체인의 한계를 극복하고 더 넓은 범위의 애플리케이션과 서비스를 지원하는 데 중요한 역할을 하고 있습니다.&lt;br /&gt;&lt;b&gt;7. 결론&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;현재 TON의 총 발행량응 50,000,000 TON으로 하드캡은 3,400,00USD입니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7.1 &lt;b&gt;토카막 프로젝트의 현재 상태와 성과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토카막 네트워크는 이더리움의 확장성 문제를 해결하기 위해 개발된 레이어2 스케일링 솔루션으로, 문제 해결을 위해 상당한 진전을 보이고 있습니다. 이 프로젝트는 다수의 독립적인 플라즈마 체인을 활용하여 이더리움 블록체인의 부하를 줄이고, 각 체인이 특정 애플리케이션에 최적화되도록 설계되었습니다. 옵티미스틱 롤업 기반의 구조를 통해 트랜잭션 처리 속도를 향상시키며, 네트워크의 전체적인 효율성과 성능을 극대화하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토카막 네트워크의 핵심 성과 중 하나는 높은 트랜잭션 처리량과 낮은 거래 비용을 실현한 것입니다. 이를 통해 사용자는 더 빠르고 비용 효율적인 방식으로 트랜잭션을 처리할 수 있게 되었습니다. 또한, 토카막의 TON 토큰은 네트워크의 거버넌스, 보안, 경제적 인센티브 메커니즘을 지원하는 중추적인 역할을 하며, 토카막 네트워크의 건강한 운영과 지속 가능한 성장을 도모하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크의 검증자와 참여자들은 TON 토큰을 통해 인센티브를 받으며, 이는 참여자들이 네트워크에 계속해서 기여하고 참여하도록 장려하는 중요한 요소입니다. 이러한 인센티브 구조는 네트워크의 안정성과 보안을 강화하는 데 기여하며, 네트워크 참여자들에게 지속적인 가치를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 토카막 프로젝트는 블록체인 기술의 혁신적인 발전을 나타내며, 이더리움 생태계 내에서 그 가치와 중요성을 점차 확립해 나가고 있습니다. 온더(Onther)는 이 프로젝트를 통해 이더리움 네트워크의 근본적인 확장성 문제에 대한 구체적이고 실용적인 해결책을 제공함으로써 암호경제와 현실경제의 갭을 줄이고 있습니다. 토카막 네트워크는 이더리움의 기술적 한계를 넘어 다양한 애플리케이션과 서비스를 지원함으로써 블록체인 기술의 대중화와 사회적, 경제적 변화를 촉진할 것으로 기대됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8. 참고문헌&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jeong, K., &amp;amp; Park, W. 토카막 레이어 2 암호경제 [Tokamak layer 2 crypto-economics]. Tokamak Network&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Poon, J., &amp;amp; Buterin, V. Plasma: Scalable Autonomous Smart Contracts&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이명숙&amp;amp;김기주.(2023).블록체인 기술의 적용과 미래방향. 실천공학교육논문지,133-142&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gopax.(2023,11,6). 이더리움 플라즈마(Plasma) 톺아보기. &lt;a href=&quot;https://academy.gopax.co.kr/ideorium-peulrajeuma-plasma-topabogi/&quot;&gt;https://academy.gopax.co.kr/ideorium-peulrajeuma-plasma-topabogi/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공현철. (2018,4,26). 블록체인 확장성 솔루션 시리즈 2-1 :: Plasma Overview. &lt;a href=&quot;https://medium.com/decipher-media/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%ED%99%95%EC%9E%A5%EC%84%B1-%EC%86%94%EB%A3%A8%EC%85%98-%EC%8B%9C%EB%A6%AC%EC%A6%88-2-1-plasma-overview-7e6875f4c20d&quot;&gt;https://medium.com/decipher-media/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%ED%99%95%EC%9E%A5%EC%84%B1-%EC%86%94%EB%A3%A8%EC%85%98-%EC%8B%9C%EB%A6%AC%EC%A6%88-2-1-plasma-overview-7e6875f4c20d&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vitalik. (2023,11,14). Exit games for EVM validiums: the return of Plasma. &lt;a href=&quot;https://vitalik.eth.limo/general/2023/11/14/neoplasma.html?ref=academy.gopax.co.kr&quot;&gt;https://vitalik.eth.limo/general/2023/11/14/neoplasma.html?ref=academy.gopax.co.kr&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시넷. (2021,8,28). 플라즈마 알고리즘. &lt;a href=&quot;http://wiki.hash.kr/index.php/%ED%94%8C%EB%9D%BC%EC%A6%88%EB%A7%88_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98&quot;&gt;http://wiki.hash.kr/index.php/%ED%94%8C%EB%9D%BC%EC%A6%88%EB%A7%88_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시넷. (2022,5,27). ㈜온더. &lt;a href=&quot;http://wiki.hash.kr/index.php/%E3%88%9C%EC%98%A8%EB%8D%94&quot;&gt;http://wiki.hash.kr/index.php/%E3%88%9C%EC%98%A8%EB%8D%94&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시넷. (2021,4,27).정순형. &lt;a href=&quot;http://wiki.hash.kr/index.php/%EC%A0%95%EC%88%9C%ED%98%95&quot;&gt;http://wiki.hash.kr/index.php/%EC%A0%95%EC%88%9C%ED%98%95&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시넷. (2022, 1, 12). 토카막 네트워크. &lt;a href=&quot;http://wiki.hash.kr/index.php/%ED%86%A0%EC%B9%B4%EB%A7%89_%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&quot;&gt;http://wiki.hash.kr/index.php/%ED%86%A0%EC%B9%B4%EB%A7%89_%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&lt;/a&gt;&lt;/p&gt;</description>
      <category>블록체인/논문</category>
      <author>jundev</author>
      <guid isPermaLink="true">https://junmonologue.tistory.com/29</guid>
      <comments>https://junmonologue.tistory.com/29#entry29comment</comments>
      <pubDate>Sun, 7 Jul 2024 00:39:47 +0900</pubDate>
    </item>
  </channel>
</rss>