HandsLog

Log of handsupmin

오프체인 서명 검증(Off-chain Signature Verification)이란?

개요 블록체인 기술에서 모든 것을 온체인(On-chain)으로 처리하는 것은 비효율적이거나 불가능한 경우가 많음 이때 오프체인 서명 검증(Off-chain Signature Verification)은 오프체인(서버)의 유연성과 온체인(컨트랙트)의 신뢰성을 결합하는 강력한 해결책이 됨 쉽게 비유하자면, 클럽 매니저(서버)가 VIP 손님(사용자)에게만 특별한 싸인이 담긴 입장권(서명)을 발급하고, 입구의 가드(스마트 컨트랙트)는 그 싸인만 확인하고 들여보내는 것과 같음 가드는 매번 매니저에게 연락할 필요 없이, 위조되지 않은 싸인인지 확인만 하면 됨 이 글에서는 오프체인 서명 검증이 무엇인지, 어떤 용어들이 사용되는지, 그리고 가장 중요하게는 어떤 원리로 동작하는지 상세히 알아봄 ...

September 21, 2025

안전한 가스비 대납을 위한 오프체인 서명 검증 페이마스터 (in ZkSync Era)

개요 블록체인 서비스에서 사용자가 겪는 가장 큰 장벽 중 하나는 단연 가스비(Gas Fee)임 아무리 좋은 서비스를 만들어도, 사용자가 지갑에 가스비로 쓸 코인(ETH 등)을 보유하고 있어야 한다는 점은 대중화를 가로막는 결정적인 요인임 이 문제를 해결해 사용자가 가스비 걱정 없이 서비스 핵심 가치에만 집중하게 만드는 것, 즉 가스리스 트랜잭션(Gasless Transaction)을 구현하는 것이 이번 개발의 최종 목표였음 zkSync Era는 이를 위해 페이마스터(Paymaster)라는 강력한 시스템을 제공함. 페이마스터는 서비스 제공자 같은 제3자가 사용자를 대신해 트랜잭션 수수료를 지불할 수 있게 해주는 스마트 컨트랙트임 ...

September 21, 2025

SSE란? 실시간 이벤트 전달 프로토콜 (Server-Sent Events)

SSE(Server-Sent Events)란 무엇인가 SSE는 Server-Sent Events의 약자로, 서버가 클라이언트로 실시간 데이터를 단방향으로 푸시(push)할 수 있게 해주는 웹 기술임 클라이언트가 먼저 요청을 보내고 서버는 그 연결을 끊지 않은 채, 새로운 데이터가 생길 때마다 지속적으로 응답을 보내는 방식임 주로 실시간 알림, 주식 시세 업데이트, 라이브 피드 등 서버에서 클라이언트로 일방적인 데이터 전송이 필요한 경우에 매우 유용함 SSE vs 웹소켓, 그리고 한계 SSE는 실시간 이벤트 전송에 유용하지만 만능은 아님. 웹소켓과 비교했을 때 명확한 장단점이 존재함 ...

October 25, 2025

머클트리(Merkle Tree)란? 머클트리의 개념과 블록체인에서의 역할

