Front-end/UI UX
암호화폐 UI 표시의 숨은 고민: toFixed vs toFormat
2026.01.27
암호화폐 거래소에서 마주친 숫자 표시 문제암호화폐 거래소 프로젝트를 진행하다 보면 누구나 한 번쯤 마주치는 문제가 있습니다. 사용자가 화면에서 보는 "1,234.56789"라는 숫자가 단순해 보이지만, 이를 정확하게 표시하는 것은 생각보다 복잡합니다. JavaScript의 기본 toFixed() 메서드로는 천 단위 구분자를 자동으로 추가할 수 없고, 부동소수점 연산의 한계로 인해 정밀도 문제가 발생하기 때문입니다.왜 일반 JavaScript의 toFixed()로는 부족한가?JavaScript의 부동소수점 연산은 악명 높은 정밀도 문제를 가지고 있습니다. 가장 유명한 예시가 바로 이것입니다:console.log(0.1 + 0.2); // 0.30000000000000004console.log((0.1 + ..
Blockchain
Ethers.js 없이 ERC-20 토큰 단위 변환하기
2026.01.26
최근 프로젝트에서 USDC 같은 ERC-20 토큰을 지원해야 하는 상황이 생겼습니다. Web3.js의 fromWei/toWei를 사용하고 있었는데, 이 함수들이 임의의 decimals를 다루기에는 너무 불편하다는 걸 깨달았죠. Ethers.js를 추가할까 고민하다가, 결국 직접 구현하기로 결정했습니다. 그 과정과 이유를 공유합니다.Wei란 무엇인가?블록체인을 다루다 보면 항상 마주치는 개념이 바로 "최소 단위"입니다. 이더리움에서는 이를 Wei라고 부르는데, 1 Ether는 정확히 (10^{18}) Wei입니다. 왜 이렇게 큰 숫자를 사용할까요? 소수점 연산의 부정확성을 피하고, 아주 작은 금액도 정확하게 표현하기 위해서입니다.이더리움만의 이야기는 아닙니다. 다른 블록체인들도 각자의 최소 단위를 가지고 ..
Blockchain
블록체인 도메인 개발자가 JSON-RPC를 꼭 알아야 하는 이유
2026.01.26
블록체인 dApp을 개발하면서 Web3.js나 ethers.js를 사용하다 보면, 내부적으로 어떤 방식으로 블록체인 노드와 통신하는지 궁금해지실 겁니다. 오늘은 그 핵심에 있는 JSON-RPC 프로토콜에 대해 알아보겠습니다.1. JSON-RPC란 무엇인가?정의와 역사JSON-RPC는 JavaScript Object Notation-Remote Procedure Call의 약자로, 원격 프로시저 호출을 위한 가볍고 간단한 프로토콜입니다. 쉽게 말하면, 네트워크를 통해 다른 컴퓨터에 있는 함수를 마치 내 컴퓨터에 있는 것처럼 호출할 수 있게 해주는 규칙이라고 보시면 됩니다.JSON-RPC는 stateless하고 light-weight한 특징을 가지고 있으며, transport에 구애받지 않아서 HTTP, W..
Front-end/NextJS
모바일과 PC를 동시에 지원하는 적응형 Tooltip 컴포넌트 만들기
2026.01.12
1. 들어가며웹 개발을 하다 보면 하나의 UI 컴포넌트로 여러 환경을 지원해야 하는 상황이 자주 발생합니다. 특히 모바일과 데스크톱을 동시에 고려해야 할 때가 그렇죠.이번 글에서는 입력 방식에 따라 자동으로 Tooltip 또는 Popover를 렌더링하는 적응형 컴포넌트를 구현한 경험을 공유하려고 합니다. 마우스가 있는 환경에서는 hover 기반 Tooltip을, 터치만 가능한 환경에서는 클릭 기반 Popover를 자동으로 선택하는 컴포넌트입니다.2. 문제 상황: Tooltip이 모바일에서 동작하지 않는다PWA로 모바일과 PC를 동시 지원하는 과정에서제 경우는 PWA(Progressive Web App)를 개발하면서 이 문제를 마주쳤습니다. PWA는 하나의 웹 코드로 모바일 앱처럼 설치도 가능하고, 데스크..
WebCommon
Passkey 이해하기 2 - 코드로 배우는 실전 구현
2025.12.24
이 글에서는 실제 동작하는 Passkey 데모 프로젝트를 통해 등록과 로그인을 어떻게 구현하는지 알아본다.전체 코드는 GitHub 레포지토리에서 확인할 수 있다.전체 플로우 한눈에 보기Passkey 등록 플로우1. 클라이언트: 사용자 이름 입력 후 "등록" 버튼 클릭 ↓2. 클라이언트 → 서버: POST /register/start { username } ↓3. 서버: challenge 생성 및 PublicKeyCredentialCreationOptions 반환 ↓4. 클라이언트: navigator.credentials.create() 호출 → 생체 인증 진행 ↓5. 브라우저: 공개키/비밀키 쌍 생성, 비밀키는 디바이스에 저장 ↓6. 클라이언트 → 서버: POST /register/fi..