콘텐츠 대표 이미지 - 블록체인과 웹3로 만드는 탈중앙화 웹 애플리케이션(dApp) 완전정복
프로그램개발 · 홈페이지/웹개발

블록체인과 웹3로 만드는 탈중앙화 웹 애플리케이션(dApp) 완전정복

서버가 없어도 돌아가는 웹, 로그인 버튼 대신 지갑 연결 버튼.
웹 개발자의 눈으로 바라본 Web3의 실제 구조와 현실적인 구현법을 파헤칩니다.

0. 시작하기 전에 — "탈중앙"이라는 단어의 오해 풀기

웹 개발을 몇 년 해본 사람이라면 Web3라는 단어를 들었을 때 두 가지 감정이 동시에 든다.
하나는 "또 마케팅 용어인가?", 다른 하나는 "그래도 스마트 컨트랙트는 진짜 신기하던데?"

결론부터 말하자면 둘 다 맞다.
Web3 생태계에는 거품이 많았고, 동시에 기술적으로는 명백히 새로운 것이 있었다.
그 새로운 것의 핵심은 단 하나다.

"서버 운영자를 신뢰하지 않아도, 애플리케이션의 상태 변화가 규칙대로 실행됨을 검증할 수 있다."

기존 웹 애플리케이션은 운영 주체에 대한 신뢰 위에 서 있다.
우리가 은행 앱에 잔액이 100만 원이라고 표시되는 걸 믿는 이유는, 은행이라는 기관과 감독기관이 있기 때문이다.
dApp(Decentralized Application)은 그 신뢰를 코드와 합의 알고리즘으로 대체하려는 시도다.

다만 여기서 반드시 짚고 가야 할 팩트가 있다.
현실의 dApp은 100% 탈중앙화되어 있지 않다.
프론트엔드는 대부분 중앙 서버나 CDN에서 서빙되고, 데이터 조회는 인덱서 API를 쓰며, RPC 노드도 특정 업체(Infura, Alchemy 등)에 의존하는 경우가 절대다수다.
즉 "탈중앙화 스펙트럼" 위에서 어디쯤에 위치할지를 설계하는 것이 개발자의 진짜 일이다.

탈중앙화 스펙트럼 : 어디까지 분산할 것인가 Web2 하이브리드 온체인 중심 풀 온체인 DB + API 서버 세션 로그인 운영사 신뢰 속도 ★★★★★ 자산·권한만 온체인 콘텐츠는 IPFS/DB 지갑 + 서버 혼용 실무 채택률 최고 핵심 로직 컨트랙트 인덱서로 조회 DAO 거버넌스 검증성 ★★★★ 상태 전부 체인에 기록 비용 폭증 희소 사례

1. dApp의 해부학 — 레이어별로 뜯어보기

웹 개발자에게 가장 빠른 이해 방법은 기존 3-tier 구조와 대응시키는 것이다.

역할Web2 스택Web3(dApp) 스택
프론트엔드React / Vue / Next.jsReact / Next.js + wagmi·viem·ethers.js
인증세션·JWT·OAuth지갑 서명(EIP-4361 SIWE)
백엔드 로직Node/Spring/Django스마트 컨트랙트(Solidity, Rust)
데이터베이스MySQL / PostgreSQL체인 상태(storage) + 인덱서(The Graph 등)
파일 스토리지S3 / NCP Object StorageIPFS / Arweave
서버 통신REST / GraphQLJSON-RPC (eth_call, eth_sendRawTransaction)
배포CI/CD → 서버 교체컨트랙트 배포는 사실상 불변(프록시 패턴 필요)

1-1. 프론트엔드는 여전히 "그냥 웹"이다

많은 사람이 오해하는 부분이다.
dApp의 UI는 React나 Next.js로 만든 평범한 SPA다.
차이는 딱 하나, 백엔드 API를 호출하는 대신 블록체인 노드에 JSON-RPC를 호출한다는 것.

// 기존 Web2
const res = await fetch('/api/balance');

// Web3 (viem 기준)
import { createPublicClient, http } from 'viem';
import { mainnet } from 'viem/chains';

const client = createPublicClient({
  chain: mainnet,
  transport: http('https://eth.llamarpc.com')
});

