<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2001/Atom">
  <channel>
    <title>Shaan Blog</title>
    <description>blog of software develop and business log  문제 해결을 위한 수단을 연구하며 기록합니다</description>
    <link>https://blog.sciencebro.kr/</link>
    <atom:link href="https://blog.sciencebro.kr/rss.xml" rel="self" type="application/rss+xml" />
    <pubDate>Sun, 21 Jun 2026 19:57:13 +0900</pubDate>
    <lastBuildDate>Sun, 21 Jun 2026 19:57:13 +0900</lastBuildDate>
    
    <item>
      <title>쿠버네티스 서비스의 외부 노출</title>
      <description>&lt;h2 id=&quot;클러스터-구성&quot;&gt;클러스터 구성&lt;/h2&gt;

&lt;p&gt;클러스터는 쿠버네티스 환경을 구성하는 네트워크 중 가장 큰 단위를 말한다.&lt;/p&gt;

&lt;p&gt;노드라고 부르는 개별 서버들의 합집합이 클러스터(K8s pool)이며, 쿠버네티스 안에서 실행되는 각 Pod의 자원 총량은 클러스터 자원을 넘을 수 없다.&lt;/p&gt;

&lt;p&gt;클러스터는 여러 노드를 연결해 하나의 네트워크를 형성하며, 논리적으로 로컬 네트워크와 같이 각 Pod가 소통할 수 있도록 한다.&lt;/p&gt;

&lt;p&gt;예) Service(서비스, svc)라는 개념으로 묶인 Pod 간에 통신할 때, 외부 네트워크라면 고유한 IP 또는 도메인을 이용해 호출해야 하는 과정을 K8s 네트워크 안의 고유한 Service 이름으로 호출할 수 있다.&lt;/p&gt;

&lt;h3 id=&quot;pod&quot;&gt;Pod&lt;/h3&gt;

&lt;p&gt;Pod는 K8s 안에서 사용하는 가상 환경 단위이다.&lt;/p&gt;

&lt;p&gt;하나의 Pod 당 하나의 가상환경을 가지고, 이미지를 실행한다.&lt;/p&gt;

&lt;p&gt;이미지는 docker에서도 사용하는데, 사전 구성된 실행 명령어와 실행 파일을 가진 채 배포할 수 있는 파일을 말한다.&lt;/p&gt;

&lt;p&gt;개별 Pod는 고유한 ID를 가지고 클러스터 안에서 실행된다. &lt;em&gt;{svc name}-{Pod ID}&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;svc&quot;&gt;svc&lt;/h3&gt;

&lt;p&gt;svc는 여러 개의 Pod를 하나의 단위로 묶어 사용할 수 있도록 하는 개념적 집합체다.&lt;/p&gt;

&lt;p&gt;svc는 같은 목적으로 실행된 여러 Pod를 논리적으로 포함하며, svc 이름으로 수신된 요청을 하위 Pod들이 자원을 효율적으로 사용할 수 있도록 로드밸런싱 한다.&lt;/p&gt;

&lt;h2 id=&quot;노드-ip와-클러스터-ip&quot;&gt;노드 IP와 클러스터 IP&lt;/h2&gt;

&lt;p&gt;노드 IP는 각 하드웨어가 가지는 외부 IP를 말한다.&lt;/p&gt;

&lt;p&gt;다만 K8s 안에서 각 하드웨어 서버를 &lt;strong&gt;노드&lt;/strong&gt;라고 부르기 때문에 노드 IP라는 이름으로 표현한다.&lt;/p&gt;

&lt;p&gt;Cluster IP는 K8s 네트워크 내의 svc가 가지는 고유한 가상 IP를 말한다.&lt;/p&gt;

&lt;p&gt;이 IP는 노드 IP와는 다르고, 클러스터 내부 자원에 접속하기 위해서 사용한다.&lt;/p&gt;

&lt;p&gt;노드 IP만으로는 별도의 포트포워딩 없이 클러스터 내부 자원에 접속할 수 없다.&lt;/p&gt;

&lt;h2 id=&quot;클러스터-내부로-요청-전달&quot;&gt;클러스터 내부로 요청 전달&lt;/h2&gt;

&lt;p&gt;클러스터 내부 자원인 svc 호출을 위해서는 클러스터 IP를 이용한 호출이 필요하다.&lt;/p&gt;

&lt;p&gt;다만, 클러스터 IP는 외부 IP가 아니기 때문에 로컬 네트워크가 아닌 환경에서 호출할 때 제약이 생긴다.&lt;/p&gt;

&lt;p&gt;이 문제를 해결하기 위해서 외부 IP를 가진 노드를 이용해 요청을 수신하고, 클러스터로 전달하는 과정이 필요하다.&lt;/p&gt;

&lt;p&gt;아래 설명되는 iptables를 이용해 노드로 수신된 요청을 클러스터로 전달하게 되는데, PREROUTING 과정을 통해 요청의 목적지가 클러스터 내부 Pod IP로 변환된다.&lt;/p&gt;

&lt;p&gt;PREROUTING 과정에서 요청의 목적지가 변환되면, iptables의 FORWARD 과정을 거쳐 Pod로 요청이 전달된다.&lt;/p&gt;

&lt;h3 id=&quot;iptables&quot;&gt;iptables&lt;/h3&gt;

&lt;p&gt;iptables는 커널 수준에서 사전 정의된 IP로 보내거나 받는 요청을 조율할 수 있다.&lt;/p&gt;

&lt;p&gt;iptables는 규칙을 저장해 어떤 IP를 목적지로 하는 요청에 어떤 조율을 할지 정의하며, 실제 요청을 가공하는 작업은 netfilter가 수행한다.&lt;/p&gt;

&lt;p&gt;iptables로 지정할 수 있는 규칙은 &lt;strong&gt;[ACCEPT, DROP, REJECT, LOG]&lt;/strong&gt; 등이 있으며, 규칙을 적용하는 대상을 구분하는 종류는 &lt;strong&gt;[PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING]&lt;/strong&gt;, 작업을 구분하는 종류는 &lt;strong&gt;[filter, nat, mangle, raw]&lt;/strong&gt; 이 있다.&lt;/p&gt;

&lt;p&gt;iptables 규칙과 별개로, INPUT 단계에서 호스트로 전달된 요청의 port를 호스트가 허용하지 않는 경우 요청은 거절된다.&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ACCEPT : 패킷 통과 허용, 요청에 대한 응답 정상 반환
DROP : 패킷 폐기, 송신 클라이언트는 폐기 사실을 모른 채 응답을 대기하게 됨
REJECT : 패킷 거부, 송신 클라이언트는 거부 사실을 반환받음
LOG : 패킷 기록, 별도의 작업 없이 해당 패킷을 syslog에 기록함

PREROUTING : 네트워크 도착 즉시 실행됨, 목적지 주소를 바꾸는 용도로 사용
INPUT : 최종 목적지가 현재 서버인 경우 실행됨, 응답을 변환하거나 송신 클라이언트 필터 등에 사용
FORWARD : 목적지가 현재 서버가 아니며 다른 서버로 전달되는 경우 실행됨, 서버를 거치는 요청을 기록하는 용도에 사용
OUTPUT : 현재 서버에서 바깥 네트워크로 송신되는 요청에 실행됨, IP 블랙리스트 호출을 거절하거나 요청 전송 전 정보를 변환하는 용도에 사용
POSTROUTING : 네트워크 작업이 완료된 후 반환되는 시점에 실행됨, 응답 정보 변환하는 용도에 사용

filter : 패킷 허용, 거부, 폐기 등을 결정
nat : IP, 포트 주소 변환
mangle : 패킷 헤더의 정보 변환
raw : 별다른 작업이 없는 순수 요청
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;iptables로 처리되는 요청은 아래와 같은 순서를 거친다.&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;외부 -&amp;gt; 내부
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; raw(PREROUTING) -&amp;gt; mangle(PREROUTING) -&amp;gt; nat(PREROUTING)
  a. mangle(INPUT) -&amp;gt; filter(INPUT) : 현재 서버가 목적지인 경우
  b. mangle(FORWARD) -&amp;gt; filter(FORWARD) -&amp;gt; mangle(POSTROUTING) -&amp;gt; nat(POSTROUTING) : 서버를 거쳐 다른 목적지로 전송하는 경우

내부 -&amp;gt; 외부
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; raw(OUTPUT) -&amp;gt; mangle(OUTPUT) -&amp;gt; nat(OUTPUT) -&amp;gt; filter(OUTPUT) -&amp;gt; mangle(POSTROUTING) -&amp;gt; nat(POSTROUTING)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
      <pubDate>Sun, 21 Jun 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/k8s-packet-jumping-with-iptables/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/k8s-packet-jumping-with-iptables/</guid>
    </item>
    
    <item>
      <title>현대적인 업무 방식</title>
      <description>&lt;h2 id=&quot;산업혁명-시대의-근로&quot;&gt;산업혁명 시대의 근로&lt;/h2&gt;

&lt;p&gt;산업혁명 시대에는 물품들이 공장에서 제조되기 시작하며 생산 속도와 생산량에 큰 변화가 나타났다.&lt;/p&gt;

&lt;p&gt;공장에서 생산되는 물품들은 일정한 공장 가동 주기에 맞춰 작업자가 재료를 투입하거나 완성품을 출하하는 등 기계와 수많은 사람들의 유기적 협력이 필요했다.&lt;/p&gt;

&lt;p&gt;이러한 협업 방식이 고정된 시간제 형태로 굳어지며 9시 출근, 6시 퇴근 방식인 &lt;strong&gt;‘9to6’&lt;/strong&gt; 가 업무 방식으로 이어져 내려오고 있다.&lt;/p&gt;

&lt;h2 id=&quot;현대의-근로&quot;&gt;현대의 근로&lt;/h2&gt;

&lt;p&gt;현대에 들어서며, 공장에서의 직접적인 생산 근로는 기계의 빠른 발전으로 점차 줄어드는 동시에 기계를 관리하는 의사결정 및 업무 조율을 위한 사무 인력이 늘고 있다.&lt;/p&gt;

&lt;p&gt;기계와 사람의 동시 협력이 줄어가는 지금, 왜 우리는 아직 이전의 업무 방식인 9to6를 유지하고 있는 걸까?&lt;/p&gt;

&lt;h3 id=&quot;관리-집단의-관성&quot;&gt;관리 집단의 관성&lt;/h3&gt;

&lt;p&gt;현대의 디지털 환경을 어릴 때부터 접하며 자라온 젊은 세대와 달리 공장 생산을 경험한 기성세대는 처음 접한 업무 방식이 9to6이며, 오랜 기간 이 방식에 익숙해져 왔다.&lt;/p&gt;

&lt;p&gt;이전의 업무 방식에 익숙한 기성세대가 경력이 쌓여 현재 사무 관리직 또는 경영 책임자로서 이전 규칙을 선호하고 유지하려 한다.&lt;/p&gt;

&lt;p&gt;이러한 현실적 제약 때문에 우리는 아직 9to6 방식을 주요한 업무 방식으로 이용한다.&lt;/p&gt;

&lt;h3 id=&quot;협업-구조의-제약&quot;&gt;협업 구조의 제약&lt;/h3&gt;

&lt;p&gt;9to6가 아닌 10to7, 8to5 등 시차 출근을 채택하는 업무 방식도 존재한다.&lt;/p&gt;

&lt;p&gt;다만 이 경우에도 앞뒤 몇 시간을 변동적으로 이용할 뿐, 오후 1시부터 오후 10시까지 근무하는 등 업무 시간의 대폭 변경을 찾기 어렵다.&lt;/p&gt;

&lt;p&gt;기존 근무 시간에서 크게 변화를 만들기 어려운 이유는 다른 집단의 근무 시간에 맞춰 소통해야 하기 때문이다.&lt;/p&gt;

&lt;p&gt;본인이 오후 1시에 근무를 시작하더라도 거래처는 이미 오전부터 근무를 시작해 각종 안건에 대해 결정을 내리고, 오전 중 회신을 기대한다.&lt;/p&gt;

&lt;p&gt;이미 거래처의 결정이 오전에 끝난 상황에서 오후에 출근한 본인은 의사결정 과정에 의견 반영을 기대하기 어렵고, 협업 속도가 느려져 생긴 손해를 감수하게 될 수도 있다.&lt;/p&gt;

&lt;p&gt;업무 시간의 변동으로 감수해야 하는 불이익으로 인해 기업의 목적 달성이 늦어지거나 어려워지기 때문에 &lt;strong&gt;‘9to6’&lt;/strong&gt; 는 강력한 표준 근로 환경으로 작동하고 있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;우리는 현대 사회의 유연한 소통 방식과 네트워크를 이용해 자율적인 업무 환경을 기대한다.&lt;/p&gt;

&lt;p&gt;하지만 업무를 위해 소통하는 다른 집단과의 원활한 교류를 위해서 업무 환경 타협이 필요하다.&lt;/p&gt;

&lt;p&gt;결국 9to6라는 구조는 산업혁명 시대에 고정되어 사회적 타협으로 작동하며 지금까지 이어지고 있다.&lt;/p&gt;
</description>
      <pubDate>Tue, 26 May 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/lifestyle/modern-office-type/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/lifestyle/modern-office-type/</guid>
    </item>
    
    <item>
      <title>직업의 변화, 정보 우위</title>
      <description>&lt;h2 id=&quot;기술과-문화의-발전에-따라-직업도-변해왔다&quot;&gt;기술과 문화의 발전에 따라 직업도 변해왔다&lt;/h2&gt;

&lt;p&gt;과거에는 시간에 맞춰 첨탑의 종을 울려 마을 전체가 공통적인 생활을 할 수 있도록 돕는 직업이 존재했다.&lt;/p&gt;

&lt;p&gt;이 직업은 기계의 발전과 동력 기관 비용이 저렴해짐에 따라 더 정확하고 편리한 기계식 알림 방식이 확산되며, 현재는 일부의 이벤트성 문화로 남아 종사하는 사람이 매우 적어졌다.&lt;/p&gt;

&lt;p&gt;우리는 앞으로 발전하는 기술로 인해 어떤 변화를 맞이하게 될지 고민해 직업을 선택해야 한다.&lt;/p&gt;

&lt;h3 id=&quot;육체-노동과-지식-노동&quot;&gt;육체 노동과 지식 노동&lt;/h3&gt;