개요 머클트리는 블록체인에서 거래 집합을 안전하고 효율적으로 요약·검증하기 위해 쓰이는 핵심 자료구조임 블록 헤더에 머클루트가 포함되는 이유는 블록 안의 모든 거래를 고정 크기 해시 하나로 대표해 무결성 확인과 경량 검증을 가능하게 하기 때문임 이 글은 머클트리의 구조와 동작 원리, 블록체인에서의 실무적 의미와 구현 주의사항까지 초보자도 이해할 수 있도록 상세히 설명함 핵심 개념과 구조 머클트리는 보통 이진 트리 형태로 구현함 거래들을 리프(leaf) 로 두고 인접 두 리프의 해시를 이어 붙여 부모 해시를 만들며 이 과정을 반복해 루트 해시를 얻음 해시 함수는 체인별로 다르며 비트코인은 더블 SHA‑256, 이더리움은 트라이 구조에서 Keccak‑256 을 사용함 최상단 해시를 머클루트(Merkle root) 라 부르며 크기는 해시 함수에 따라 고정됨 리프 수가 홀수일 때는 마지막 리프를 복제해 짝을 맞추는 방식이 일반적이며 비트코인은 이 규칙을 사용함 트리 깊이는 리프 수 N에 대해 ⌈log₂ N⌉ 에 비례하므로 대량의 거래를 효율적으로 요약할 수 있음 동작 원리와 장점 인접 노드 해시 H_left || H_right 를 순서대로 연결해 해시를 계산하고 이를 위로 올려가며 루트 해시를 얻음 무결성 검증 단일 거래가 바뀌면 해당 리프에서 루트까지의 모든 경로 해시가 바뀌어 변조를 즉시 탐지할 수 있음 효율적 포함 증명 특정 거래가 블록에 포함되었음을 증명하려면 그 거래와 경로상의 형제 해시들만 있으면 됨 필요한 해시 개수는 O(log N) 으로 작아 대역폭과 검증 비용이 작음 확장성 보조 리프가 1,000,000개여도 증명에 필요한 형제 해시는 약 20개 수준으로 32바이트 해시 기준 약 640바이트에 불과함 블록 헤더와 경량 노드(SPV) 비트코인 블록 헤더는 이전 블록 해시, 머클루트, 난스 등 합의 관련 메타데이터를 포함함 경량 노드(SPV)는 블록 전체가 아니라 헤더 체인만 받아 신뢰성을 확보하고, 개별 거래에 대해서는 풀노드로부터 머클 증명 을 받아 포함 여부를 검증함 이 방식은 모바일·임베디드 환경에서도 실사용이 가능하게 하는 기반이 됨 이더리움은 전통적인 이진 머클트리 대신 머클‑패트리샤 트라이(MPT) 를 사용해 거래·영수증·상태 루트를 헤더에 담아 유사한 목적을 달성함 구현 세부와 체인별 차이 비트코인 ...

September 20, 2025

MySQL 테이블 이름 변경 RENAME TABLE vs ALTER TABLE 정리

개요 테이블 이름 변경은 ALTER TABLE로도 가능하지만, RENAME TABLE을 쓰면 다수 테이블을 한 번에 처리 가능하며 같은 서버 내 다른 데이터베이스로 이동까지 가능함 핵심 차이 ALTER TABLE RENAME은 단일 테이블 대상 RENAME TABLE은 여러 테이블을 한 문장으로 변경 가능 스키마 간 이동 지원 current_db.table에서 other_db.table로 변경 가능 동일 트랜잭션처럼 동작하는 원자성 제공, 다중 변경 중 하나라도 실패 시 전체 미적용 권한 요구 사항 존재, 원본 테이블에 ALTER와 DROP, 대상 스키마에 CREATE 권한 필요 트리거와 외래키 메타데이터는 함께 유지되나, 뷰나 저장 프로시저의 하드코딩된 참조는 자동 갱신되지 않음 사용법 단일 테이블 이름 변경 RENAME TABLE old_table TO new_table; 단일 테이블 이름 변경 ALTER 사용 ALTER TABLE old_table RENAME new_table; 다수 테이블 이름 일괄 변경 RENAME TABLE old_table1 TO new_table1, old_table2 TO new_table2, old_table3 TO new_table3; 다른 데이터베이스로 이동 같은 서버 내 RENAME TABLE current_db.table_name TO other_db.table_name; 주의 사항 대상 이름이 이미 존재하면 실패 교차 서버 이동 불가, 같은 서버 인스턴스 내 스키마 간 이동만 가능 실행 시 메타데이터 락 획득, 짧은 구간 동안 읽기나 쓰기 대기 가능 배치 변경 전 사전 검증 권장, 이름 충돌 여부와 권한 확인 뷰나 프로시저 참조는 수동 점검 필요, 린트나 간단한 탐색 쿼리로 영향 범위 확인 권장 정리 단일 변경만 필요하면 ALTER로 충분하나, 다수 변경이나 스키마 이동까지 고려하면 RENAME TABLE이 더 실용적 선택 원자적 일괄 변경과 스키마 간 이동을 활용하되, 권한과 의존성 영향 검증을 선행할 것 ...

November 24, 2025

Prisma에는 왜 JOIN이 없을까: ORM 패턴, 스키마, 내부 동작 정리

개요 Prisma로 관계형 데이터베이스를 다루다 보면 자연스럽게 드는 질문이 있음 Prisma에서는 JOIN이 어디로 갔나 하는 질문임 개발자가 작성하는 Prisma Client API에는 JOIN이 없고, 서브쿼리도 보이지 않음 정말로 없는지, 없다면 왜 그런지, 어떤 트레이드오프가 있는지 정리함 ORM이란 무엇인가 ORM은 객체와 관계형 데이터베이스 간의 매핑을 제공하는 아이디어이자 구현체 집합을 의미함 애플리케이션에서 모델을 통해 데이터베이스 테이블을 간접 제어하는 추상화 계층 제공 SQL을 직접 작성하지 않고 데이터 접근 로직을 일관된 API로 수행 가능 데이터베이스 의존성 완화 효과 기대 ...