const balance = await client.readContract({
  address: '0xTokenAddress',
  abi: erc20Abi,
  functionName: 'balanceOf',
  args: ['0xUserAddress']
});

여기서 중요한 개념이 read와 write의 분리다.
읽기(eth_call)는 무료이고 즉시 응답한다. 노드에서 로컬 실행만 하기 때문이다.
쓰기(트랜잭션)는 가스비가 들고, 블록에 포함될 때까지 기다려야 한다.

UX 관점의 핵심 함의

Web2에서 POST 요청은 보통 100~300ms면 끝난다.
그러나 dApp의 쓰기 작업은 ① 지갑 팝업 → ② 사용자 서명 → ③ 멤풀 대기 → ④ 블록 포함 → ⑤ 확정(confirmation)의 5단계를 거친다.
이더리움 메인넷 기준 12초 블록타임, L2는 0.2~2초 수준.
즉 "로딩 스피너 하나로 퉁치면 안 되는" 다단계 상태 UI가 필수다.

1-2. 스마트 컨트랙트 = 배포 후 수정 불가능한 백엔드

스마트 컨트랙트는 EVM(Ethereum Virtual Machine) 위에서 실행되는 바이트코드다.
개발자는 보통 Solidity로 작성하고 컴파일해서 배포한다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract Guestbook {
    struct Entry { address writer; string message; uint256 time; }
    Entry[] private entries;

    event Posted(address indexed writer, string message, uint256 time);

    function post(string calldata message) external {
        require(bytes(message).length <= 200, "too long");
        entries.push(Entry(msg.sender, message, block.timestamp));
        emit Posted(msg.sender, message, block.timestamp);
    }

    function total() external view returns (uint256) {
        return entries.length;
    }
}

이 코드에서 웹 개발자가 주목해야 할 포인트는 세 가지다.

① msg.sender가 곧 인증이다.
별도의 로그인 로직이 없다. 트랜잭션에 서명한 지갑 주소가 자동으로 들어온다.
서명 검증은 노드가 이미 수행했으므로 위조가 구조적으로 불가능하다.

② event는 사실상 "인덱싱용 로그"다.
컨트랙트 storage를 순회해 검색하는 것은 가스비가 비싸고 느리다.
그래서 실무에서는 이벤트를 찍고, 오프체인 인덱서가 이를 수집해 조회 API를 제공한다.
event는 Web3판 "쓰기 전용 로그 테이블"이라고 생각하면 정확하다.

③ 배포 후 코드는 바꿀 수 없다.
버그가 있어도 패치 배포가 불가능하다.
그래서 프록시 패턴(UUPS, Transparent Proxy)을 쓴다.
로직 컨트랙트와 저장소 컨트랙트를 분리하고, delegatecall로 연결해 로직만 교체하는 방식이다.
다만 이는 업그레이드 권한자가 곧 중앙 권력이 된다는 역설을 낳는다. 그래서 타임락(Timelock) + 멀티시그로 권한을 제한하는 것이 표준 관행이다.

2. 지갑 연결과 SIWE — "로그인 버튼"의 재발명

홈페이지 개발에서 가장 먼저 만나는 Web3 요소는 지갑 연결이다.
과거에는 window.ethereum을 직접 만졌지만, 지금은 표준화가 상당히 진행됐다.

2-1. EIP-1193과 EIP-6963

EIP-1193은 지갑 Provider의 공통 인터페이스 규격이다.
request({ method, params }) 형태의 단일 진입점을 정의한다.

문제는 지갑이 여러 개 설치된 경우였다. 메타마스크, Rabby, Coinbase Wallet이 서로 window.ethereum을 덮어써서 충돌이 났다.
이를 해결한 것이 EIP-6963(Multi Injected Provider Discovery)이다.
각 지갑이 자신을 이벤트로 "방송"하고, dApp이 이를 수집해 목록으로 보여주는 구조다.
요즘 지갑 선택 모달에 아이콘이 쭉 뜨는 건 대부분 이 규격 덕분이다.

2-2. SIWE(Sign-In with Ethereum, EIP-4361)