&lt;p&gt;직업은 특정 노동에 종사하는 사람들의 유형을 분류하여 “업”이라는 기준으로 표현한 방식을 말한다.&lt;/p&gt;

&lt;p&gt;노동의 종류에는 &lt;strong&gt;육체 노동&lt;/strong&gt;과 &lt;strong&gt;지식 노동&lt;/strong&gt;이 존재한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&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;ul&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;/ul&gt;

&lt;p&gt;우리 사회는 과거 육체 노동이 주요한 문화에서, 정보통신의 발전으로 점차 지식 노동이 주요한 문화로 변화했다.&lt;/p&gt;

&lt;p&gt;하지만 최근 인공지능의 발전으로 과거 지식 노동의 많은 부분이 사람에서 기계로 대체되고 있다.&lt;/p&gt;

&lt;p&gt;이에 대해 매체에서는 육체 노동으로 직업을 전환하는 사례를 부각하고 있는데, 이는 지식 노동과 인공지능을 이해하지 못함으로 인해 생기는 일부 사례의 과대 해석이다.&lt;/p&gt;

&lt;h3 id=&quot;인공지능의-작업-방식&quot;&gt;인공지능의 작업 방식&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;인공지능은 과거의 지식 노동 산물을 이용한 도구&lt;/strong&gt;이다.&lt;/p&gt;

&lt;p&gt;인공지능은 과거 기록을 분석해 통계적 패턴을 찾아 &lt;strong&gt;같은 유형의 작업&lt;/strong&gt;을 효율화하고, 기록 간의 연관성을 표현한 정보를 이용해 새로운 정보가 연관된 기록을 &lt;strong&gt;확률적&lt;/strong&gt;으로 찾아내는 작업을 수행한다.&lt;/p&gt;

&lt;p&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;/p&gt;

&lt;p&gt;반면, 사람의 작업 방식은 인공지능과 다른 점이 존재한다.&lt;/p&gt;

&lt;p&gt;사람의 학습 및 일상을 통해 다른 정보를 받아들여 주관적인 표현으로 재구성하는 과정이 유사하지만, 사람은 &lt;strong&gt;무모한 도전&lt;/strong&gt;으로 보이는 새로운 시도로 자신의 주관적 가치로부터 &lt;strong&gt;고찰&lt;/strong&gt;을 통해 새로운 기록을 만들 수 있다.&lt;/p&gt;

&lt;p&gt;이전 기록으로부터 연관성이 없는 여러 정보를 조합해 통계적으로 무의미해 보이는 작업에 도전하여 새로운 기록을 만들어낼 수 있다는 점이 인공지능이 대체할 수 없는 사람의 지식 노동 영역이다.&lt;/p&gt;

&lt;h3 id=&quot;인공지능으로-대체되어-사람이-가지지-않게-될-직업&quot;&gt;인공지능으로 대체되어 사람이 가지지 않게 될 직업&lt;/h3&gt;

&lt;p&gt;인공지능이 사람보다 효율적인 직업으로 현대 사회에서 선호되는 &lt;strong&gt;기업 사무&lt;/strong&gt; 직업이 있다.&lt;/p&gt;

&lt;p&gt;기업 사무에서는 전형적인 &lt;strong&gt;Bottom-up&lt;/strong&gt; 방식으로 정보를 조합하고, 정리하여 보고하는 방식이 작업량의 대부분을 차지한다.&lt;/p&gt;

&lt;p&gt;이 작업은 주관적 판단보다는 사실의 전달으로 현상을 효율적으로 판단하는 것이 주요하기에 사람보다 많은 정보를 빠르게 조합하고 표현할 수 있는 인공지능이 효율적이다.&lt;/p&gt;

&lt;p&gt;서로 다른 기업의 사무에 대해 조율이 필요한 경우에도, 합리적 결과 도출을 위한 정보 수집 과정은 인공지능이 효율적이다.&lt;/p&gt;

&lt;p&gt;사람은 인공지능이 수집한 정보를 이용한 제안 작성, 결과에 대한 의사 집행을 수행하는 작업에 강점을 가진다.&lt;/p&gt;

&lt;p&gt;이성적으로는 인공지능이 도출한 결과가 바로 집행되어야 효율적이지만, 기업 간 사무에 앞서 사람 간의 일에서는 &lt;strong&gt;관계&lt;/strong&gt;가 존재하기에 관계의 성격에 따라 제안과 합의 과정이 달라지기 때문이다.&lt;/p&gt;

&lt;h3 id=&quot;사람에게-필요한-도구&quot;&gt;사람에게 필요한 도구&lt;/h3&gt;

&lt;p&gt;앞선 내용대로 사람이 새로운 기록을 만들어내는 영역에서 직업을 가지는 경우에는 새로운 기록을 효율적으로 표현하고, 기록을 보호하는 도구가 필요해진다.&lt;/p&gt;

&lt;p&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;/p&gt;

&lt;p&gt;미래에는 정보 우위가 따라잡을 수 없는 효율성의 차이를 만들어내 사회적 지위, 부의 기준으로 표현될 것이다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;나는 미래 직업에서 필수적인 도구이자 범용 정보의 질을 높이기 위한 플랫폼을 만들고 있다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STRIGIFIC&lt;/strong&gt;, 개인이 창출한 기록 소유를 증명하는 동시에 외부와 격리된 환경에서 인공지능을 활용할 수 있도록 한다.&lt;/p&gt;

&lt;p&gt;개인의 영감으로 고찰을 이어가 관철한 정보에 대해서는 플랫폼 내의 범용 기록으로 공개하여 내부의 지위를 확보하고, 기록 공유를 통한 새로운 영감의 촉매로 이용되도록 한다.&lt;/p&gt;

&lt;p&gt;추후 아래 도메인을 통해 서비스를 제공할 예정이다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://strigific.com&quot;&gt;STRIGIFIC 정보 소유 플랫폼&lt;/a&gt;&lt;/p&gt;
</description>
      <pubDate>Thu, 07 May 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/lifestyle/define-job-about-human/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/lifestyle/define-job-about-human/</guid>
    </item>
    
    <item>
      <title>이더리움의 계정 추상화, 네이티브 계정 추상화</title>
      <description>&lt;h2 id=&quot;계정-추상화&quot;&gt;계정 추상화&lt;/h2&gt;

&lt;p&gt;계정 추상화는 프로그래밍 함수를 포괄적으로 사용할 수 있도록 기능을 일반화할 때 사용하는 &lt;strong&gt;추상화&lt;/strong&gt;와 같은 의미로 계정을 변환하는 방식을 말한다.&lt;/p&gt;

&lt;p&gt;추상 계정은 특정 목적으로 사전 정의되어 있는 기능 외에 상황에 따라 요구하는 추가 기능을 사용할 수 있는 유연한 기능 범위를 가지게 되어 &lt;strong&gt;프로그래밍 가능한 계정&lt;/strong&gt;으로 변화한다.&lt;/p&gt;

&lt;p&gt;예를 들면, 자산의 보관 및 전송을 위한 개인 지갑 계정을 추상화하는 경우 기존에 염두에 두지 않은 NFT 발행 기능을 사용하기 위해 새로운 외부 함수를 호출하는 등의 변화가 가능해진다.&lt;/p&gt;

&lt;h3 id=&quot;모듈식-계정&quot;&gt;모듈식 계정&lt;/h3&gt;

&lt;p&gt;모듈식 계정은 위에서 설명한 새로운 기능 추가를 편리하게 수행할 수 있도록 기능 단위를 모듈화하여 배포한 외부 컨트랙트를 사용하는 방식을 말한다.&lt;/p&gt;

&lt;p&gt;모듈식 계정에서 계정 본체는 최소한의 계정 기능만을 가진 OS를 배포하고, 그 외의 계정 기능은 모두 외부 컨트랙트에 배포 후 계정에서 호출 권한을 부여하는 트랜잭션에 서명하여 사용한다.&lt;/p&gt;

&lt;p&gt;프로그래밍 시 npm, pip 과 같은 라이브러리 사용을 생각할 수 있다. 라이브러리 설치 도구에 명령어를 입력해 해당 라이브러리를 프로젝트에서 사용하도록 설정하고, 프로젝트에서 라이브러리 기능 사용을 위해 바로 호출할 수 있는 것처럼 모듈식 계정 역시 외부 기능 설치 후 호출 방식을 이용한다.&lt;/p&gt;

&lt;h3 id=&quot;양자-내성-암호-사용을-위한-계정-추상화&quot;&gt;양자 내성 암호 사용을 위한 계정 추상화&lt;/h3&gt;

&lt;p&gt;최근 양자컴퓨터의 상용화 가능성을 두고 많은 주제가 화두에 오르고 있다.&lt;/p&gt;

&lt;p&gt;블록체인 서명 체계의 양자 공격 취약성을 경고하며 빠른 대처를 요구하는 의견도 매우 활발하게 논의되고 있는데, 현재 이더리움 네트워크 및 계정 추상화를 지원하는 네트워크는 상대적으로 양자 공격에 대한 대비가 많이 진행되었다고 볼 수 있다.&lt;/p&gt;

&lt;p&gt;계정 추상화를 지원하지 않는 네트워크의 경우에는 서명 검증 기능에서 양자 내성 암호를 사용하기 위해 네트워크 전체를 변경하는 &lt;strong&gt;하드포크&lt;/strong&gt;가 필수적이며, 그 과정에서 네트워크 내부 계정들은 새로운 기능 사용을 위해 주소가 다른 새로운 계정으로 자산을 이전하는 등의 방식이 필요하다.&lt;/p&gt;

&lt;p&gt;하지만, 계정 추상화를 지원하는 경우에는 네트워크 수준에서 &lt;strong&gt;양자 내성 암호 검증 알고리즘 모듈&lt;/strong&gt;을 추가하는 상대적으로 작은 업데이트와 각 계정의 자율적인 기능 수정으로 양자 내성을 갖출 수 있다는 점에서 양자공격이 일부 대비가 진행중이다.&lt;/p&gt;

&lt;p&gt;계정 추상화는 이런 대규모 변화에 대해서도 유연하게 대처 가능한 선택지를 제공하며, 네트워크의 업데이트와 별개로 각 계정의 자율적인 모듈 사용으로 기능을 추가할 수 있다는 점이 특징이다.&lt;/p&gt;

&lt;h3 id=&quot;추상-레이어의-구분&quot;&gt;추상 레이어의 구분&lt;/h3&gt;

&lt;p&gt;계정 추상화 방식에 대해서 네트워크 내부의 추상화 지원, 외부 컨트랙트의 추상화 지원으로 구분할 수 있다.&lt;/p&gt;

&lt;h4 id=&quot;플러그인-추상화&quot;&gt;플러그인 추상화&lt;/h4&gt;

&lt;p&gt;EIP-4337을 이용한 UserOp, EntryPoint를 이용한 계정 추상화를 플러그인 추상화라고 표현한다.&lt;/p&gt;

&lt;p&gt;EIP-4337은 계정 외부 컨트랙트가 계정을 관리할 수 있는 &lt;strong&gt;스마트 컨트랙트&lt;/strong&gt; 기능을 추가하는 제안이다.&lt;/p&gt;

&lt;p&gt;이 방식은 외부 컨트랙트가 제출된 UserOp를 EntryPoint라는 신뢰되는 컨트랙트에 전달하여 트랜잭션 실행을 의뢰하는 방식으로 작동한다.&lt;/p&gt;

&lt;p&gt;블록체인 네트워크 내부에서는 데이터의 저장, 컨트랙트 간의 소통에 발생하는 비용을 &lt;strong&gt;가스비&lt;/strong&gt;라고 지칭하는데 위의 EntryPoint와의 소통에서 가스비가 발생하여 추상 과정이 없는 단순 트랜잭션에 비해 비용이 높다.&lt;/p&gt;

&lt;h4 id=&quot;네이티브-추상화&quot;&gt;네이티브 추상화&lt;/h4&gt;

&lt;p&gt;EIP-8141의 프레임 트랜잭션을 이용한 네트워크 빌더 수준에서의 계정 추상화를 네이티브 추상화라고 표현한다.&lt;/p&gt;

&lt;p&gt;EIP-8141은 네트워크 빌더 수준에서 &lt;strong&gt;Frame&lt;/strong&gt; 단위 동작을 수행 기능을 추가하는 제안이다.&lt;/p&gt;

&lt;p&gt;이 방식은 네트워크 내부 엔진에서 동작을 단위별로 구분하고, 실행하기 때문에 외부 컨트랙트와의 소통 없이 실행되어 트랜잭션 비용이 저렴하다.&lt;/p&gt;

&lt;p&gt;Frame을 이용한 추상화로 UserOp로는 여러 개의 요청으로 분리되어야 하는 동작을 하나의 요청으로 수행할 수 있게 되었다.&lt;/p&gt;

&lt;p&gt;UserOp는 내부에 동작을 위한 CallData가 하나 포함되어 전달되기에 하나의 UserOp 당 하나의 동작을 수행하여 복잡한 동작을 수행하기 위해서는 여러 개의 UserOp를 이용해야 하는 점에서 높은 비용을 요구한다.&lt;/p&gt;

&lt;p&gt;Frame은 내부에 배열 형태로 여러 동작을 순차적으로 요청할 수 있어 순서 관계를 통한 복잡한 동작을 수행하기에 유리하다.&lt;/p&gt;

&lt;h2 id=&quot;eip-8141&quot;&gt;EIP-8141&lt;/h2&gt;

&lt;p&gt;EIP-8141 프레임 트랜잭션은 &lt;strong&gt;프레임 모드에 따른 권한 분리&lt;/strong&gt;가 특징이다.&lt;/p&gt;