November 23, 2025

Prisma Client index.d.ts로 읽는 ObjektInventory 집계·그룹화 타입 구조

@prisma/client의 index.d.ts 개요 Prisma Client가 생성하는 index.d.ts는 모델별 쿼리 메서드와 그 입출력 타입을 정의하는 타입 소스임 여기서는 예시 모델 ObjektInventory를 기준으로 집계 aggregation, 그룹화 groupBy, 카운트 count, 조회 find 계열 메서드의 타입 구조와 사용 맥락 정리 핵심은 타입 안전성과 결과 형태의 명시적 제어이며, 모든 타입은 Prisma 스키마를 기반으로 자동 생성됨 핵심 개념 Aggregation 집계 평균, 합, 최소, 최대, 카운트 같은 통계 요약 계산 결과 형태를 명확히 보장하는 Output 타입과 어떤 필드를 집계할지 지정하는 Input 타입으로 구성 Group By 그룹화 특정 필드 기준으로 그룹 묶음 생성 후 각 그룹에 집계 적용 입력 인자 검증이 엄격하며 by, orderBy, having, take, skip 조합 규칙 존재 Count 카운트 조건에 맞는 레코드 개수 반환 _count를 다른 집계와 함께 요청하거나 단독 count 메서드로 호출 가능 Find 조회 findUnique, findFirst, findMany로 조건, 정렬, 페이징, select, include를 조합해 조회 반환 타입은 선택한 필드와 관계에 따라 좁혀짐 타입 구조와 동작 집계 결과 타입 ObjektInventoryAvgAggregateOutputType, ObjektInventorySumAggregateOutputType, ObjektInventoryMinAggregateOutputType, ObjektInventoryMaxAggregateOutputType, ObjektInventoryCountAggregateOutputType 등으로 구성 각 필드는 해당 타입의 스칼라값 또는 null을 가질 수 있음 집계 입력 타입 ObjektInventoryAvgAggregateInputType, ObjektInventorySumAggregateInputType 등에서 true로 지정한 필드만 결과에 포함됨 그룹화 인자와 출력 타입 ObjektInventoryGroupByArgs에 by로 그룹 기준 필드 지정, _count, _avg, _sum, _min, _max 중 필요한 집계 선택 출력은 ObjektInventoryGroupByOutputType으로 각 그룹 키 필드 + 선택한 집계 결과 반환 조회 인자 타입 ObjektInventoryFindUniqueArgs, ObjektInventoryFindFirstArgs, ObjektInventoryFindManyArgs에서 where, orderBy, cursor, take, skip, select, include 등을 타입 안전하게 지정 메서드 반환 타입 추론 제네릭과 조건부 타입을 통해 선택한 select 또는 집계 키에 맞춰 반환 타입이 자동으로 좁혀짐 _count를 true로 둘 경우 숫자 반환, 객체 형태를 원하면 _count { _all: true } 형태 사용 사용 예시 집계 예시 const aggregationResult = await prisma.objektInventory.aggregate({ _avg: { objektId: true }, _sum: { lenticularPairTokenId: true }, where: { owner: 'john' }, }) 그룹화 예시 const groupByResult = await prisma.objektInventory.groupBy({ by: ['status'], _count: { _all: true }, _avg: { objektId: true }, }) 카운트 예시 const totalCount = await prisma.objektInventory.count({ where: { owner: 'john' }, }) 조건부 조회 예시 const inventories = await prisma.objektInventory.findMany({ where: { owner: 'john' }, orderBy: { updatedAt: 'desc' }, take: 10, }) 제약과 주의 사항 groupBy 규칙 by에 포함되지 않은 필드로 orderBy 또는 having을 사용할 수 없음 take 또는 skip을 사용하는 경우 orderBy 필수 런타임 전 타입 레벨에서 오류로 차단되어 쿼리 일관성 확보 null 가능성 집계 결과는 조건에 맞는 레코드가 없으면 각 필드가 null이 될 수 있음 연산 전 null 체크 필요 _count 반환 형태 _count: true는 숫자 단일 값, _count: { _all: true }는 카운트 내역을 가진 객체 반환 사용 목적에 맞는 형태 선택 권장 성능 고려 불필요한 필드 조회 지양, select로 최소화 where 조건에 인덱스 친화적 필드 사용 권장 대규모 groupBy는 데이터베이스 리소스 부담 가능, 필요한 필드와 조건만 사용 타입 안전성 스키마 변경 시 재생성된 index.d.ts를 기준으로 컴파일 타임 검증 수행 any 캐스팅으로 타입 보호 우회 금지 맥락과 활용 포인트 데이터 분석 워크로드에서 서버 측 집계 활용으로 불필요한 애플리케이션 레벨 후처리 감소 리포트, 대시보드, 통계 API에서 groupBy + 다중 집계 조합이 유용 타입 정의가 강제하는 인자 조합 규칙으로 런타임 쿼리 오류를 사전에 방지 가능 반환 타입이 선택된 입력에 따라 좁혀지므로 응답 스키마를 명확히 설계 가능 마무리 ObjektInventory를 예로 본 index.d.ts의 집계와 그룹화 타입은 Prisma Client가 제공하는 타입 안전 쿼리의 핵심 축임 입력 타입으로 의도를 명시하고, 출력 타입으로 결과 스키마를 보장하는 흐름이 데이터 품질과 안정성을 높임 그룹화 규칙과 _count 반환 형태, null 가능성 같은 세부 제약만 지키면 복잡한 통계 요구사항도 간결하게 커버 가능 ...