지갑을 연결했다고 해서 인증이 끝난 것은 아니다.
주소는 공개 정보라서, 누군가 남의 주소를 "내 주소"라고 서버에 주장할 수 있다.
따라서 서버 세션이 필요한 경우 반드시 서명 기반 인증을 거쳐야 한다.

SIWE 흐름

1) 서버가 nonce(1회용 난수)를 발급한다.
2) 클라이언트가 도메인·주소·nonce·만료시각이 담긴 규격화된 메시지를 만든다.
3) 사용자가 지갑으로 personal_sign 서명한다. 가스비 0원.
4) 서버가 서명에서 주소를 복구(ecrecover)해 일치 여부와 nonce 유효성을 검증한다.
5) 검증되면 세션/JWT 발급.

보안 체크리스트

· nonce는 반드시 서버 생성 + 1회 사용 후 폐기. 재사용 시 리플레이 공격에 노출된다.
· 메시지에 domain과 uri를 포함해 피싱 사이트 서명 유도를 방지한다.
· 스마트 컨트랙트 지갑(AA 지갑)은 개인키 서명이 없으므로 EIP-1271 isValidSignature 방식으로 검증해야 한다.
· 절대로 "이 서명 하면 로그인됩니다" 같은 불투명한 메시지를 쓰지 말 것. 사용자 교육 차원에서도 나쁘다.

2-3. 계정 추상화(ERC-4337)가 바꾼 UX

dApp UX 최대의 적은 "가스비를 내려면 먼저 토큰이 있어야 한다"는 닭과 달걀 문제였다.
신규 사용자는 지갑을 만들자마자 잔액 0원이라 아무것도 못 한다.

ERC-4337(Account Abstraction)은 프로토콜 변경 없이 이 문제를 풀었다.
핵심 구성요소는 다음과 같다.

구성요소역할
UserOperation일반 트랜잭션 대신 사용하는 "의도" 객체
Bundler여러 UserOperation을 모아 실제 트랜잭션으로 제출
EntryPoint검증·실행을 담당하는 표준 싱글톤 컨트랙트
Paymaster가스비 대납 또는 USDC 등으로 대체 결제

Paymaster 덕분에 "가스비 무료 체험"이 가능해졌고,
스마트 컨트랙트 지갑이므로 소셜 복구, 지출 한도, 세션 키 같은 기능도 구현할 수 있다.
게임 dApp에서 매번 서명 팝업이 뜨지 않는 이유가 바로 세션 키다.

2024년 이더리움 Dencun 업그레이드 이후에는 EIP-7702 논의가 본격화되어,
기존 EOA(일반 지갑)도 일시적으로 컨트랙트 코드를 위임받아 AA 기능을 쓸 수 있는 방향으로 진화 중이다.

3. 데이터 계층 — 온체인·오프체인 분리 설계

여기가 실무 아키텍처의 진짜 승부처다.
초보 설계자가 가장 많이 하는 실수는 "모든 걸 체인에 올리자"다.

3-1. 왜 모든 걸 올리면 안 되는가

EVM 스토리지에 32바이트 슬롯 하나를 새로 쓰는 비용은 20,000 gas다.
문자열 1KB를 저장하려면 수십만 gas가 든다.
메인넷 가스비가 30 gwei, ETH 가격이 400만 원이라 가정하면,
게시글 하나 저장에 수천 원~수만 원이 나갈 수 있다.
게다가 모든 노드가 영원히 그 데이터를 복제 보관해야 하므로 네트워크 전체에 부담이다.

황금 규칙

온체인에는 ①소유권 ②잔액 ③권한 ④검증 가능한 해시 ⑤합의가 필요한 규칙만 올린다.
본문·이미지·프로필 같은 대용량 콘텐츠는 IPFS/Arweave에, 검색·필터링용 복제본은 오프체인 DB에 둔다.

3-2. IPFS와 콘텐츠 주소 지정(CID)

IPFS는 파일 위치(URL)가 아니라 내용의 해시(CID)로 데이터를 가리킨다.
같은 파일은 어디에 있든 같은 CID를 갖고, 내용이 1바이트라도 바뀌면 CID가 완전히 달라진다.
즉 변조를 원천적으로 감지할 수 있다.

현실 체크