&lt;p&gt;프레임 모드는 &lt;strong&gt;[VERIFY, DEFAULT, SENDER]&lt;/strong&gt; 가 존재한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;VERIFY : 트랜잭션의 서명 및 진위 여부를 검증하는 프레임 모드를 의미한다. 이 모드의 프레임이 실패하거나 반려되는 경우 트랜잭션 실행 권한이 없다는 의미가 되어 트랜잭션이 무효 처리된다. (블록이 생성되지 않고 노드에서 무효 처리)&lt;/li&gt;
  &lt;li&gt;DEFAULT : 트랜잭션에서 수행하는 상태 변경 로직이나 외부 컨트랙트와의 소통 로직을 포함하는 프레임 모드를 의미한다. 이 프레임이 실패하거나 반려되는 경우 실행 단위의 실패를 의미하며 이후 프레임을 수행하지 않고, 트랜잭션이 실패가 된다. (블록이 생성되어 실패 이력 기록)&lt;/li&gt;
  &lt;li&gt;SENDER : 트랜잭션을 수행하는 계정의 자산에 관여하는 프레임 모드를 의미한다. 이 모드의 프레임은 자산의 전송 관련 로직을 포함하며, VERIFY 모드에서 sender_approved 상태를 반환하는 경우에만 실행 가능하다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;각 프레임은 트랜잭션 내부에 배열의 요소로 입력되고, 배열 순서에 따라 index 0 부터 순차적으로 실행된다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;블록체인 생태계는 양자컴퓨터라는 새로운 기술에 대응하기 위해 사용자의 자율성을 확대하며, 자연스러운 데이터 이전이 가능한 &lt;strong&gt;계정 추상화&lt;/strong&gt;를 진행하고 있다.&lt;/p&gt;

&lt;p&gt;네트워크마다 채택하는 양자 내성 대응 방식이 다양하지만, 이미 네트워크 활성 유저가 많은 대규모 프로젝트에서는 계정 추상화를 이용한 검증 방식 변경이 우세하며 이외의 네트워크에서는 설계 단계부터 양자 내성을 염두에 둔 경우도 존재한다.&lt;/p&gt;

&lt;p&gt;양자컴퓨터로 인해 블록체인이 무력화된다는 의견과는 달리 양자컴퓨터 개발 분야에서의 정보 공유를 통해 보안을 강화하는 방향으로 생태계가 발전하고 있으므로 고전적인 네트워크 시스템보다 안전하다.&lt;/p&gt;
</description>
      <pubDate>Wed, 22 Apr 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/ethereum-native-acount-abstract/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/ethereum-native-acount-abstract/</guid>
    </item>
    
    <item>
      <title>기록의 중요성과 유의미한 기록</title>
      <description>&lt;p&gt;인간은 이전의 기록을 보고, 간접 경험을 통해 다음 세대가 발전하는 과정을 거쳐왔다.&lt;/p&gt;

&lt;p&gt;기록은 현재의 가치를 정리해 미래로 전달하는 방법이다.&lt;/p&gt;

&lt;h2 id=&quot;기록의-중요성&quot;&gt;기록의 중요성&lt;/h2&gt;

&lt;p&gt;우리는 다른 사람에게 정보를 전달하기 위해 기록하는 경우가 많다.&lt;/p&gt;

&lt;p&gt;{보고서, 제안서, 편지, 채팅, 논문, 블로그} 등의 형식을 띠는 기록이 다른 사람에게 정보를 전달하는 목적이다.&lt;/p&gt;

&lt;p&gt;스스로 생각을 정리하거나 잊지 않기 위해 기록하는 경우도 있다.&lt;/p&gt;

&lt;p&gt;{일기, 브레인스토밍, 필기} 등의 형식을 띠는 기록이 스스로를 위해 정보를 정리하는 목적이다.&lt;/p&gt;

&lt;p&gt;최근에는 생성형 인공지능의 발달로 위의 두 기록 간 형식 구분이 크게 의미가 없어졌다.&lt;/p&gt;

&lt;p&gt;스스로 정보를 정리한 필기를 인공지능을 이용해 보고서 형태로 재구성하는 일이 매우 쉬워졌고, 반대로 복잡한 전문용어를 이용한 논문을 내가 이해하기 쉽게 구어체로 재구성하는 일도 가능하다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;기록을-다루는-방식의-변화&quot;&gt;기록을 다루는 방식의 변화&lt;/h2&gt;

&lt;p&gt;이전 세대에서 역량이 뛰어난 사무 인력은 기록을 &lt;strong&gt;보기 편하게&lt;/strong&gt; 작성하는 사람을 말했다.&lt;/p&gt;

&lt;p&gt;퍼져있는 기록을 인용하여 하나의 매체로 정리하고, 기록을 직관적인 시각자료로 표현하는 일은 과거 사무 업무의 큰 부분을 차지했다.&lt;/p&gt;

&lt;p&gt;현재는 사무 인력의 보고서 작성 능력이 이전에 비해 덜 중요해졌다.&lt;/p&gt;

&lt;p&gt;같은 사람이 작성해도 때에 따라 달라지는 단어 선택과 문맥과 달리, 정규 양식을 사전 학습한 인공지능은 항상 일정한 수준의 결과물을 기대할 수 있기 때문이다.&lt;/p&gt;

&lt;p&gt;이 시점에서 우리는 &lt;strong&gt;어떤 기록이 중요하며, 어떻게 기록해야 의미를 전달할 수 있는지&lt;/strong&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;strong&gt;사람은 기록을 찾는 일이 아닌, 새로운 기록을 만들어내는 능력이 인공지능에 비해 효율적&lt;/strong&gt;이다.&lt;/p&gt;

&lt;p&gt;새로운 기록은 이전의 파편 정보를 하나로 엮어내는 일을 뜻하지 않는다.&lt;/p&gt;

&lt;p&gt;새로운 기록은 개인이 보유한 고유의 발상을 이용해 기존 기록으로부터 파생한 것을 의미한다.&lt;/p&gt;

&lt;p&gt;사람은 인공지능이나 다른 방법을 이용해 정리한 기록으로부터 &lt;strong&gt;새로운 사실을 밝혀내기 위해 고민하는 방식으로 기록을 다뤄야 한다.&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;새로운-기록을-위한-기록-방법&quot;&gt;새로운 기록을 위한 기록 방법&lt;/h2&gt;

&lt;p&gt;기존 기록을 바탕으로 새로운 사실을 밝혀내는 활동을 위해서는 &lt;strong&gt;유의미한 기록&lt;/strong&gt;들을 쉽게 모아보고, 골라내는 작업이 중요하다.&lt;/p&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;개인의 의견을 담은 것&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;기록의 초점이 명확하더라도 의견을 포함하지 않은 것은 유의미한 기록이라기보다는 &lt;strong&gt;사실&lt;/strong&gt;이나 &lt;strong&gt;관찰 결과&lt;/strong&gt;에 가깝다.&lt;/p&gt;

&lt;p&gt;우리는 사실과 관찰을 바탕으로 새로운 가능성을 찾아 정리한 &lt;strong&gt;유의미한 기록&lt;/strong&gt;을 해야 한다.&lt;/p&gt;

&lt;p&gt;초점이 명확하고 의견을 포함한 기록을 다시 확인하기 위해서 &lt;strong&gt;분류&lt;/strong&gt;를 해야 한다.&lt;/p&gt;

&lt;p&gt;분류 방법은 아래 내용에 부합하는 태그를 이용하는 것을 추천한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;핵심 주제&lt;/strong&gt; : 기록이 다루는 사실과 관찰 결과에 대한 정보&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;발상 방법&lt;/strong&gt; : 정보를 어떻게 연결하고 해석하는지에 대한 정보&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;예를 들면 핵심 주제가 “데이터베이스 설계” 라면 바탕이 되는 사실은 데이터베이스의 종류와 특징, 저장 가능한 형태 등일 것이다.&lt;/p&gt;

&lt;p&gt;이에 대한 발상 방법은 “고차원 정보 저장을 위한 벡터 분리” 등이 될 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;{데이터베이스 설계, 고차원 정보 저장을 위한 벡터 분리}&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위의 두 정보를 조합해 내용을 유추하면, 고차원 벡터 정보를 저장하기 위한 데이터베이스 종류와 효율적인 용량 관리 및 조회를 위한 데이터 분리 방법이 있을 것이다.&lt;/p&gt;

&lt;p&gt;우리는 이런 정보를 만들어 기록하고, 미래의 자신 또는 타인이 같은 주제에 대해 더 빠르게 사실을 습득하고 더 깊은 고민을 할 수 있도록 해야 한다.&lt;/p&gt;

</description>
      <pubDate>Fri, 17 Apr 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/lifestyle/importance-of-history/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/lifestyle/importance-of-history/</guid>
    </item>
    
    <item>
      <title>이더리움 L2 네트워크의 운영 안정성</title>
      <description>&lt;h2 id=&quot;이더리움-layer-2-블록-증명-방식&quot;&gt;이더리움 Layer 2 블록 증명 방식&lt;/h2&gt;
&lt;p&gt;이더리움 Layer 2 네트워크는 각 목적에 따라 Optimistic, Validity 등의 블록 검증 방식을 이용한다. &lt;br /&gt;
이전에 소개한 zkSync Era는 Validity 검증 방식 중 boojum 이라는 증명 알고리즘을 이용하는 예시다. &lt;br /&gt;
이 글에서는 Layer 2 네트워크의 블록 증명 방식에 따른 운영 안정성을 고려하기 위한 내용을 다룬다. &lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;optimistic&quot;&gt;Optimistic&lt;/h3&gt;
&lt;p&gt;Optimistic 검증 방식은 &lt;strong&gt;낙관적 블록 생성&lt;/strong&gt;방식이다. &lt;br /&gt;
블록에 오류가 없을 것으로 추정하고, Layer 1으로 블록을 제출하여 약 7일간의 &lt;strong&gt;이의제기 기간&lt;/strong&gt;을 대기한 후 블록을 확정하는 방식이다. &lt;br /&gt;
이 방식은 별도의 블록 검증 없이 바로 Layer 1으로 제출하기에 네트워크 처리 연산량이 적다는 장점이 있지만, 블록 오류가 있는 경우 치명적인 네트워크 혼란이 생길 수 있다. &lt;br /&gt;
블록 오류가 &lt;strong&gt;이의제기 기간&lt;/strong&gt; 내에 발견되면 Optimistic 네트워크는 오류 블록의 등록을 취소하고, 해당 블록 기록자에 대한 페널티를 부여하는 방식으로 네트워크 신뢰를 확보한다. &lt;br /&gt;
오류 블록이 취소됨으로 인해서 해당 블록이 포함하는 트랜잭션 작업이 무효가 되는 것은 아니다. &lt;br /&gt;
초기 방식에서는 문제를 발견한 블록에 대해서 큰 비용이 필요하지만 신뢰도를 보장하는 Layer 1에서 다시 블록 내부 작업을 수행 후 정정된 블록을 기록하는 방식으로 오류를 해결했다. &lt;br /&gt;
최근에는 문제 블록 내부에서 오류의 원인이 되는 트랜잭션을 찾은 뒤 최소 실행 단위만 Layer 1에서 다시 실행 후 블록을 정정하는 방식도 이용되고 있다. &lt;br /&gt;
&lt;br /&gt;
Optimistic의 &lt;strong&gt;이의제기 기간&lt;/strong&gt; 방식으로 인해 DeFi 서비스 또는 실시간 확정이 필요한 서비스는 불편을 겪을 수 있다. &lt;br /&gt;
DeFi 서비스의 경우는 자금 인출이 블록 확정까지 지연되는 점, 실시간 확정이 필요한 서비스는 트랜잭션 실행 결과에 대한 신뢰를 보장할 수 없는 점이다. &lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;bold&quot;&gt;BoLD&lt;/h4&gt;
&lt;p&gt;악의적인 이의제기로 인해 블록 확정이 무한정 지연되는 문제를 해결하기 위해 검증자 중 올바른 검증을 제출하는 1건의 경우를 이용해서 다른 이의제기를 무효화하는 Optimistic 세부 알고리즘이다. &lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;opfp&quot;&gt;OPFP&lt;/h4&gt;
&lt;p&gt;내부적인 이더리움 가상 머신(EVM)을 이용한 검증 방식이다. 오류 발생 시 Layer 1에서 실행한 EVM을 이용해 블록을 다시 연산하고, 정정한다. &lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;op-kailua&quot;&gt;OP Kailua&lt;/h4&gt;
&lt;p&gt;블록의 오류 발생 시에만 영지식 증명(ZK)를 이용해 정정하는 방식이다. Optimistic의 빠른 Layer 1 제출의 강점을 이용하고, 블록 확정 지연시간을 줄이기 위해 ZK로 블록을 검증한다. &lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;validity&quot;&gt;Validity&lt;/h3&gt;
&lt;p&gt;Validity 방식은 각 블록에 대해 Layer 2에서 검증 후 Layer 1으로 제출하는 방식이다. &lt;br /&gt;
Layer 2 네트워크 내부에서 블록 검증 연산이 실행되기 때문에 네트워크 부담 연산량이 늘어나고, 검증 연산 후 Layer 1으로 블록이 제출되기 때문에 블록의 미확정 시간이 검증 대기열 상태에 따라 변동되는 점이 특징이다. &lt;br /&gt;
블록 검증을 위해 영지식 증명(ZK)를 이용해 각 작업 단위를 검증하는 것이 기본 방식이다. &lt;br /&gt;
ZK는 연산 방식에 따라 SNARK, STARK로 구분된다. &lt;br /&gt;
현재 이더리움 메인넷이 채택한 ZK 는 SNARK 방식이지만, 일부 Layer 2는 메인넷과 별개로 STARK를 채택하여 검증하는 경우도 있다.(대표적인 Layer 2 starknet) &lt;br /&gt;
최근 구글의 양자컴퓨터 연구로 확산된 양자내성증명 방식은 STARK 방식이다. &lt;br /&gt;
STARK 방식과 SNARK 방식은 기본 알고리즘의 채택이 완전히 달라 서로 다른 특성을 가진다. &lt;br /&gt;
SNARK 방식은 각 데이터를 타원곡선 암호를 이용해 암호화하는 방식으로, 양자컴퓨터의 쇼어 알고리즘에 취약한 타원곡선 암호로 인해 양자 위협에 노출된다. &lt;br /&gt;
STARK 방식은 각 데이터를 해시 변환을 이용해 암호화하는 방식으로, 양자컴퓨터의 쇼어 알고리즘이 역산하기에 어려운 방식을 이용하여 양자 내성을 가지지만 해시 데이터의 크기로 인해 증명 데이터 용량이 SNARK에 비해 매우 커서 네트워크 연산 부담이 크다. &lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;stwo&quot;&gt;Stwo&lt;/h4&gt;
&lt;p&gt;STARK 방식의 증명을 경량화해 네트워크 부담을 낮추는 방식의 증명 방식이다. &lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;linea&quot;&gt;Linea&lt;/h4&gt;
&lt;p&gt;격자기반 암호를 이용하는 증명 방식이다. &lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;boojum&quot;&gt;Boojum&lt;/h4&gt;
&lt;p&gt;STARK 방식의 고성능 증명 방식이다. &lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;openvm&quot;&gt;OpenVM&lt;/h4&gt;
&lt;p&gt;별도의 지정 증명 방식 없이 연산 도구만 제공하는 방식이다. &lt;br /&gt;
채택 네트워크가 별도로 증명 알고리즘을 지정한다. &lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;전용-rpc-노드&quot;&gt;전용 RPC 노드&lt;/h2&gt;
&lt;p&gt;이더리움 Layer 2의 사용으로 블록 생성 부담이 줄어 네트워크 가용성이 확보되었지만, 사용자의 체감 가용성은 트랜잭션을 처리하는 RPC 노드의 최대 처리 속도 제한으로 개선이 필수적이다. &lt;br /&gt;
높은 처리 속도와 낮은 지연 시간을 요구하는 경우, 트랜잭션 처리 중 노드 오류를 최소화하기 위해 &lt;strong&gt;전용 RPC 노드&lt;/strong&gt;를 사용한다. &lt;br /&gt;
RPC 노드는 네트워크를 구성하는 각 노드를 의미하며, 사용자는 임의의 RPC 노드에 트랜잭션을 제출하며 RPC 노드가 로컬에서 트랜잭션 오류 확인 후 다른 노드와 공유하여 저장하는 방식으로 네트워크에 트랜잭션 결과가 저장된다. &lt;br /&gt;
&lt;strong&gt;전용 RPC 노드&lt;/strong&gt;는 특정 목적을 위해 RPC 노드를 인증된 사용자만 이용할 수 있도록 제공하는 방식이다. &lt;br /&gt;
일반적인 RPC 노드는 다수의 사용자가 제출하는 트랜잭션 처리를 위해 최대 처리 속도가 낮게 설정되는 반면, 전용 RPC 노드는 인증된 소수의 사용자가 제출하는 트랜잭션만 처리하기에 높은 처리 속도를 가진다. &lt;br /&gt;
또한, 전용 RPC 노드는 노드 오류로 인한 트랜잭션 지연을 보상하는 구조가 설계되어 있어 기업 서비스에서 트랜잭션 처리 신뢰도를 높이기 위한 수단으로 이용된다. &lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;web3-서비스를-위한-고려사항&quot;&gt;Web3 서비스를 위한 고려사항&lt;/h2&gt;
&lt;p&gt;Layer 2로의 네트워크 확장으로 다양한 RPC 노드가 필요해졌다. &lt;br /&gt;
그 이유는 각 네트워크의 블록 생성 방식의 다름으로 네트워크 특화 노드가 필요하고, 블록 증명이 Layer 2 네트워크에서 수행되는 경우 노드의 연산 부하가 블록 생성 속도에 비례해 늘어나기 때문에 연산 능력의 향상이 요구되기 때문이다. &lt;br /&gt;
따라서 &lt;strong&gt;안정적인 Web3 서비스 운영과 블록 신뢰도&lt;/strong&gt;를 위해 Validity 방식의 블록 생성 네트워크를 채택하며, 양자내성 네트워크를 고려하는 경우를 고려하면 &lt;strong&gt;전용 RPC 노드를 적극 활용&lt;/strong&gt;해야 한다. &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;사용 목적에 따른 블록 생성 방식을 제안한다.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;사용 목적&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;블록 생성 방식&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;특징&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;실시간 반응형&lt;/strong&gt;(게임, 소셜 네트워크)&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Optimistic&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;빠른 Layer 2 기록으로 데이터 송수신 속도 최적화&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;데이터 검증형&lt;/strong&gt;(전자계약, 자산 송금)&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Validity&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Layer 2에서의 블록 검증을 통한 빠른 블록 확정, 서비스 신뢰를 ZK 증명 방식의 무결성으로 확장&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;서비스에 사용할 네트워크 선정 시 참고할 수 있는 사이트를 아래에 기재한다. &lt;br /&gt;
&lt;a href=&quot;https://l2beat.com/scaling/summary&quot;&gt;L2Beat&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;
</description>
      <pubDate>Tue, 14 Apr 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/ethereum-subchain-stability/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/ethereum-subchain-stability/</guid>
    </item>
    
    <item>
      <title>이더리움 L2 네트워크와 ZKsync Era 소개</title>
      <description>&lt;h2 id=&quot;ethereum&quot;&gt;Ethereum&lt;/h2&gt;
