@samcoding

Wagmi vs Codama — EVM과 Solana 타입 안전성 무엇이 다를까
웹쓰리 프론트엔드 개발에서 온체인 프로그램이나 스마트 계약과 상호작용하는 과정은 오류가 가장 빈번하게 발생하는 구간입니다. EVM 생태계가 별도의 컴파일 단계 없이 ABI 타입 추론을 활용해 직관적인 개발 흐름을 완성했다면, 솔라나는 최근 Web3.js v2와 코다마를 도입하며 초경량 함수형 파이프라인으로의 패러다임 전환을 이뤄내고 있습니다. 두 생태계가 컴파일 타임의 타입 안전성을 확보하기 위해 선택한 서로 다른 아키텍처적 접근법과 개발자 경험의 차이를 살펴봅니다.
EVM의 컴파일 프리 타입 안전성: Viem과 as const의 마법
과거 EVM 개발자들은 스마트 계약과 상호작용하기 위해 Solidity 코드를 빌드하고 TypeChain 같은 별도 도구로 무거운 타입 정의 파일을 매번 생성해야 했습니다. 하지만 Viem과 Wagmi는 이러한 중간 생성 단계를 완전히 제거했습니다. 이들은 내부적으로 ABIType 라이브러리를 활용하여, 추가적인 컴파일 과정 없이 오직 TypeScript 자체의 타입 시스템만으로 강력한 정적 타입 안전성을 구현합니다.
이 혁신의 메커니즘은 매우 단순합니다. ABI JSON 배열 끝에 as const 단언을 추가하는 것입니다. TypeScript 컴파일러는 이 구문을 바탕으로 스마트 계약 내부의 함수 명세, 매개변수 개수, 데이터 타입을 온더플라이로 정밀하게 파악합니다. 개발자가 함수명을 입력할 때 정확한 자동 완성이 제공되는 것은 물론, 매개변수 타입을 잘못 기입하면 컴파일 단계에서 즉시 빌드 에러를 유도합니다.
Viem은 이러한 타입 추론 능력을 바탕으로, 조회용 무상태 액션인 readContract와 상태 변경을 위한 writeContract를 완전히 독립적인 클라이언트 구조로 격리합니다. 특히 가스비 낭비와 불필요한 지갑 서명 요청 실패를 방지하기 위해, 실제 온체인 전송 전 simulateContract를 호출하는 시뮬레이션 설계를 적극 권장합니다.
const abi = [...] as const; // ABI를 정적 리터럴 타입으로 단언합니다.
// 1. 가상 노드 상에서 트랜잭션을 사전 실행하여 결과와 가스 상태를 검증합니다.
const { request } = await publicClient.simulateContract({
account,
address: '0x...',
abi,
functionName: 'transfer',
args: ['0x...', 100n], // 매개변수 타입 오류가 있다면 이 빌드 시점에서 감지됩니다.
});
// 2. 사전에 검증을 마친 안전한 요청 객체를 전달해 사용자 서명을 안전하게 받아냅니다.
await walletClient.writeContract(request);이 파이프라인을 사용하면 스마트 계약 호출 과정에서 트랜잭션이 중간에 되돌아가는 실패 상황을 서명 팝업을 띄우기 전에 예측하여 잡을 수 있습니다. 결과적으로 사용자가 무의미한 가스를 낭비하지 않도록 보호하며, 한 차원 높은 신뢰를 보장하는 프론트엔드 환경을 제공합니다.
Solana의 패러다임 전환: 무거운 Anchor TS에서 가벼운 Codama로
솔라나 개발 환경이 기존의 무거운 클래스 기반 앵커 TS 클라이언트에서 코다마(Codama, 구 Kinobi)를 활용한 초경량 함수형 클라이언트로 빠르게 전환되고 있습니다. 기존 앵커 클라이언트는 온체인 프로그램의 IDL을 해석하고 통신하기 위해 거대한 클래스 인스턴스를 통째로 로드해야 했기 때문에 프론트엔드 번들 크기가 비대해지는 원인이 되었습니다.
반면 코다마는 IDL 파일을 분석하여 트리 쉐이킹이 가능한 독립적인 타입과 함수들을 개별적으로 생성합니다 [1]. 개발자는 거대한 런타임 객체를 생성할 필요 없이, 필요한 계정 디코더나 인스트럭션 빌더만 파일 단위로 임포트하여 독립적으로 호출할 수 있습니다.
// 코다마가 생성한 초경량 함수형 클라이언트 활용 예시
import { fetchCounter, getMakeOfferInstructionAsync } from '@solana/clients';
// 필요한 함수만 단독으로 호출하여 계정 데이터를 디코딩
const counterAccount = await fetchCounter(rpc, counterAddress);
// 빌드 단계에서 트리 쉐이킹이 가능한 개별 인스트럭션 빌더 활용
const makeOfferInstruction = await getMakeOfferInstructionAsync({
maker,
mint,
offerAddress,
});이 아키텍처는 프론트엔드 성능에 결정적인 영향을 미칩니다. dApp 화면에서 사용하지 않는 스마트 계약 기능이나 보조 함수들은 빌드 단계에서 컴파일러에 의해 완전히 제거됩니다. 결과적으로 자바스크립트 실행 파일의 물리적 크기가 크게 줄어들어 모바일 환경이나 네트워크 속도가 느린 곳에서도 뛰어난 사용자 경험을 제공합니다.
트랜잭션 빌딩 비교: 단순 메소드 호출 vs pipe 기반 함수형 파이프라인
EVM과 솔라나는 온체인 실행 환경이 다른 만큼 트랜잭션을 빌드하는 프론트엔드 아키텍처도 전혀 다릅니다. Viem과 Wagmi를 사용하는 EVM 개발 환경에서는 ABI를 기반으로 단일 스마트 계약 메소드를 직접 호출하면 프레임워크가 백그라운드에서 트랜잭션을 완성하므로 매우 직관적입니다. 반면 솔라나 키트에서는 하나의 트랜잭션에 다수의 독립적인 인스트럭션을 담고 수수료 지불자와 블록해시 유효 기간을 개별적으로 관리해야 하므로 무상태 함수형 파이프라인 방식을 사용합니다.
솔라나 키트가 제공하는 pipe 기반 트랜잭션 빌딩 아키텍처는 함수형 프로그래밍 방식을 사용하여 트랜잭션 메시지를 순차적으로 변화시킵니다. 다음과 같이 매개변수를 주입받아 무상태로 트랜잭션을 가공하는 흐름을 가집니다.
import {
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
pipe
} from '@solana/kit';
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayer(feePayerAddress, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
(tx) => appendTransactionMessageInstruction(transferInstruction, tx)
);이 아키텍처의 핵심 강점은 TypeScript의 강력한 타입 좁히기 설계에 있습니다. 처음 생성된 기본 트랜잭션 메시지는 서명이나 전송이 불가능한 초기 타입 상태를 유지합니다. 파이프라인을 지나면서 수수료 지불자와 블록해시 수명 정보가 명확히 명시될 때마다 TypeScript 컴파일러가 인식하는 메시지 타입의 정적 속성이 점진적으로 추가됩니다.
만약 블록해시 할당이나 수수료 지불자 지정 같은 필수 단계를 누락하면, 해당 트랜잭션 메시지는 최종 서명 함수가 요구하는 정적 타입을 충족하지 못하게 됩니다. 즉, 컴파일러 수준에서 서명 불가 타입으로 간주되어 빌드 에러를 발생시킵니다. 런타임에 발생할 수 있는 주요 전송 오류나 실수들을 코드를 실행하기 전 컴파일 단계에서 원천 차단하는 정교한 안전 장치입니다.
모듈화와 최적화: Wagmi v3와 Solana Kit의 공통분모
최신 Web3 프론트엔드 도구들은 번들 최적화와 의존성 관리를 위해 극단적인 모듈화의 길을 걷고 있습니다. 프레임워크가 모든 기능을 통째로 제공하는 기존 방식에서 벗어나, 필요한 기능만 선택해서 조립하는 방식으로 아키텍처가 변화하고 있습니다.
Wagmi v3는 메타마스크나 코인베이스 월렛처럼 번들 크기를 키우던 기존 커넥터들을 선택적 피어 의존성으로 완전히 분리했습니다. 개발자는 실제 서비스에 필요한 지갑 커넥터만 프로젝트 의존성에 직접 추가하여 로드하므로 번들 크기를 획기적으로 줄일 수 있습니다. 또한 dApp의 소프트웨어 공급망 보안과 의존성 라이선스를 더욱 투명하게 관리하는 데 도움이 됩니다.
이러한 흐름은 솔라나 키트가 보여주는 마이크로 패키지 설계와 정확히 일치합니다. 솔라나 키트 역시 시스템 프로그램, 토큰 프로그램, 컴퓨트 버짓 관리 등을 단일 코어 라이브러리에 묶지 않고 각각 독립적인 마이크로 패키지로 분리하여 배포합니다. 개발자는 필요한 기능만 선택적으로 가져와 트랜잭션을 빌드할 수 있으며, 빌드 타임에 사용하지 않는 코드는 완벽하게 트리 쉐이킹되어 극도로 최적화된 프론트엔드 환경을 구축할 수 있습니다.
멀티체인 빌더가 나아갈 방향
EVM의 컴파일 단계 없는 타입 추론과 솔라나의 코드 생성 기반 함수형 파이프라인은 각 체인의 고유한 런타임 특성을 반영하여 개발자 경험을 개선한 결과물입니다. 멀티체인 dApp을 구축하는 개발자라면 Wagmi v3의 경량화된 커넥터 구조와 솔라나 웹쓰리 v2의 파이프 기반 함수형 패턴을 모두 활용할 줄 아는 것이 유리합니다. 두 생태계의 최신 도구를 직접 통합해 보며 번들 크기 최적화와 컴파일 타임 안전성을 동시에 달성하는 최적의 프론트엔드 아키텍처를 설계해 보시기 바랍니다.
참고 링크