IPFS는 영구 저장소가 아니다.
아무도 핀(pin)하지 않으면 데이터는 가비지 컬렉션으로 사라진다.
그래서 Pinata, Filebase, web3.storage 같은 피닝 서비스를 쓰거나 직접 노드를 운영해야 한다.
진짜 영구성이 필요하면 선불 저장 모델인 Arweave를 검토하라.
과거 다수의 NFT 프로젝트가 메타데이터를 중앙 서버 URL로 두었다가 서비스 종료와 함께 이미지가 깨진 사례가 실제로 있었다.

3-3. 인덱서 — dApp의 숨은 백엔드

"이 사용자가 보유한 NFT를 최신순으로 20개 보여줘."
이 쿼리를 체인에 직접 던지는 것은 불가능에 가깝다. 체인에는 SQL이 없다.

그래서 The Graph 같은 인덱싱 프로토콜이 등장했다.
동작 원리는 이렇다.

1) Subgraph 매니페스트에 감시할 컨트랙트 주소와 이벤트를 정의한다.
2) 이벤트가 발생하면 AssemblyScript로 작성한 매핑 핸들러가 실행된다.
3) 핸들러가 엔티티를 저장하면 내부 PostgreSQL에 쌓인다.
4) 개발자는 GraphQL로 조회한다.

query {
  transfers(first: 20, orderBy: timestamp, orderDirection: desc,
            where: { to: "0xabc..." }) {
    id
    tokenId
    from
    timestamp
  }
}

결국 dApp 개발의 절반은 "이벤트 설계"다.
어떤 값을 indexed로 둘지(최대 3개), 어떤 정보를 로그에 남길지에 따라
나중에 만들 수 있는 화면의 범위가 결정된다.
컨트랙트를 배포한 뒤에 이벤트를 추가하는 건 불가능하므로,
DB 스키마 설계보다 훨씬 신중해야 한다.

dApp 레퍼런스 아키텍처 브라우저 UI Next.js + wagmi 지갑 EIP-1193 / 6963 Paymaster ERC-4337 가스 대납 RPC 노드 JSON-RPC 게이트웨이 인덱서 GraphQL 조회 IPFS / Arweave 콘텐츠 주소 저장 블록체인 (L1 / L2 롤업) 스마트 컨트랙트 · 상태 · 이벤트 로그

4. 확장성 — L2 롤업이 dApp을 현실화했다

2021년 NFT 붐 당시 이더리움 메인넷의 단순 전송 수수료가 수만 원까지 치솟았다.
"탈중앙 앱"이라면서 클릭 한 번에 커피값이 나가니 대중화가 될 리 없었다.

4-1. 롤업의 원리

롤업은 실행은 L2에서, 데이터와 최종 정산은 L1에서 하는 구조다.
수백~수천 건의 트랜잭션을 묶어 압축한 뒤 L1에 올리므로 고정비를 N분의 1로 나눈다.

구분Optimistic 롤업ZK 롤업
검증 방식일단 유효하다 가정, 이의제기 기간 운영영지식 증명으로 수학적 검증
출금 지연보통 7일(챌린지 기간)증명 생성 후 수십 분~수 시간
대표 체인Arbitrum, Optimism, BasezkSync, Scroll, Linea, Polygon zkEVM
EVM 호환거의 완전 호환zkEVM으로 빠르게 수렴 중

4-2. EIP-4844(Proto-Danksharding)의 임팩트

2024년 3월 Dencun 업그레이드로 도입된 블롭(blob) 트랜잭션은 L2 비용 구조를 뒤집었다.
기존에는 L2가 데이터를 L1 calldata에 기록해 비쌌지만,
블롭은 약 18일 후 삭제되는 임시 데이터 공간을 별도 수수료 시장으로 분리했다.

결과는 극적이었다. 주요 L2의 트랜잭션 수수료가 평균 90% 이상 하락했고,
체감 비용이 수십 원 이하로 떨어졌다.
이때부터 소셜·게임·티켓팅처럼 트랜잭션이 잦은 dApp이 현실적으로 가능해졌다.

개발자 선택 가이드