November 22, 2025

JavaScript Promise.all과 Map 정리 – 동시 비동기 처리와 키-값 컬렉션 기본

개요 여러 비동기 작업을 한 번에 묶어 처리하거나 결과를 모아야 하는 경우가 잦음 키-값 기반으로 데이터를 구조화해 저장하고 순회해야 하는 요구도 흔함 이 글은 Promise.all의 동작과 주의점, Map의 핵심 사용법을 개발자 관점에서 요약 정리함 Promise.all 개념과 정의 여러 Promise를 단일 Promise로 집계하는 유틸리티 모든 입력이 이행되면 결과를 같은 순서의 배열로 반환 하나라도 거부되면 즉시 거부로 끝나는 fail fast 특성 보유 입력은 Promise와 값 혼합 가능하며 값은 내부적으로 Promise.resolve로 이행 처리됨 ...

November 21, 2025

MECE 개념 정리: 상호배제와 전체포괄로 구조화하는 분류 원칙

개요 MECE는 Mutually Exclusive Collectively Exhaustive의 약자이며 상호배제와 전체포괄을 뜻함 겹치지 않게 나누되 합치면 전체가 되는 분류 원칙을 말함 영어권에서는 미씨로 읽고, 한국어로는 엠이씨이 또는 미시로 불림 컨설팅 실무에서 대중화된 사고 틀로 문제 분해, 요건 정의, 케이스 분류에 자주 사용됨 개념과 정의 상호배제는 요소들이 서로 겹치지 않는 상태를 의미함 중복 없이 하나의 요소가 정확히 하나의 범주에만 속함 전체포괄은 분류된 요소들을 모두 합치면 전체 모수를 빠짐없이 덮는 상태를 의미함 누락 없이 전체 공간을 커버하는 분할이 목표임 ...

November 20, 2025

MSA 설계와 운영의 핵심 난제 3가지와 실전 해결 전략

개요 MSA의 기술적 어려움은 결국 분산 시스템의 어려움과 동일함 네트워크는 불안정, 데이터는 서비스별로 분산, 한 번의 요청이 여러 프로세스를 통과하는 구조 특성상 실패와 지연이 쉽게 전파됨 리더급 실무 경험을 검증하려면 이 분산 시스템의 고통을 직접 다뤄본 흔적이 있는지 확인해야 함 아래는 실무 난이도가 높은 세 영역과 면접 시 검증 포인트, 실전형 답변 예시 정리 분산 트랜잭션과 데이터 정합성 핵심 맥락 모놀리식에서는 단일 DB 트랜잭션으로 주문·결제·재고 감소를 한 번에 처리 가능 MSA에서는 주문 서비스 DB, 결제 서비스 DB, 재고 서비스 DB가 분리되어 원자적 커밋 불가 일부 단계 성공 후 후속 단계 실패 시 이미 성공한 작업을 어떻게 보상할지 정의 필요 면접에서 확인할 질문 ...

November 19, 2025