&lt;p&gt;이더리움은 이전 포스트의 내용처럼 &lt;strong&gt;지분 증명&lt;/strong&gt; 방식을 이용한 블록체인 네트워크다. &lt;br /&gt;
이더리움은 작업 증명 방식의 네트워크에 비교했을 때 빠른 블록 생성 속도를 강점으로 가지지만, 대용량 트래픽 환경에서는 한정적인 자원으로 인해 사용자 체감 속도가 원활하지 않을 수 있다. &lt;br /&gt;
이더리움 네트워크 안에서 블록을 압축해 기록하는 방식으로 특정 계약의 블록 효율을 높이는 시도가 있지만, &lt;br /&gt;
이 방식은 네트워크 자체의 속도 향상이 아닌 특정 스마트 컨트랙트 동작을 위한 사전 작업으로 &lt;br /&gt;
오프체인에서 데이터를 압축하는 과정이 포함되기 때문에 기술적 숙련도를 요구되며, 압축 과정에서의 변조될 위험이 존재한다. &lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;layer-2&quot;&gt;Layer 2&lt;/h3&gt;
&lt;p&gt;이더리움 네트워크에서 &lt;strong&gt;Layer&lt;/strong&gt; 개념을 이용해 블록 생성 속도 향상, 비용 절감 및 특수 기능을 목적으로 하는 Layer 2 네트워크가 존재한다. &lt;br /&gt;
Layer 2에 속하는 네트워크는 자체 네트워크(Layer 2)에서 블록을 생성한 뒤 여러 블록을 모아 이더리움 메인 네트워크(Layer 1)에 블록을 생성하는 방식을 이용한다. &lt;br /&gt;
Layer 2 방식을 이용하면 메인 네트워크의 블록 생성 대기열과 별개로 블록을 생성하여 속도 향상을 누릴 수 있고, &lt;br /&gt;
Layer 1 의 높은 네트워크 비용을 여러 트랜잭션이 나누어 부담하기에 비용 절감 효과를 누린다. &lt;br /&gt;
데이터 무결성과 추적에 대해서는 Layer 2의 트랜잭션 추적과 Layer 1에 기록된 블록 정보를 이용할 수 있으므로 결과적인 보안성은 이더리움 메인 네트워크와 같다. &lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;zksync-era&quot;&gt;ZKsync Era&lt;/h3&gt;
&lt;p&gt;이 포스트에서는 한국 기술 블로그에 잘 소개되지 않은 ZKsync Era 네트워크의 개념을 소개한다. &lt;br /&gt;
ZKsync Era는 &lt;strong&gt;Zero-Knowledge proof, ZK(영지식 증명)을&lt;/strong&gt; 이용하는 이더리움 Layer 2 네트워크다. &lt;br /&gt;
영지식 증명은 해시값 비교와 다른 방식으로 데이터를 검증한다. &lt;br /&gt;
해시값 비교는 검증자가 원본 데이터를 직접 해시로 변환 후 블록체인에 기록된 데이터 해시와 비교하는 방식을 이용해야 해당 데이터의 변조를 확인할 수 있다. &lt;br /&gt;
데이터 검증 과정에서 검증자가 원본을 확인해 민감정보가 유출되거나, 검증자의 조작에 의한 데이터 변조 가능성 문제가 존재하여 영지식 증명 방식이 보안 측면에서 유리하다. &lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;영지식 증명은 하나의 키 쌍, 데이터 해시를 이용해서 데이터를 기록하고 검증한다. &lt;br /&gt;
기록과 검증 과정에서 원본 데이터는 데이터 소유자 외에는 노출되지 않는 점이 보안 측면의 이점이다. &lt;br /&gt;
    &lt;ol&gt;
      &lt;li&gt;키 쌍 중 &lt;strong&gt;검증 키&lt;/strong&gt;와 &lt;strong&gt;데이터 고유값&lt;/strong&gt;을 블록체인에 기록한다. &lt;br /&gt;&lt;/li&gt;
      &lt;li&gt;데이터 검증 시점에서 &lt;strong&gt;증명 키&lt;/strong&gt;와 &lt;strong&gt;원본&lt;/strong&gt;을 조합해 &lt;strong&gt;증명&lt;/strong&gt;이라는 수학적 결과물을 생성한다. &lt;br /&gt;&lt;/li&gt;
      &lt;li&gt;블록체인에 기록된 &lt;strong&gt;검증 키&lt;/strong&gt;를 이용해서 앞서 생성한 &lt;strong&gt;증명&lt;/strong&gt;을 검증한다. &lt;br /&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;검증 키&lt;/strong&gt;의 검증 결과가 “참”이며 데이터 해시와 일치하는 경우 블록체인에 기록된 정보와 소유자의 제출 정보의 무결성을 확인할 수 있다. &lt;br /&gt;
&lt;br /&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;ZKsync Era의 특징은 영지식 증명 외에도 &lt;strong&gt;Abstract Account(AA)&lt;/strong&gt; 개념이 네트워크의 기본 설정인 점이다. &lt;br /&gt;
AA를 이용하면 트랜잭션 당사자와 수신자 외의 3자가 네트워크 비용을 대납하거나, 트랜잭션의 조건을 설정하는 등의 복잡한 계약 조건을 이용할 수 있다. &lt;br /&gt;
이 특징을 이용하여 ZKsync Era 내부에서는 가스비 대납자(Paymaster)를 구현하기에 편리하며 WaaS의 프로세스 설계가 편리하다. &lt;br /&gt;
WaaS의 대표 Paymaster를 사용자 지갑 AA가 사용하도록 설정하고, AA에는 특정 조건을 충족하는 데이터만 트랜잭션에 포함할 수 있는 로직을 이용하면 &lt;br /&gt;
서비스의 프로세스에서 벗어나는 엣지 케이스를 줄이는 리스크 완화가 가능하다. &lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Sat, 21 Mar 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/introduce-ethereum-layer2-zksync-era/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/introduce-ethereum-layer2-zksync-era/</guid>
    </item>
    
    <item>
      <title>블록체인과 스마트 컨트랙트</title>
      <description>&lt;h2 id=&quot;블록체인&quot;&gt;블록체인&lt;/h2&gt;

&lt;p&gt;블록체인은 각 데이터 간의 연결고리를 만들어 데이터의 외부 개입에 의한 위변조를 방지하는 기술이다. &lt;br /&gt;
외부에서 임의로 기존 데이터 사이에 새로운 데이터를 삽입하거나 기존 데이터를 변조하면 블록체인 규칙에 의해 저장된 검증 데이터가 모두 바뀌기 때문에 검증 시점에서 위변조를 탐지할 수 있다. &lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;작업증명&quot;&gt;작업증명&lt;/h3&gt;

&lt;p&gt;블록체인의 연결고리 방식 중 작업증명이 있다. &lt;br /&gt;
작업증명 방식은 높은 부하를 가진 연산을 통해 작업의 위변조를 증명할 수 있는 노드를 선정하는 방식이다. &lt;br /&gt;
위변조를 증명하기 위한 후보 노드들은 증명 대상 데이터를 모아서 해시 알고리즘을 연산한다. &lt;br /&gt;
다만, 데이터를 단순히 해시로 변환하는게 아닌 일종의 검증 문자인 ‘nonce’를 추가해서 연산한다. &lt;br /&gt;
nonce는 임의의 숫자이며 해시 알고리즘의 특성 상 데이터의 극히 일부가 변경되어도 해시 문자열 전체가 바뀌기 때문에 nonce의 규칙을 이용해서 검증하는게 아닌, 생성된 &lt;strong&gt;해시 문자열이 규칙에 부합하는 경우가 연산의 성공이며 증명 노드가 되는 방식&lt;/strong&gt;이다. &lt;br /&gt;
nonce를 계속 변경하며 규칙에 맞는 해시를 생성해야 하는 특성으로 인해 작업증명 방식은 증명 노드에 요구하는 연산량이 매우 높고, 변조를 위해서는 네트워크에 기여하는 모든 노드보다 높은 연산량을 가져야 하는 &lt;strong&gt;자본적 해자&lt;/strong&gt;를 가진다. &lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;지분증명&quot;&gt;지분증명&lt;/h3&gt;

&lt;p&gt;블록체인의 연결고리 방식 중 지분증명도 있다. &lt;br /&gt;
지분증명 방식은 작업증명과 달리 연산을 통해 위변조 증명 노드를 선정하지 않는다. &lt;br /&gt;
해당 네트워크에 자산을 예치하고, 네트워크에 대한 &lt;strong&gt;지분을 이용해 위변조 증명 노드를 선정&lt;/strong&gt;한다. &lt;br /&gt;
지분이 큰 노드가 증명 노드가 될 확률이 높고, 증명 노드는 해시 블록 생성 대가로 추가로 자산을 배분받아 자산이 점점 늘어난다. &lt;br /&gt;
작업증명 방식과 달리 증명 연산의 부하가 작아 블록 생성에 필요한 시간이 적은 편이다. &lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;스마트-컨트랙트&quot;&gt;스마트 컨트랙트&lt;/h2&gt;

&lt;p&gt;스마트 컨트랙트는 블록체인 안에서 실행되는 함수와 같다. &lt;br /&gt;
특정 조건이 충족되면 사전 정의된 작업을 실행하는 방식으로, &lt;strong&gt;작업이 미리 정의된 상태로 블록체인에 저장되어 조건 변경이 불가능&lt;/strong&gt;하다. &lt;br /&gt;
사람 사이의 계약은 당사자 간의 의견 차이나 계약 위반을 대비해서 공증 과정이 필요하지만, 스마트 컨트랙트는 생성 시점에 조건을 설정하고 조건 충족 시 자동으로 작업이 실행되어 &lt;strong&gt;공증 없는 P2P 계약&lt;/strong&gt;이 가능하다. &lt;br /&gt;
스마트 컨트랙트의 투명성과 작업 실행을 이용하면 여러 기능을 구현할 수 있다. &lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;가스비-대납&quot;&gt;가스비 대납&lt;/h3&gt;