· 고액 자산·DeFi 코어 → L1 또는 검증된 L2
· 커뮤니티·포인트·뱃지 → 저렴한 L2 (Base, Arbitrum 등)
· 초당 수백 건 게임 로직 → 앱체인·L3 또는 오프체인 처리 후 정산
· 멀티체인 대응 시 wagmi의 chain 설정과 컨트랙트 주소 매핑을 환경변수로 분리해두면 유지보수가 훨씬 쉽다.

5. 보안 — Web3에서는 버그가 곧 돈이다

웹 개발에서 SQL 인젝션이 터지면 데이터가 유출된다. 심각하다.
그런데 스마트 컨트랙트에서 버그가 터지면 금고가 통째로 비워지고, 되돌릴 수 없다.
체인 분석 업체들의 연례 보고에 따르면 DeFi 해킹 피해는 매년 수억~수십억 달러 규모로 집계된다.

5-1. 대표 취약점 TOP 5

① 재진입(Reentrancy)
외부 호출 도중 공격자가 다시 함수를 호출해 잔액 차감 전에 반복 인출하는 고전적 공격.
해법은 Checks-Effects-Interactions 패턴: 검증 → 상태 변경 → 외부 호출 순서를 지키고, ReentrancyGuard를 병행한다.

function withdraw(uint256 amount) external nonReentrant {
    require(balances[msg.sender] >= amount, "insufficient");
    balances[msg.sender] -= amount;              // Effects 먼저
    (bool ok, ) = msg.sender.call{value: amount}(""); // Interaction 나중
    require(ok, "transfer failed");
}

② 접근 제어 누락
관리자 전용 함수에 onlyOwner를 빼먹는 실수.
믿기 어렵지만 실제 대형 사고의 상당수가 이 단순 실수에서 비롯됐다.
초기화 함수(initialize)가 누구나 호출 가능하게 열려 있는 프록시 사고도 반복적으로 발생했다.

③ 오라클 조작
가격 정보를 유동성이 얕은 DEX 풀에서 실시간으로 읽으면,
공격자가 플래시론으로 가격을 왜곡시켜 헐값에 자산을 인출할 수 있다.
→ TWAP(시간가중평균가) 또는 Chainlink 같은 분산 오라클 사용이 표준.

④ 무제한 approve
프론트엔드가 편의를 위해 type(uint256).max로 승인을 받아두는 관행.
해당 컨트랙트가 나중에 털리면 사용자 지갑도 함께 털린다.
→ Permit2나 EIP-2612 permit으로 기한·금액 제한 승인을 쓰는 것이 권장된다.

⑤ 프론트엔드 하이재킹
컨트랙트가 아무리 안전해도, 웹사이트 DNS나 npm 의존성이 탈취되면 끝이다.
실제로 여러 유명 프로젝트가 DNS 하이재킹과 공급망 공격으로 피해를 봤다.
웹 개발자의 책임 영역이 바로 여기다.

프론트엔드 보안 실무 체크리스트

· CSP 헤더와 SRI(Subresource Integrity) 적용
· 의존성 lockfile 고정 + 자동 취약점 스캔
· DNS 레지스트라 2FA·레지스트라 락 설정
· 서명 요청 시 사람이 읽을 수 있는 설명 제공 (EIP-712 구조화 서명 활용)
· 컨트랙트 주소를 하드코딩·검증하고 동적 주입 금지
· ENS/IPFS 기반 백업 배포 경로 준비

5-2. 개발 프로세스에 넣어야 할 것들

Web3 개발은 테스트 문화가 유난히 강하다. 이유는 단순하다. 롤백이 없기 때문이다.

도구용도
Foundry / Hardhat컴파일·테스트·배포 스크립트
Foundry Fuzz / Invariant무작위 입력·불변조건 검증
Slither, Mythril정적 분석으로 알려진 패턴 탐지
Tenderly트랜잭션 시뮬레이션·디버깅
OpenZeppelin Contracts검증된 표준 구현체 재사용
Immunefi 등 버그바운티배포 후 지속적 취약점 수집

"직접 짜지 말고 검증된 라이브러리를 써라"는 원칙이 Web3만큼 강력한 곳도 드물다.
ERC-20, ERC-721 같은 표준은 반드시 OpenZeppelin 구현을 상속하는 것이 업계 관행이다.

6. 실전 — 최소 기능 dApp 만들어보기