&lt;p&gt;가스비 대납은 트랜잭션 생성 시 발생하는 &lt;strong&gt;네트워크 가스비를 트랜잭션 생성자 외의 제3자가 지불&lt;/strong&gt;하는 방식을 말한다.&lt;br /&gt;
이 방식은 특정 서비스 안에서 발생하는 트랜잭션 비용을 서비스가 대신 납부하기 위해 사용한다. &lt;br /&gt;
사용자는 가스비를 직접 낼 필요가 없기 때문에 트랜잭션 생성에 대한 확인을 마치면 바로 전송하며, 해당 트랜잭션은 가스비 대납 스마트 컨트랙트에서 서비스 계정에 가스비를 청구한 뒤 네트워크에 기록한다. &lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;자동-토큰-발행&quot;&gt;자동 토큰 발행&lt;/h3&gt;

&lt;p&gt;자동 토큰 발행 방식으로도 스마트 컨트랙트를 활용할 수 있다. &lt;br /&gt;
기본적인 구조가 A 충족, B 실행 이므로 조건으로 자산 입금, &lt;strong&gt;실행으로 토큰 반환을 설정하면 내가 생성한 토큰을 다른 자산과 일정 비율로 자동 교환&lt;/strong&gt;할 수 있다. &lt;br /&gt;
이 방식은 거래소의 Convert 기능 등으로 이용할 수 있다. &lt;br /&gt;
거래소는 예비로 보유중인 토큰을 사용자가 제출하는 토큰과 시장가 또는 자체적인 기준으로 교환하여 반환하는 스마트 컨트랙트를 이용하여 빠른 속도로 사용자가 요청한 토큰을 전달한다. &lt;br /&gt;
사용자는 스마트 컨트랙트가 실행되어 조건 충족 시 자동으로 교환 대상 토큰이 반환될 것을 기대할 수 있기 때문에 거래소의 신뢰도 영향을 줄이며 거래할 수 있다. &lt;br /&gt;&lt;/p&gt;
</description>
      <pubDate>Mon, 09 Mar 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/block-chain-and-smart-contract/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/block-chain-and-smart-contract/</guid>
    </item>
    
    <item>
      <title>양자내성암호와 보안</title>
      <description>&lt;h2 id=&quot;양자컴퓨터의-개발과-보안의-두려움&quot;&gt;양자컴퓨터의 개발과 보안의 두려움&lt;/h2&gt;

&lt;p&gt;양자컴퓨터는 고전컴퓨터와 달리 &lt;strong&gt;양자의 중첩을 이용해 동시에 여러 경우를 계산&lt;/strong&gt;할 수 있는 점이 특징이다.&lt;br /&gt;
2개의 비트가 있다면 고전컴퓨터는 [00, 01, 10, 11] 4개의 경우 중 하나를 골라 계산하지만 양자컴퓨터는 4개의 경우를 중첩하여 계산 후 가장 확률이 높은 경우를 골라낸다.&lt;br /&gt;
양자의 중첩을 이용해 각 경우를 확률로 존재하는 상태에서 가장 높은 확률을 가진 경우를 찾아내는 것이다.&lt;br /&gt;
수조에 여러 개의 모래성을 쌓은 뒤 물을 채우면 가장 높은 성이 마지막까지 잠기지 않는 것과 같이 확률이 높은(높이가 높은) 경우를 남기고 나머지는 지우는(물속에 가라앉히는) 과정이다.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;양자컴퓨터를-이용한-암호-풀이&quot;&gt;양자컴퓨터를 이용한 암호 풀이&lt;/h3&gt;

&lt;p&gt;양자컴퓨터를 이용하면 기존의 비대칭 암호를 풀이하는 시간이 매우 짧아지는 점이 양자내성암호를 개발해야하는 이유다.&lt;br /&gt;
고전컴퓨터를 기준으로 고안된 비대칭 암호는, 공개키와 비밀키를 사용하여 공개키 정보로부터 비밀키를 알아내기 위해서 매우 오랜 시간이 필요한 함수를 사용한다.&lt;br /&gt;
하지만 양자컴퓨터는 다양한 경우를 한 번에 계산하여 가장 확률이 높은 경우를 찾아내기 때문에, 비밀키를 알아내기 위해 필요한 연산 시간이 기하급수적으로 짧아진다.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;양자컴퓨터로-풀기-어려운-암호&quot;&gt;양자컴퓨터로 풀기 어려운 암호&lt;/h3&gt;

&lt;p&gt;다양한 경우를 동시에 연산할 수 있는 양자컴퓨터의 특징에도 불구하고 모든 문제를 해결할 수 있지는 않다.&lt;br /&gt;
현재 양자내성암호로 가장 활발히 개발중인 암호는 &lt;strong&gt;격자 기반 암호&lt;/strong&gt;인데, 이 암호는 격자 데이터 안에 비밀 정보를 숨겨서 전달하는 방식이다.&lt;br /&gt;
단순히 모래 속에 진주알을 숨기는 암호라면 양자컴퓨터가 쉽게 진주알(비밀 정보)의 특징을 찾아낼 수 있지만, 격자 기반 암호는 모래알에 쓰레기를 섞어 진주알을 찾기 어렵게 만든다.&lt;br /&gt;
기술적으로는 격자를 비틀어서 격자의 규칙성을 어긋나게 만드는 것이다.&lt;br /&gt;
격자를 비트는 노이즈로 인해 양자컴퓨터는 다양한 경우를 동시에 연산해도 월등히 높은 확률을 가지는 특정한 경우를 찾기 어려워진다.&lt;br /&gt;
비밀 정보는 격자의 규칙에서 살짝 옮겨진 곳에 저장되는데, 원래 격자 규칙을 안다면 비밀 정보가 규칙과 다른 것을 알 수 있지만 격자가 비틀린 상황에서는 규칙을 유추하기 어렵고, 규칙을 찾더라도 비틀린 정보들로 인해 진짜 비밀 정보가 아닌 정보들도 규칙에 맞지 않아 보여 비밀 정보를 찾기 위해 수 많은 후보군을 다시 검토해야 한다.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;양자내성암호의-사용-분야&quot;&gt;양자내성암호의 사용 분야&lt;/h2&gt;

&lt;p&gt;양자내성암호가 개발되어도, 모든 암호를 양자내성암호로 대체하지는 않는다.&lt;br /&gt;
우리가 많이 사용하는 https를 예로 들면 가장 처음의 터널 생성 과정에서 클라이언트와 서버가 공유하는 대칭키 전달 과정에서 양자내성암호를 이용한 뒤, 이후의 통신에는 대칭키 암호를 이용한다.&lt;br /&gt;
대칭키 전달에만 양자내성암호를 사용하는 이유는 비대칭 암호와 달리 대칭키 암호 방식은 양자컴퓨터가 유추하는데에 오랜 시간이 필요하기 때문이다.&lt;br /&gt;
비대칭 암호는 공개키가 비밀키를 유추할 수 있는 힌트가 되지만, 대칭 암호는 아무런 힌트 없이 256개 이상의 문자열 조합을 맞춰야 한다.&lt;br /&gt;
문자열 조합의 정답 여부는 실제 데이터를 복호화 시도해야 알 수 있기에 양자컴퓨터의 장점인 &lt;strong&gt;동시에 연산&lt;/strong&gt;을 하지 못하고 한 번에 하나씩의 경우를 대입해야 한다.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;데이터베이스에-양자내성암호-적용&quot;&gt;데이터베이스에 양자내성암호 적용&lt;/h3&gt;

&lt;p&gt;데이터베이스에 저장된 데이터 역시 양자컴퓨터를 이용한 공격에 대비해 보안을 강화해야 한다.&lt;br /&gt;
데이터를 암호화하여 저장하고, 필요 시 복호화하여 사용하는 현재 방식과 크게 다르지 않은데, 복호화를 위한 키를 양자내성암호로 보호한다.&lt;br /&gt;
같은 서버 안에서 복호화 키를 보관하면 서버 공격 시 데이터베이스와 함께 복호화 키도 탈취하여 데이터 보호에 실패할 수 있다.&lt;br /&gt;
서버 공격에 대비하기 위해 복호화 키를 데이터베이스와 격리된 다른 서버에 보관하여 필요 시 데이터베이스 서버로 정보를 전달하도록 한다.&lt;br /&gt;
양자내성암호는 복호화 키 전달 시 이용된다. 복호화 키가 통신 과정에서 유출되지 않도록 보호하여 서버 간 통신을 암호화한다.&lt;br /&gt;
데이터베이스는 복호화 키를 저장하지 않고, 필요 시 서버에 요청 후 바로 삭제해 복호화 키를 보호한다.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
</description>
      <pubDate>Thu, 26 Feb 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/quantum-computer-and-post-quantum-crypto/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/quantum-computer-and-post-quantum-crypto/</guid>
    </item>
    
    <item>
      <title>투자는 서비스 개발에 필요한가?</title>
      <description>&lt;h2 id=&quot;서비스-개발-단계에서-투자는-필수적인가&quot;&gt;서비스 개발 단계에서 투자는 필수적인가?&lt;/h2&gt;

&lt;p&gt;흔히들 스타트업은 투자를 이어가며 기업을 운영하는 방식이 필수적이라고 생각한다.
내 생각에는 ‘필수가 아니다’를 넘어 &lt;strong&gt;기피해야 한다&lt;/strong&gt;는 입장이다.
이전에 투자 유치 플랫폼에 기재한 정보를 통해 한 투자자가 미팅을 요청했다.
인증된 플랫폼을 통한 접근이지만, 해당 투자자는 자신이 밝힌 소속 홈페이지에 정보가 없고 메일 주소 역시 소속과 관계 없었기에 투자자를 사칭한 사기를 의심했다.
이에 대한 내 대처는 해당 소속에 투자자 신분 확인을 요청하는 것이었다.
신분 확인을 위해 투자자에게도 통보 혹은 승인 차 연락이 갔는지, 온라인 미팅은 &lt;em&gt;투자자의 레퍼런스를 체크하는 건 무슨 경우인가요?&lt;/em&gt; 라는 질문으로 시작된 불편한 시간이었다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;물론, 본인 동의 없는 레퍼런스 체크에는 불쾌할 수 있다.
하지만 이후의 태도까지 종합하면 이 투자자의 태도가 창업자에게 비협조적임을 알 수 있다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;주요 발언을 일부 인용한다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;투자를 받고 싶다면 이런 태도로는 힘들겁니다.&lt;/li&gt;
  &lt;li&gt;본인 입맛에 맞는 투자자를 찾고 싶은거 같은데, 투자는 그렇지 않습니다.
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이전에도 투자의 필요성에 대해 회의적인 시선을 가지고 있었지만, 단 한 명의 투자자가 내 생각에 쐐기를 박았다.
나는 투자를 통해 우위를 점하려는 행위에 동조하지 않을 것이다.&lt;/p&gt;

&lt;h2 id=&quot;스타트업에-투자하는-이유&quot;&gt;스타트업에 투자하는 이유&lt;/h2&gt;

&lt;p&gt;스타트업에 투자하는 이유는 몇 가지가 있다.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;미래 가치에 대한 지분 확보&lt;/li&gt;
  &lt;li&gt;서비스 개발 기간 단축으로 확보한 기업 지분의 가치 제고&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;위의 두 가지 이유를 보면, 투자자와 창업자 관계에서 투자자는 우위에 있지 않다.
오히려 투자를 받거나 거절할 수 있는 창업자가 우위에 있다고 보는 편이 상황에 맞다.&lt;/p&gt;

&lt;h2 id=&quot;투자자와-창업자의-관계-역전&quot;&gt;투자자와 창업자의 관계 역전&lt;/h2&gt;

&lt;p&gt;왜, 많은 투자자는 창업자보다 본인이 우위에 있다고 생각하고 심지어 자금의 운용자가 아닌 &lt;strong&gt;심사역&lt;/strong&gt;까지도 이런 생각을 할까?
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;내가 생각하는 이유는 창업자가 투자를 유치하는 상황에 있다.
많은 창업자가 투자를 유치하기 위해 노력하는 시점이 재정적인 압박이 큰 상황이기 때문이다.
위 상황의 창업자는 기술이나 서비스를 개발하며 많은 자본을 사용하고, 매출 발생 없이 투자금을 소진한다.
이후 투자금이 소진되는 시기에 맞춰, 새로운 투자를 유치하지 못하면 회사를 이어갈 수 없는 상태가 되면 새로운 투자자를 만나 투자를 위해 주도적 위치를 상실한다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;과연 이런 행동이 &lt;strong&gt;스타트업&lt;/strong&gt; 방식의 기업 운영이 맞을까?
적어도 내가 생각하기에는 위 방식은 &lt;strong&gt;파산 회피를 위한 뻥튀기&lt;/strong&gt; 방식의 기업 운영이다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;기업을 운영하며 본인이 운영하는 기업이 투자가 필요한지 먼저 판단하고, 필수적인 투자 이후 다음 투자 없이 기업을 이어갈 계획을 세워야 진짜 &lt;strong&gt;스타트업&lt;/strong&gt;을 운영할 수 있다.&lt;/p&gt;
</description>
      <pubDate>Mon, 09 Feb 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/business/is-investment-necessary-to-service/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/business/is-investment-necessary-to-service/</guid>
    </item>
    
    <item>
      <title>스타트업이 뭐길래?</title>
      <description>&lt;h3 id=&quot;요즘-사람들이-이야기하는-스타트업은-제게-의문을-가지게-합니다&quot;&gt;요즘 사람들이 이야기하는 스타트업은, 제게 의문을 가지게 합니다.&lt;/h3&gt;

&lt;p&gt;저에게 스타트업은 &lt;strong&gt;새로운 방식으로 문제를 해결하는 집단&lt;/strong&gt;인데,&lt;/p&gt;

&lt;p&gt;스타트업을 기사로만 접하는 대중과 스타트업 현업 종사자조차 다르게 생각합니다.
&lt;br /&gt;
이들에게 스타트업은 &lt;strong&gt;투자를 받아 사업하는 기업&lt;/strong&gt;이며&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;투자를 잘 받는 스타트업이 잘 나가는 것&lt;/strong&gt;입니다.&lt;/p&gt;

&lt;p&gt;어쩌다가 스타트업의 가치가 &lt;strong&gt;투자 금액&lt;/strong&gt;을 기준으로 삼게 되었는지 모르겠습니다.
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;투자는-자금을-활용하는-방법입니다&quot;&gt;‘투자’는 자금을 활용하는 방법입니다.&lt;/h3&gt;

&lt;p&gt;자금 활용의 궁극적 목표는 증식입니다.&lt;/p&gt;

&lt;p&gt;자금의 손실을 막으려다 보니, 투자자의 행동은 자연스럽게 자금 운용 태도가 보수적으로 변하게 됩니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;투자자들은 미래의 가치를 예상하기 위해 ‘선례’를 필요로 하고,&lt;/p&gt;

&lt;p&gt;스타트업이 그린 가설대로 미래가 흘러갈 것이라고 투자자를 ‘설득’해야 합니다.&lt;/p&gt;

&lt;p&gt;한국의 벤처캐피탈이 하는 일은 &lt;strong&gt;계산으로 검증된 지표를 믿는 투자&lt;/strong&gt;입니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;스타트업은 새로운 방식으로 문제 해결에 도전하기 위해 초기 자금을 필요로 합니다.&lt;/p&gt;

&lt;p&gt;이때, 지분을 대가로 자금을 투자하는 곳이 벤처캐피탈입니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;벤처캐피탈은 손실을 줄이기 위해 예측 가능성을 요구하기 때문에,&lt;/p&gt;

&lt;p&gt;선례가 없는 진짜 새로운 방식은 벤처캐피탈에서 투자받기 어렵습니다.
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;선례는-인물의-성공-유사-방식의-성공-등의-유형이-있습니다&quot;&gt;선례는 인물의 성공, 유사 방식의 성공 등의 유형이 있습니다.&lt;/h3&gt;

&lt;p&gt;인물의 성공은 스타트업의 핵심 인물이 성공한 경험을 말합니다.&lt;/p&gt;

&lt;p&gt;유사 방식의 성공이란 타 국가나 다른 기업이 이미 비슷한 시도에서 성과를 거두었는지를 뜻합니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;개인의 자본으로 사업을 시작하기 어려운 기술력 기반 스타트업들은 ‘투자’를 통해 새로운 시도를 하려 합니다.&lt;/p&gt;

&lt;p&gt;투자를 받기 위해서 최초의 아이디어에서 여러 가지 선례를 참고해 변형을 가하고,&lt;/p&gt;

&lt;p&gt;사업 본질과 무관한 인력을 영입합니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;스타트업은 이렇게 비슷해집니다.&lt;/p&gt;

&lt;p&gt;시작은 각자의 생각과 의지로 추진하지만&lt;/p&gt;

&lt;p&gt;자본의 논리와 투자자의 기호에 변형되어 틀에 맞춰집니다.&lt;/p&gt;
</description>
      <pubDate>Sun, 01 Feb 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/business/what-is-that-startup/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/business/what-is-that-startup/</guid>
    </item>
    
    <item>
      <title>마법과 공학, 현상과 이해</title>
      <description>&lt;h2 id=&quot;요즘-대규모-언어-모델gemini-gpt-claude을-활용해서-프로그래밍-지식-없이-애플리케이션-서비스를-만들었다는-이야기가-많이-들립니다&quot;&gt;요즘 대규모 언어 모델(Gemini, GPT, Claude)을 활용해서 프로그래밍 지식 없이 애플리케이션 서비스를 만들었다는 이야기가 많이 들립니다.&lt;/h2&gt;

&lt;p&gt;하지만 저의 관점에서 프로그래밍 지식 없이 ‘프로그래밍을 했다’는 말은 근본적인 의문을 품게 합니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;어떻게 프로그래밍했다는 거지?&lt;/strong&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;인공지능의 발전으로 다양한 지식에 손쉽게 접근하고, 
컴퓨터를 이용하는 분야에 대해서는 손쉬운 자동화가 가능하다는 점은 분명 환영하고 활용해야 할 긍정적인 변화입니다.
&lt;br /&gt;
한 가지 고려할 점은, &lt;strong&gt;인공지능을 ‘마법 지팡이’처럼 휘두르는 방식과 ‘효율 좋은 공구’로 활용할지 선택하는 문제&lt;/strong&gt;입니다.
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;앞서 예를 든 애플리케이션 서비스를 만드는 것에 대해 생각하면, 
프로그래밍 지식 없이 만들어낸 경우 단지 마법 지팡이를 이용해 현상만을 구현한 것에 불과합니다.&lt;/p&gt;

&lt;p&gt;이 경우 사용자는 원하는 바의 결과물은 얻었지만, 그 현상이 어떻게 이루어졌는지 알 수 없다는 치명적 결함이 발생합니다.&lt;/p&gt;

&lt;p&gt;현상은 구현되어 잘 작동하는 듯 보이지만, 
내부의 구조를 이해하지 못하는 이상 추가 기능이나 문제 해결 시 다시 마법 지팡이에 의존하는 방법이 유일해집니다.&lt;/p&gt;

&lt;p&gt;마법 지팡이 의존도가 높아질수록, 지팡이 장인(LLM 운영사)은 가격을 높이는 동시에 사용자는 이해하려는 노력과 능력이 퇴보합니다.&lt;/p&gt;

&lt;p&gt;결국 내가 만들어낸 서비스를 나 자신도 이해하지 못하고 &lt;strong&gt;막대한 비용을 투입해 유지&lt;/strong&gt;해야만 하는 상황에 처하게 됩니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;제가 생각하는 인공지능의 올바른 활용은 잘 드는 칼이나 볼트 크기에 맞춰지는 만능 스패너와 같은 사용법입니다.&lt;/p&gt;

&lt;p&gt;사용하는 주체는 여전히 의도를 가진 우리가 되어야 하고, 그 과정의 불편을 해소하는 효율적인 도구로 인공지능을 사용하는 것입니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;인공지능이 만능이라고 생각하고 첫 시작부터 마무리까지 모든 걸 맡겨버리는 방식은 사실상 인공지능 운영사에 이익을 기부하는 것과 다르지 않습니다.&lt;/p&gt;

&lt;p&gt;어떤 일을 해야 할지 명확히 정의하고, 해결 방법을 이해하며 사용해야 우리는 인공지능을 효율적으로 활용할 수 있습니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;대기업의 인공지능 활용을 위한 인력 감축을 본 당신께,&lt;/p&gt;

&lt;p&gt;이미 서비스를 운영 중이고 규모를 갖춘 경우 인공지능을 이용한 인력 감축과 효율화는 합리적으로 보일 수 있습니다.&lt;/p&gt;

&lt;p&gt;하지만 서비스가 아직 개발 중이라면 인공지능이 대체할 수 없는 역할이 우선적이고 지배적입니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;인공지능은 반복적인 일을 수행하는 데에 적합한 반면, 서비스 개발 단계에서는 비정형적인 사고와 창의적인 아이디어를 검증하고 구체화하는 일이 필요합니다.&lt;/strong&gt;&lt;/p&gt;
</description>
      <pubDate>Sat, 10 Jan 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/business/do-not-say-understand-with-generative-ai/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/business/do-not-say-understand-with-generative-ai/</guid>
    </item>
    
    <item>
      <title>창업을 선택한 이유</title>
      <description>&lt;p&gt;사람들과 이야기 중 자주 나오는 질문입니다.&lt;/p&gt;

&lt;h2 id=&quot;왜-창업했어요&quot;&gt;왜 창업했어요?&lt;/h2&gt;

&lt;p&gt;저는 이 질문에 답하는 방식이 두 가지입니다.&lt;/p&gt;

&lt;h3 id=&quot;직함과-성과를-중요시하는-상대&quot;&gt;직함과 성과를 중요시하는 상대&lt;/h3&gt;

&lt;h3 id=&quot;흥미와-능력을-중요시하는-상대&quot;&gt;흥미와 능력을 중요시하는 상대&lt;/h3&gt;
&lt;p&gt;&lt;br /&gt;
서로 다른 유형의 답변에는 모두 거짓은 없지만, 표면적인 이유와 근본적인 이유를 각각 포함합니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;제가 20살에 창업한 표면적인 이유는 &lt;strong&gt;직접 만든 상품을 통해 저와 같은 문제를 가진 사람들에게 도움을 주기 위해서&lt;/strong&gt; 이지만,
&lt;br /&gt;
근본적으로는 문제와 호기심을 해결한 뒤 산출물을 공유하고 싶었기 때문입니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;첫 창업 이후 스타트업을 경험하고, 투자자와 만나며 저에게 창업의 이유가 재정립되었습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;개인의 호기심 해결&lt;/li&gt;
  &lt;li&gt;직함을 중요시하는 사람들에게 가치를 납득시키는 수단
&lt;br /&gt;
창업을 준비한다는 명목과 명함 한 장, 준비된 가치관이 있다면,&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;사람들은 저를 이해한 태도를 취합니다.&lt;/p&gt;

&lt;p&gt;실제로 창업을 통해 막대한 돈을 벌기보다, 지금 당장 빠져있는 문제를 해결하고, 본질적인 이유를 찾는 것에 집중해도 괜찮습니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;사람들은 창업에 대해 막연한 상상과 유행으로 창업자를 자신의 편견 안에서 이해합니다.&lt;/p&gt;

&lt;p&gt;저에게는 그들의 “이해”를 통해 얻을 수 있는 경험과 지식이 필요합니다.&lt;/p&gt;

&lt;p&gt;그래서 저는 “창업”이라는 수단을 문제 해결을 위한 효율적인 도구로 이용합니다.&lt;/p&gt;
</description>
      <pubDate>Sat, 03 Jan 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/business/reason-of-startup/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/business/reason-of-startup/</guid>
    </item>
    
    <item>
      <title>좋은 직장이라는 환상</title>
      <description>&lt;p&gt;“대기업, 높은 연봉, 멋진 직함.” 모두가 부러워하는 그곳에 입사한 친구는 왜 1년 만에 퇴사했을까요?&lt;/p&gt;

&lt;p&gt;‘대퇴사의 시대’, ‘조용한 퇴직’이라는 말들이 쏟아집니다. 하지만 거창한 단어 뒤에 숨겨진 본질은 어쩌면 아주 간단한 한 문장일지 모릅니다.&lt;/p&gt;

&lt;p&gt;이 회사, 나랑 안 맞아요.&lt;/p&gt;

&lt;h2 id=&quot;우리는-늘-좋은-직장을-찾아-헤맵니다-하지만-우리가-좋은-직장이라고-믿었던-기준들이-사실은-우리를-불행하게-만드는-환상은-아니었을까요&quot;&gt;우리는 늘 ‘좋은 직장’을 찾아 헤맵니다. 하지만 우리가 ‘좋은 직장’이라고 믿었던 기준들이, 사실은 우리를 불행하게 만드는 ‘환상’은 아니었을까요?&lt;/h2&gt;

&lt;h3 id=&quot;환상-1-돈을-벌기-위한-수단&quot;&gt;환상 1: 돈을 벌기 위한 수단&lt;/h3&gt;

&lt;p&gt;‘높은 연봉’이라는 조건 하나만 보고, 매일 아침 지옥철에 몸을 싣고 영혼 없는 표정으로 출근합니다.&lt;/p&gt;

&lt;h3 id=&quot;환상-2-나를-꾸미는-수식어&quot;&gt;환상 2: 나를 꾸미는 수식어&lt;/h3&gt;

&lt;p&gt;‘멋진 직함’이라는 명함을 얻기 위해, 내 관심사와 전혀 다른 분야의 일을 억지로 해내며 하루하루를 버팁니다.&lt;/p&gt;

&lt;h3 id=&quot;환상-3-사회적-소속감&quot;&gt;환상 3: 사회적 소속감&lt;/h3&gt;

&lt;p&gt;‘대기업’이라는 안정적인 소속감을 얻는 대가로, 나와 맞지 않는 조직 문화를 견디며 진짜 ‘나’를 잃어버립니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;이런 환상을 좇다 보면, 우리는 어느새 기업의 기준에 나를 맞추기 시작합니다. 관심 없는 분야도 열정적으로 보이기 위해 이력서를 꾸미고, 해보지 않은 경험도 능숙한 척 면접에서 연기합니다.&lt;/p&gt;

&lt;p&gt;그렇게 겨우 합격한 직장에서, 우리가 진정한 만족과 행복을 느끼기란 처음부터 불가능한 일이었을지 모릅니다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;하지만 우리 마음 깊은 곳에서는 알고 있습니다. 진짜 행복한 일이란,&lt;/p&gt;

&lt;p&gt;“나의 가치관을 투영해 세상에 기여하는 수단”이자, “혼자가 아닌, 함께하기에 더 크게 성장할 수 있는 조직”이라는 것을요.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;이제, ‘나를 회사에 맞추는’ 낡은 방식을 끝내야 합니다. 나의 ‘결’에 맞는 기업이 나를 찾아오게 만들어야 합니다. 지원서가 아닌 나의 ‘소개서’를, 나의 ‘이야기’를 보여줘야 합니다.&lt;/strong&gt;&lt;/p&gt;
</description>
      <pubDate>Thu, 01 Jan 2026 12:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/business/hallucinatioin-of-great-job/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/business/hallucinatioin-of-great-job/</guid>
    </item>
    
    <item>
      <title>GoLang, Mongo Index</title>
      <description>&lt;p&gt;Mongodb에서 특정 키를 빠르게 조회하기 위해 Index 기능을 사용할 수 있다.&lt;/p&gt;

&lt;p&gt;Index 기능을 사용하면 특정 키 값을 기준으로 데이터를 조회하는 데에 필요한 연산이 줄어들고, unique option을 이용해 컬렉션 안에서 유일한 값으로 지정할 수 있다.
&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;index-model&quot;&gt;Index Model&lt;/h2&gt;
&lt;p&gt;Index 설정을 위해서 어떤 키를 Index로 사용하는지에 대한 Model을 선언해야 한다.&lt;/p&gt;

&lt;p&gt;예시에서는 단일 필드 “sample_id” 키를 오름차순으로 정렬하는 Index와 복합 필드 “sample_id”, “name” 키를 오름차순으로 정렬하는 Index를 선언한다.&lt;/p&gt;