이론만으로는 감이 안 온다. 실제 흐름을 코드로 따라가 보자.
목표는 "지갑 연결 → 방명록 작성 → 목록 조회"다.

6-1. 스택 구성

npm create vite@latest my-dapp -- --template react-ts
cd my-dapp
npm i wagmi viem @tanstack/react-query
# 컨트랙트 개발
curl -L https://foundry.paradigm.xyz | bash && foundryup
forge init contracts

6-2. 지갑 연결 설정

import { createConfig, http } from 'wagmi';
import { base, baseSepolia } from 'wagmi/chains';
import { injected } from 'wagmi/connectors';

export const config = createConfig({
  chains: [base, baseSepolia],
  connectors: [injected()],
  transports: {
    [base.id]: http(import.meta.env.VITE_RPC_BASE),
    [baseSepolia.id]: http(import.meta.env.VITE_RPC_SEPOLIA),
  },
});

6-3. 읽기와 쓰기 훅

import { useAccount, useConnect, useReadContract,
         useWriteContract, useWaitForTransactionReceipt } from 'wagmi';

function Guestbook() {
  const { address, isConnected } = useAccount();
  const { connect, connectors } = useConnect();

  const { data: total } = useReadContract({
    address: CONTRACT, abi: ABI, functionName: 'total',
  });

  const { writeContract, data: hash, isPending } = useWriteContract();
  const { isLoading: mining, isSuccess } =
    useWaitForTransactionReceipt({ hash });

  if (!isConnected) {
    return <button onClick={() => connect({ connector: connectors[0] })}>
      지갑 연결
    </button>;
  }

  return (
    <div>
      <p>총 {String(total ?? 0n)}개</p>
      <button
        disabled={isPending || mining}
        onClick={() => writeContract({
          address: CONTRACT, abi: ABI,
          functionName: 'post', args: ['안녕 Web3!'],
        })}>
        {isPending ? '지갑에서 승인해주세요'
          : mining ? '블록에 기록 중...'
          : '방명록 남기기'}
      </button>
      {isSuccess && <p>완료되었습니다</p>}
    </div>
  );
}

여기서 배우는 UX 패턴

버튼 하나에 4가지 상태가 존재한다는 점을 주목하자.
idle → 서명 대기(isPending) → 채굴 대기(mining) → 성공/실패
Web2라면 'isLoading' 하나로 끝났을 것을, dApp에서는 반드시 분리해야 한다.
사용자가 "내 돈이 지금 어디쯤 있는지" 알 수 없으면 즉시 이탈한다.
여기에 블록 익스플로러 링크를 함께 제공하는 것이 사실상 표준 매너다.

6-4. 흔히 겪는 실전 이슈

· 네트워크 불일치
사용자가 메인넷에 연결된 상태에서 테스트넷 컨트랙트를 호출하면 그냥 실패한다.
useSwitchChain으로 체인 전환을 유도하는 UI를 반드시 넣어야 한다.

· BigInt 직렬화
viem은 숫자를 bigint로 반환한다. JSON.stringify가 바로 터진다.
포매팅에는 formatUnits, parseUnits를 쓰고, 소수점 연산에 절대 float를 쓰지 말 것.

· 서버 사이드 렌더링 충돌
Next.js에서 지갑 상태를 SSR로 렌더하면 하이드레이션 불일치가 난다.
지갑 관련 UI는 mounted 체크 후 클라이언트에서만 렌더링한다.

· RPC 요청 폭증
컴포넌트마다 useReadContract를 남발하면 무료 RPC 쿼터를 순식간에 태운다.
Multicall3로 배칭하고, React Query의 staleTime을 넉넉히 설정하자.

7. 어디에 쓰면 진짜 좋은가 — 유즈케이스 판별법

기술을 배웠다면 다음 질문은 "그래서 내 프로젝트에 필요한가?"다.
냉정하게 판별하는 기준을 제시한다.

블록체인이 필요한 조건 (3개 이상 해당해야 검토 가치 있음)