&lt;p&gt;Key 값이 필드 이름, Value 값이 정렬 방향이다.(1 : 오름차순 / -1 : 내림차순)
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;단일-필드-인덱스&quot;&gt;단일 필드 인덱스&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;singleSampleIndexModel := mongo.IndexModel{Keys: bson.D{{Key: &quot;sample_id&quot;, Value: 1}}}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;복합-인덱스&quot;&gt;복합 인덱스&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;compoundSampleIndexModel := mongo.IndexModel{Keys: bson.D{{Key: &quot;sample_id&quot;, Value: 1},{Key: &quot;name&quot;,Value: 1}}}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;index-option&quot;&gt;Index Option&lt;/h2&gt;
&lt;p&gt;Index를 선언할 때, Option을 사용해서 unique 필드 설정이 가능하다.&lt;/p&gt;

&lt;p&gt;unique 설정이 true이면, 해당 필드는 컬렉션 내에서 유일한 값이 되며 중복되는 데이터가 삽입 시도되는 경우 “Duplicate error”를 반환하며 삽입에 실패한다.&lt;/p&gt;

&lt;p&gt;복합 인덱스의 경우에는 인덱스에 사용한 필드 조합이 컬렉션 내에서 유일한 값이 되며 인덱스에 사용한 모든 필드가 중복되는 경우에는 삽입에 실패하지만, 하나라도 다른 경우 삽입이 가능하다.
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;단일-필드-인덱스-unique-설정&quot;&gt;단일 필드 인덱스 unique 설정&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;singleSampleIndexModel := mongo.IndexModel{Keys: bson.D{{Key: &quot;sample_id&quot;, Value: 1}}, Options: options.Index().SetUnique(true)}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;복합-인덱스-unique-설정&quot;&gt;복합 인덱스 unique 설정&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;compoundSampleIndexModel := mongo.IndexModel{Keys: bson.D{{Key: &quot;sample_id&quot;, Value: 1}, {Key: &quot;name&quot;, Value: 1}}, Options: options.Index().SetUnique(true)}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;create-index&quot;&gt;create Index&lt;/h2&gt;
&lt;p&gt;Index Model 선언 후에는 컬렉션에 Index를 등록해야 한다.&lt;/p&gt;

&lt;p&gt;collection은 mongo driver의 mongo.Collection 타입이다.&lt;/p&gt;

&lt;p&gt;아래 예시 코드처럼 인덱스를 등록할 수 있고, 등록에 성공하면 name 변수에 인덱스 이름이 반환된다.&lt;/p&gt;

&lt;p&gt;인덱스 이름은 “필드명_순서” 형태이며, 복합 인덱스의 경우 “필드명_순서_필드명_순서”이다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;name, err := collection.Indexes().CreateOne(context.TODO(), singleSampleIndexModel)

name, err := collection.Indexes().CreateOne(context.TODO(), compoundSampleIndexModel)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
      <pubDate>Sat, 17 May 2025 00:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/golang-mongo-index/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/golang-mongo-index/</guid>
    </item>
    
    <item>
      <title>GoLang, bcrypt 비밀번호 보안</title>
      <description>&lt;p&gt;웹 서비스를 이용할 때, 비밀번호를 등록해서 로그인 인증을 하는 경우가 많다.&lt;/p&gt;

&lt;p&gt;우리가 입력한 비밀번호가 그대로 데이터베이스에 저장된다면 어떤 일이 일어날까?&lt;/p&gt;

&lt;p&gt;데이터베이스의 단편적인 정보 유출로 유저 권한을 탈취당한다.&lt;/p&gt;

&lt;p&gt;이런 일을 방지하기 위해서 로그인 비밀번호 등의 민감 정보는 암호화하는 과정이 필요하다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;hash&quot;&gt;HASH&lt;/h2&gt;
&lt;p&gt;해시는 원본 데이터를 해쉬 함수를 이용해 변환한 결과값을 말한다.&lt;/p&gt;

&lt;p&gt;해시는 단방향성 암호화 기능이기 때문에, 변환된 해시 데이터로부터 원본을 얻을 수 없다.&lt;/p&gt;

&lt;p&gt;아래는 문자열에 SHA256 알고리즘을 이용해 해시로 변환하는 과정이다.&lt;/p&gt;

&lt;p&gt;원본 데이터 = “샨 LIP n BIP”&lt;/p&gt;

&lt;p&gt;—-해시 함수 적용—&amp;gt;&lt;/p&gt;

&lt;p&gt;변환 데이터 = “12f497ac02bbe138b507ff746d7024b79e33e4614e2cab908f371c85fe10b2d3”&lt;/p&gt;

&lt;h2 id=&quot;hash-algorithm&quot;&gt;HASH ALGORITHM&lt;/h2&gt;
&lt;p&gt;해시 알고리즘은 상황에 맞는 여러 선택지가 있다.&lt;/p&gt;

&lt;p&gt;정보의 중요성이나 변환 속도를 고려해 적절한 알고리즘을 선택해야한다.&lt;/p&gt;

&lt;p&gt;많은 서비스에서 이용하는 해시 알고리즘은 SHA-256이다.
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;md5&quot;&gt;MD5&lt;/h3&gt;

&lt;p&gt;128비트 해시 값을 생성한다.&lt;/p&gt;

&lt;p&gt;과거에 널리 사용되었으나, 현재는 심각한 보안 취약점 (충돌 공격에 취약)이 발견되어 보안 용도로는 사용하지 않는 것이 좋다.&lt;/p&gt;

&lt;p&gt;파일 무결성 검사 등 간단한 용도로는 여전히 사용될 수 있다.
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;sha-256&quot;&gt;SHA-256&lt;/h3&gt;

&lt;p&gt;256비트 해시 값을 생성하며, 현재 가장 널리 사용되는 안전한 해시 알고리즘 중 하나다.&lt;/p&gt;

&lt;p&gt;블록체인 기술(예: 비트코인)에서 주로 사용한다.
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;ripemd-160&quot;&gt;RIPEMD-160&lt;/h3&gt;

&lt;p&gt;RIPEMD-160은 160비트 해시 값을 생성하며, SHA-1과 유사한 보안 수준을 제공하는 것으로 알려져 있다.
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;whirlpool&quot;&gt;Whirlpool&lt;/h3&gt;

&lt;p&gt;512비트 해시 값을 생성하며, 강력한 보안성을 목표로 한다.
&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;bcrypt-package&quot;&gt;bcrypt package&lt;/h2&gt;
&lt;p&gt;GO에서 이용할 수 있는 패키지 중, 해시 함수를 지원하는 것이 있다.&lt;/p&gt;

&lt;p&gt;bcrypt 패키지는 비밀번호 암호화를 중점으로 둔 패키지로, 주요한 3가지 함수가 노출되어 있다.&lt;/p&gt;

&lt;p&gt;https://pkg.go.dev/golang.org/x/crypto@v0.37.0/bcrypt&lt;/p&gt;

&lt;h3 id=&quot;generatefrompassword&quot;&gt;GenerateFromPassword&lt;/h3&gt;

&lt;p&gt;주어진 비밀번호 문자열을 원본으로 이용해 해쉬 데이터를 반환한다.
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;comparehashandpassword&quot;&gt;CompareHashAndPassword&lt;/h3&gt;

&lt;p&gt;저장된 해쉬 데이터와 비밀번호 문자열에서 얻은 해쉬 데이터를 비교해 비밀번호를 비교한다.
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;cost&quot;&gt;Cost&lt;/h3&gt;

&lt;p&gt;해쉬 데이터를 만들기 위해 사용된 Cost를 반환한다.&lt;/p&gt;

&lt;p&gt;GenerateFromPassword 함수에는 Cost라는 인자가 전달되어야 한다.(4부터 31)&lt;/p&gt;

&lt;p&gt;Cost가 클수록 더 긴 해시가 생성되어 보안이 강화되는 대신, 컴퓨팅 비용이 증가한다.(Cost 값 만큼 해쉬 알고리즘이 반복되기 때문)
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;bcrypt가 유용한 이유는, 해시 데이터로 변환하기 전 원본 데이터에 salt라고 부르는 문자열을 삽입하는 기능과 Cost를 이용한 반복 해싱 때문이다.&lt;/p&gt;

&lt;p&gt;salt가 삽입되면, 해시 데이터가 완전히 달라지기 때문에 무차별 대입으로부터 보안을 강화할 수 있다.&lt;/p&gt;
</description>
      <pubDate>Sat, 10 May 2025 00:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/golang-bcrypt/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/golang-bcrypt/</guid>
    </item>
    
    <item>
      <title>GoLang, Fiber 프레임워크</title>
      <description>&lt;p&gt;Go 언어로 API 서버를 구현하기 위해서 Fiber라는 프레임워크를 사용한다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;프레임워크&quot;&gt;프레임워크&lt;/h2&gt;
&lt;p&gt;프레임워크(framework)는 특정 목적을 가진 기능을 구현하기 쉽도록 미리 만들어진 함수와 구조체의 모음이다.&lt;/p&gt;

&lt;p&gt;대표적인 프레임워크로는 [Java언어의 Spring], [Python언어의 Django], [java script언어의 React] 등이 있다.
&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;api&quot;&gt;API&lt;/h2&gt;
&lt;p&gt;API는 서버와 클라이언트 간의 데이터 교환 방식이다.&lt;/p&gt;

&lt;p&gt;API의 종류에 따라 REST API, SOAP API, GraphQL API 등이 있다.&lt;/p&gt;

&lt;p&gt;이 중 내가 구현하는 것은 REST API다.&lt;/p&gt;

&lt;p&gt;REST API는 별도의 설정 없이 HTTP 요청으로 데이터를 주고받을 수 있다는 장점이 있다.
&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;fiber&quot;&gt;Fiber&lt;/h2&gt;
&lt;p&gt;fiber는 Go서버에서 HTTP 요청을 처리하기 위한 프레임워크다.&lt;/p&gt;

&lt;p&gt;Go에서 사용할 수 있는 다른 프레임워크로 gin, echo, fasthttp 등이 있지만 서비스 확장성에 대한 장점이 있는 fiber를 사용한다.&lt;/p&gt;

&lt;p&gt;https://gofiber.io/
&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;fiber-app-init&quot;&gt;Fiber app init&lt;/h2&gt;
&lt;p&gt;fiber를 이용하기 위해서 main.go 파일에서 초기화 및 선언이 필요하다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;func main() {
// 앱 객체 선언 및 할당
app := fiber.New(fiber.Config {AppName: &amp;lt;app name&amp;gt;})

// 로깅 미들웨어 사용 설정
app.Use(logger.New(logger.ConfigDefault))

// 라우터 등록
app.Get(&quot;/&quot;, func(c fiber.Ctx) error {
return c.SendString(&quot;Hello! Here is go api server!&quot;)
})

// 라우터 그룹을 이용한 등록
router.SetupApiRoutes(app)

// 서버 실행 및 포트 지정
app.Listen(&quot;:8888&quot;)
}

func SetupApiRoutes(app *fiber.App) {
// 라우터 그룹 설정
apiGroup := app.Group(&quot;/api&quot;)

// 라우터 등록 (&quot;&quot; 으로 설정된 경우 그룹의 최상단을 의미한다.)
// 여기에서 사용한 &quot;apiGroup.Get&quot;은 Get 메서드로 요청한 데이터를 해당 라우터에서 처리한다는 의미다.
apiGroup.Get(&quot;&quot;, func(c fiber.Ctx) error { return c.JSON(&quot;api route called&quot;) })
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;fiber-request-listen&quot;&gt;Fiber request listen&lt;/h2&gt;
&lt;p&gt;fiber를 이용해서 클라이언트 요청을 받고, 데이터를 처리한 뒤 반환하는 방법은 아래와 같다.&lt;/p&gt;

&lt;p&gt;// 선행 조건 : apiGroup.Get 등으로 등록된 라우터에서 핸들러로 아래 함수 지정 및 파라미터 이름 명시&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apiGroup.Get(&quot;/:paramName&quot;, func(c fiber.Ctx) error { return c.JSON(&quot;api route called&quot;) })

func GetRequestWithParams(c fiber.Ctx) error {
// 클라이언트에서 요청과 함께 보낸 파라미터 가져오기
param := c.Params(&amp;lt;parameter name&amp;gt;)

// 가져온 파라미터를 포함한 데이터를 클라이언트에 반환
return c.JSON(fiber.Map {&quot;data&quot;: param})
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;fiber-request-handler&quot;&gt;Fiber request handler&lt;/h2&gt;
&lt;p&gt;위에서 언급한 핸들러는 데이터를 처리할 함수를 의미한다.&lt;/p&gt;

&lt;p&gt;사용 방식은 “apiGroup.Get(“”, handlerFunction)”이며,&lt;/p&gt;

&lt;p&gt;핸들러 등록 시에는 뒤에 ()를 붙여 함수 실행문을 작성하지 않아야 한다.&lt;/p&gt;

&lt;p&gt;“handlerFunction()”으로 작성할 경우 라우터 등록 시에 함수가 실행되고, 요청에 대해서는 실행되지 않는 오류가 발생한다.&lt;/p&gt;

&lt;p&gt;handlerFunction과 handlerFunction()의 차이는 함수에 대한 정보를 의미하는 것과 함수 실행을 위한 트리거를 의미하는 데에 있다.
&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;middleware&quot;&gt;middleware&lt;/h2&gt;
&lt;p&gt;fiber app init 시에 이용한 로깅 미들웨어와 같은 미들웨어는 데이터를 가로채 특정 행동을 하는 함수를 말한다.&lt;/p&gt;

&lt;p&gt;로깅 미들웨어는 요청에 대한 정보를 터미널 또는 로그 파일에 출력하는 역할을 한다.&lt;/p&gt;

&lt;p&gt;또 다른 미들웨어 예시로 request header 값을 읽고 특정 값이 없다면 400번대 응답을 반환하는 역할이 있다.(로그인 등의 사용자 인증에 사용)&lt;/p&gt;
</description>
      <pubDate>Sat, 03 May 2025 00:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/golang-fiber/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/golang-fiber/</guid>
    </item>
    
    <item>
      <title>GoLang, Fiber 프레임워크의 POST 메서드</title>
      <description>&lt;p&gt;Fiber에서는 HTTP 요청을 수신하고, 응답할 수 있다.&lt;/p&gt;

&lt;p&gt;그중 POST 메서드에 대해 다른 프레임워크와 다른 점이 있어 소개한다.&lt;/p&gt;

&lt;p&gt;(데이터를 직접 조작하지 않고 특정 구조체에 바로 할당하는 방식)
&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;fiber-listen-post-method&quot;&gt;Fiber Listen POST Method&lt;/h2&gt;
&lt;p&gt;Fiber App에서 POST Method를 수신하는 방법은 아래와 같다.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;package main
import &quot;&amp;lt;module path&amp;gt;/handler&quot;

// Fiber app 선언
app := fiber.New()
// POST 메서드를 수신하는 path 등록
app.Post(&quot;/path&quot;, handler.PostHandler)
// 로컬호스트의 포트 3000에서 앱 실행
app.Listen(&quot;:3000&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;curl-request&quot;&gt;Curl request&lt;/h2&gt;
&lt;p&gt;위 예제와 같다면 “http://localhost:3000/path”에서 POST 메서드를 수신한다.&lt;/p&gt;

&lt;p&gt;일반적으로, POST 메서드를 사용하는 경우 POST BODY에 서버에 전달할 데이터를 입력한다.&lt;/p&gt;

&lt;p&gt;Curl을 예시로 들면, 아래와 같은 요청 구문을 사용한다.&lt;/p&gt;

&lt;p&gt;“curl -H “Content-Type: application/json” -X POST http://localhost:3000/path -d ‘{&lt;json data=&quot;&quot;&gt;}&apos;&quot;&lt;/json&gt;&lt;/p&gt;

&lt;p&gt;-H “Content-Type: application/json”&lt;/p&gt;

&lt;p&gt;=&amp;gt; POST BODY의 유형이 json임을 헤더에 표시
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;-X POST&lt;/p&gt;

&lt;p&gt;=&amp;gt; HTTP 요청 메서드를 POST로 지정
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;-d ‘{&lt;json data=&quot;&quot;&gt;}&apos;&quot;&lt;/json&gt;&lt;/p&gt;

&lt;p&gt;=&amp;gt; POST BODY 데이터 입력, 헤더에서 json으로 타입을 지정했기 때문에 json으로 입력한다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;(헤더의 Content-Type를 application/json 외에 text/plain, text/html 등으로 지정할 수 있다.)&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;fiber-body&quot;&gt;Fiber Body&lt;/h2&gt;
&lt;p&gt;Fiber는 Fiber.Ctx 타입의 데이터를 인자로 받아 핸들러 함수를 호출한다.&lt;/p&gt;

&lt;p&gt;예제는 인자에서 Body 데이터를 가공하는 과정이다.&lt;/p&gt;

&lt;p&gt;Body 데이터를 []byte 타입으로 얻을 수도 있지만, 불필요한 코드를 줄이기 위해 Bind 방식을 이용한다.&lt;/p&gt;

&lt;p&gt;Bind 방식을 이용하기 위해서는 미리 입력받을 데이터의 구조체를 선언해야 한다.(PostData)&lt;/p&gt;

&lt;p&gt;구조체의 내부 변수 이름은 대문자로 시작해야 하며, json에서 이용하는 변수 이름을 따로 지정한다.&lt;/p&gt;

&lt;p&gt;(패키지 외부에서 접근하는 요소는 대문자로 시작, 내부에서만 사용하는 경우 소문자로 시작)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;!! 권장 방식은 ctx.BodyParser() 함수를 이용하는 것&lt;/strong&gt;인데, 현재 글을 작성하는 시점에서 fiver/v3가 해당 함수를 지원하지 않아 Bind().Body() 방식을 이용한다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;package handler

type PostData struct {

    Name string `json:&quot;name&quot;`

    Number int `json:&quot;number&quot;`

}

func PostHandler(ctx fiber.Ctx) error {
    // 데이터가 입력될 변수 선언
    bodyData := new(PostData)
    // 요청의 Body를 앞에서 선언한 bodyData로 할당
    ctx.Bind().Body(&amp;amp;bodyData)

    // 데이터가 제대로 할당된 경우 Name을 반환
    return ctx.SendString(bodyData.Name)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
      <pubDate>Sat, 03 May 2025 00:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/golang-fiber-post-method/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/golang-fiber-post-method/</guid>
    </item>
    
    <item>
      <title>GoLang, 변수 타입 변환</title>
      <description>&lt;p&gt;Go는 정적 타입 언어이므로 변수 선언 후 타입을 변경할 수 없다.&lt;/p&gt;

&lt;p&gt;또한, 타입의 변환 또는 반환값에 대한 타입 확인 과정이 다른 언어와 다른 점이 있다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TYPE ASSERTION&lt;/strong&gt;을 사용하는 경우&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;interface {} 타입 등의 불명확한 타입인 경우&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TYPE CONVERSION&lt;/strong&gt;을 사용하는 경우&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;int to string처럼 타입을 변환하는 경우
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;type-assertion-타입-명시&quot;&gt;TYPE ASSERTION (타입 명시)&lt;/h2&gt;
&lt;p&gt;외부 함수로부터 반환된 변수 타입을 명시하는 과정이다.&lt;/p&gt;

&lt;p&gt;예를 들어, MONGO DRIVER를 이용해 데이터를 삽입한 뒤 반환받는 InsertOneResult의 경우&lt;/p&gt;

&lt;p&gt;InsertOneResult가 가지고 있는 변수인 InsertedID를 타입 명시하는 과정이 필요하다.&lt;/p&gt;

&lt;p&gt;코드 예시에서는 result에 할당한 InsertOneResult의 InsertedID를&lt;/p&gt;

&lt;p&gt;bson.ObjectID 타입으로 명시한다.&lt;/p&gt;

&lt;p&gt;이 과정이 없다면 컴파일러가 result.InsertedID의 타입이 interface {}이므로&lt;/p&gt;

&lt;p&gt;내부 변수의 사용이 불가능하다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;result, err := collection.InsertOne(context.TODO(), document)

if err != nil {

panic(err)

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;타입-명시-코드-type-assertion&quot;&gt;타입 명시 코드 (type assertion)&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;objectID, ok := result.InsertedID.(bson.ObjectID)

if !ok {
panic(&quot;error in assertion ObjectID&quot;)
}

return objectID.string()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;type-conversion-타입-변환&quot;&gt;TYPE CONVERSION (타입 변환)&lt;/h2&gt;
&lt;p&gt;선언된 변수의 타입을 변환하는 과정이다.&lt;/p&gt;

&lt;p&gt;이미 알고 있는 타입의 변수를 다른 타입으로 변환할 때 필요하다.&lt;/p&gt;

&lt;p&gt;float64 타입을 float32 타입으로 변환해 메모리 할당을 최적화하는 등에 사용할 수 있다.&lt;/p&gt;

&lt;h3 id=&quot;float64-타입으로-변수-선언&quot;&gt;float64 타입으로 변수 선언&lt;/h3&gt;

&lt;p&gt;var float64Data float64 = 123.12345&lt;/p&gt;

&lt;h3 id=&quot;float64-타입의-변수를-float32-타입으로-변환&quot;&gt;float64 타입의 변수를 float32 타입으로 변환&lt;/h3&gt;

&lt;p&gt;var float32Data float32 = float32(float64Data)&lt;/p&gt;
</description>
      <pubDate>Wed, 30 Apr 2025 00:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/golang-variable-type-change/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/golang-variable-type-change/</guid>
    </item>
    
    <item>
      <title>GoLang, Mongo Driver</title>
      <description>&lt;p&gt;Python 프로젝트에서 데이터베이스로 Mongo를 주로 이용해 왔다.&lt;/p&gt;

&lt;p&gt;Go에서도 Mongo 데이터베이스를 이용해보려 한다.
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;mongo-특징&quot;&gt;Mongo 특징&lt;/h2&gt;
&lt;p&gt;Mongo는 No-sql 데이터베이스다.&lt;/p&gt;

&lt;p&gt;sql 데이터베이스(MySQL, Postgre)와 달리 데이터 구조를 명시하고 타입을 지정하지 않고 다양한 형태의 데이터가 저장된다.&lt;/p&gt;

&lt;p&gt;Mongo 데이터는 document 형태로 저장되는데, 단어 그대로 문서처럼 저장된다는 뜻이다.&lt;/p&gt;

&lt;p&gt;Mongo document는 BSON, (binary JSON) 타입의 문서인데,&lt;/p&gt;

&lt;p&gt;java-script 데이터 전달을 위해 만들어진 JSON을 binary 형태의 데이터가 입력되도록 변형된 타입이다.&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;go---mongo-driver&quot;&gt;Go - Mongo driver&lt;/h2&gt;
&lt;p&gt;Go에서 이용할 수 있는 Mongo driver는 공식적으로 지원되고 있다.&lt;/p&gt;

&lt;p&gt;https://www.mongodb.com/ko-kr/docs/drivers/go/current/&lt;/p&gt;

&lt;p&gt;MongoDB 고 (Go) 드라이버 - 고 (Go) 드라이버 v2.2 - MongoDB Docs&lt;br /&gt;
https://www.mongodb.com/ko-kr/docs/drivers/go/current/ 
공식 문서를 이용해 Mongodb와 Go 프로젝트를 연결해 보겠다.&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;mongo-connect&quot;&gt;Mongo Connect&lt;/h2&gt;
&lt;p&gt;Mongodb는 docker compose를 이용해 컨테이너로 실행한 상태이고,&lt;/p&gt;

&lt;p&gt;docker compose 파일 예시는 아래와 같다.&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;services:

  mongo:

    image: mongo:8.0.8-noble

    container_name: mongo

    ports:

      - 27017:27017

    volumes:

      - mongo-data:/data/db

      - mongo-setting:/data/configdb

    environment:

      MONGO_INITDB_ROOT_USERNAME: &amp;lt;user name&amp;gt;

      MONGO_INITDB_ROOT_PASSWORD: &amp;lt;user password&amp;gt;

    command: mongod --auth

volumes:

  mongo-data:

    external: false

  mongo-setting:

    external: false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;현재 설정 상, localhost의 포트 27017로 Mongodb에 접근할 수 있다.&lt;/p&gt;

&lt;p&gt;environment에 입력한 user name과 user password를 적용하면 Mongodb 접속을 위한 uri를 작성할 수 있다.&lt;/p&gt;

&lt;p&gt;“mongodb://&lt;user name=&quot;&quot;&gt;:&lt;user password=&quot;&quot;&gt;@localhost:27017&quot;&lt;/user&gt;&lt;/user&gt;&lt;/p&gt;

&lt;p&gt;uri를 Mongo driver에 입력하고 반환값을 받는 Go 코드는 아래와 같다.&lt;/p&gt;

&lt;p&gt;client, err := mongo.Connect(options.Client(). ApplyURI(uri))&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;mongo-client&quot;&gt;Mongo Client&lt;/h2&gt;
&lt;p&gt;위 과정을 통해 Mongodb와 연결을 성공하면, 반환값으로 client를 얻게 된다.&lt;/p&gt;

&lt;p&gt;Mongo client는 database 및 collection 접근을 위한 필수 연결점이다.&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;mongo-database-collection-접근&quot;&gt;Mongo database, collection 접근&lt;/h2&gt;
&lt;p&gt;client를 이용하면 database와 collection에 접근할 수 있다.&lt;/p&gt;

&lt;p&gt;(client), (database), (collection) 관계는 client -&amp;gt; database -&amp;gt; collection으로, 순서대로 접근한다.&lt;/p&gt;

&lt;p&gt;database를 얻는 방법은 아래와 같다.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;database := client.Database(&amp;lt;database name&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;collection을 얻는 방법은 아래와 같다.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;collection := database.Collection(&amp;lt;collection name&amp;gt;)&amp;lt;br/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;mongo-crud&quot;&gt;Mongo CRUD&lt;/h2&gt;
&lt;p&gt;데이터를 읽고 쓰는 작업을 CRUD(create, read, update, delete)라고 한다.&lt;/p&gt;

&lt;p&gt;위에서 얻은 collection을 이용해 CRUD 하는 방법은 아래와 같다.&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;createinsert&quot;&gt;create(insert)&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;doc := &amp;lt;입력할 데이터 구조체&amp;gt;

collection.InsertOne(context.TODO(), doc)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;read&quot;&gt;read&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;filter := &amp;lt;데이터를 찾기 위한 조건 (예: ID 또는 고유 조합 값)&amp;gt;

collection.FindOne(context.TODO(), filter)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;update&quot;&gt;update&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;filter := &amp;lt;데이터를 찾기 위한 조건 (예: ID 또는 고유 조합 값)&amp;gt;

update := &amp;lt;업데이트할 내용 (Set, Push 등의 연산자 사용)&amp;gt;

collection.UpdateOne(context.TODO(), filter, update)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;delete&quot;&gt;delete&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;filter := &amp;lt;데이터를 찾기 위한 조건 (예: ID 또는 고유 조합 값)&amp;gt;

collection.DeleteOne(context.TODO(), filter)

Find(FindOne과 다름) 반환값으로는 cursor를 얻게 되며, cursor를 통해 documentId를 얻을 수 있다.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;-바다코끼리-연산자&quot;&gt;:= 바다코끼리 연산자&lt;/h2&gt;
&lt;p&gt;Go에서는 Python처럼 := 연산자를 이용할 수 있다.&lt;/p&gt;

&lt;p&gt;모양이 바다코끼리와 비슷해서 바다코끼리(walrus) 연산자라고 부른다.&lt;/p&gt;

&lt;p&gt;이 연산자를 이용해 할당한 변수는 변수 할당과 동시에 이용할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ex) if isWalrus := checkIsWalrus(walrus) {...}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;예시에서는 if 조건으로 isWalrus를 이용하는 동시에 isWalrus에 checkIsWalrus 함수 반환값을 할당한다.&lt;/p&gt;
</description>
      <pubDate>Sat, 26 Apr 2025 00:00:00 +0900</pubDate>
      <link>https://blog.sciencebro.kr/software/golang-mongo-driver/</link>
      <guid isPermaLink="true">https://blog.sciencebro.kr/software/golang-mongo-driver/</guid>
    </item>
    
  </channel>
</rss>