1. 서로 신뢰하지 않는 다수 당사자가 같은 데이터를 공유해야 한다.
2. 중립적인 제3자 중개인이 없거나 비용이 과도하다.
3. 기록의 변조 불가능성과 공개 검증이 서비스의 핵심 가치다.
4. 자산이나 권리의 소유권 이전이 일어난다.
5. 국경을 넘는 정산이 필요하다.

블록체인이 필요 없는 경우

· 우리 회사만 쓰는 내부 데이터 → 그냥 DB가 100배 낫다.
· 개인정보를 다뤄야 한다 → 온체인 기록은 삭제가 불가능해 GDPR·개인정보보호법과 정면 충돌한다.
· 초저지연·대용량 처리 → 전통 인프라가 압도적으로 우월하다.
· "투자 유치용 키워드가 필요해서" → 가장 나쁜 이유다.

7-1. 실제로 작동하는 영역

① 스테이블코인 결제·송금
Web3에서 가장 명확한 PMF(제품-시장 적합성)를 찾은 영역이다.
국경 간 송금이 수 초 내에, 수수료 몇십 원으로 끝난다.
결제 SDK와 지갑을 붙이는 웹 개발 수요가 꾸준히 발생한다.

② 증명서·자격 검증(SBT, Verifiable Credentials)
수료증·멤버십·출입 자격을 양도 불가 토큰으로 발급해 위조를 차단한다.
다만 개인정보는 오프체인에 두고 해시나 영지식 증명만 온체인에 올리는 설계가 필수다.

③ 온체인 거버넌스(DAO)
제안 → 투표 → 타임락 → 자동 실행까지 코드로 강제된다.
프론트엔드 개발자 입장에서는 제안 목록, 투표 UI, 정족수 시각화 같은 전형적인 웹 작업이 많다.

④ 크리에이터 로열티와 티켓팅
2차 유통 시 자동 분배, 암표 방지를 위한 이전 제한 로직 등이 컨트랙트로 구현된다.
실제로 대형 스포츠·공연 티켓 분야에서 NFT 기반 입장권 시범 사례가 축적되고 있다.

⑤ 실물 자산 토큰화(RWA)
국채·펀드 지분 등을 토큰화하는 흐름이 제도권에서 확대되고 있다.
이 영역은 KYC 화이트리스트, 전송 제한(ERC-3643 등) 같은 규제 대응 기능 구현이 핵심이다.

이처럼 Web3 관련 웹 개발 수요는 "코인"이 아니라 지갑 연동, 대시보드, 거버넌스 UI, 데이터 시각화 같은
지극히 평범하고 견고한 프론트엔드 작업에서 발생한다.
실제로 재능넷 같은 재능 공유 플랫폼에서도 "지갑 연동 웹 구축", "The Graph 서브그래프 작성",
"NFT 민팅 페이지 개발" 같은 의뢰가 개별 프로젝트 단위로 활발히 오간다.
즉 Web3는 웹 개발자에게 새 직업이 아니라 새 도구 세트에 가깝다.

트랜잭션 생애주기와 UI 상태 매핑 1 의도 생성 버튼 클릭 idle 2 서명 요청 지갑 팝업 isPending 3 멤풀 전파 해시 발급 pending 4 블록 포함 영수증 수신 mining→done 5 확정 인덱서 반영 finalized 주의 : 3단계에서 사용자가 창을 닫아도 트랜잭션은 계속 진행된다 해시를 로컬에 저장하고 재방문 시 상태를 복원하는 로직이 필요하다

8. 한계와 리스크 — 낭만 없이 보기

전문가라면 장점만 말하지 않는다. 명백한 한계를 정리한다.

① 성능은 여전히 전통 DB에 비할 바가 아니다.
L2로 개선됐다지만, 글로벌 합의를 거치는 구조상 중앙 서버의 처리량·지연을 이길 수 없다.
"블록체인이 더 빠르다"는 주장은 대체로 틀렸다.

② 키 분실은 곧 자산 소멸이다.
비밀번호 재설정 메일이 없다.
이 문제를 완화하려고 소셜 복구, MPC 지갑, 패스키 기반 지갑이 등장했지만,
편의성을 높일수록 중앙화 요소가 다시 들어온다는 트레이드오프를 피할 수 없다.

③ 프라이버시 역설
퍼블릭 체인의 모든 거래는 공개된다.
지갑 주소 하나가 실명과 연결되는 순간 전 생애 거래내역이 노출된다.
이 때문에 영지식 증명, 스텔스 주소 같은 기술 연구가 활발하다.

④ 규제 불확실성
국가별로 가상자산·증권성 판단 기준이 다르고 변화 속도도 빠르다.
토큰을 발행하는 순간 기술 문제가 아니라 법률 문제가 된다.
개발 착수 전 법률 검토는 선택이 아니라 필수다.

⑤ MEV(최대 추출 가능 가치)
멤풀에 노출된 트랜잭션을 보고 앞질러 거래하는 샌드위치 공격 등이 존재한다.
DEX 거래 UI를 만든다면 슬리피지 설정, 프라이빗 멤풀 라우팅을 반드시 고려해야 한다.

9. 웹 개발자를 위한 학습 로드맵

단계목표핵심 활동
1주차감각 익히기테스트넷 지갑 생성, 포셋에서 테스트 토큰 수령, 익스플로러에서 트랜잭션 구조 관찰
2~3주차읽기 구현viem으로 잔액·토큰 정보 조회 페이지 제작, ABI 이해
4~5주차쓰기 구현wagmi로 트랜잭션 전송, 4단계 상태 UI 완성
6~8주차컨트랙트 작성Solidity 기초 + Foundry 테스트, OpenZeppelin 상속 실습
9~10주차데이터 계층IPFS 업로드, The Graph 서브그래프 배포
11~12주차보안·배포Slither 정적 분석, 테스트넷 배포 후 소스 검증(Verify)

학습 팁

· 반드시 테스트넷부터. 실수로 메인넷에 배포해 가스비를 날리는 사고는 흔하다.
· 기존 프로젝트의 Verified Contract 소스를 읽는 것이 최고의 교재다. 익스플로러에서 무료로 볼 수 있다.
· Solidity는 문법보다 가스 비용 감각과 보안 패턴이 훨씬 중요하다.
· CTF 형식의 학습 게임(Ethernaut 등)으로 취약점을 직접 공격해보면 이해가 빠르다.

10. 마무리 — 도구로서의 Web3

Web3의 가치를 한 문장으로 다시 정리하면 이렇다.

"운영자를 신뢰하지 않아도 되는 대신, 비싸고 느리고 되돌릴 수 없다."

이 트레이드오프가 말이 되는 문제 영역에서만 블록체인을 쓰면 된다.
그리고 그 판단을 정확히 내릴 수 있는 사람이 진짜 실력 있는 개발자다.

흥미로운 사실은, dApp 개발의 대부분이 결국 평범한 웹 개발 실력에 좌우된다는 점이다.
상태 관리, 에러 핸들링, 반응형 레이아웃, 접근성, 로딩 UX.
컨트랙트가 아무리 정교해도 사용자는 프론트엔드만 본다.

그래서 Web3 시대에도 홈페이지·웹개발 역량은 낡지 않는다.
오히려 지갑·서명·트랜잭션이라는 새로운 인터랙션 패턴을 다룰 줄 아는 개발자가 희소해졌다.

기술 트렌드는 계속 바뀐다. 롤업이 앱체인으로, 계정 추상화가 기본 사양으로,
영지식 증명이 일상 도구로 옮겨가는 중이다.
하지만 변하지 않는 원칙은 하나다.

사용자는 "탈중앙화"를 원하지 않는다. 그 결과로 얻는 안전함·투명함·소유권을 원한다.

기술을 앞세우지 말고 경험을 앞세워라.
지갑 연결 버튼 하나가 "복잡한 절차"가 아니라 "간편한 시작"으로 느껴질 때,
비로소 dApp은 특별한 앱이 아니라 그냥 좋은 웹 서비스가 된다.

오늘 배운 구조를 토대로 작은 방명록 하나를 테스트넷에 올려보길 권한다.
첫 트랜잭션이 블록에 기록되고, 그 기록이 지구 반대편 노드에도 똑같이 존재한다는 사실을 확인하는 순간,
이 기술이 왜 사람들을 매료시켰는지 몸으로 이해하게 될 것이다. 🚀

댓글 작성

이 글에 대한 여러분의 생각을 들려주세요

댓글 0