본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 2. · 20 Views
Block Explorer 설정 Blockscout 완벽 가이드
이더리움 프라이빗 네트워크에서 Blockscout을 활용해 트랜잭션을 조회하고 스마트 컨트랙트를 검증하는 방법을 단계별로 설명합니다. DevOps 환경에서 블록 익스플로러를 구축하고 운영하는 실무 노하우를 담았습니다.
목차
1. Blockscout 소개
김개발 씨는 회사에서 프라이빗 이더리움 네트워크를 운영하게 되었습니다. 테스트넷에서 트랜잭션을 보내고 받는 것까지는 성공했는데, 문제가 생겼습니다.
"이 트랜잭션이 정말 성공한 건지 어떻게 확인하죠?" 메인넷에서는 Etherscan을 사용했는데, 프라이빗 네트워크에서는 그게 불가능했습니다.
Blockscout은 오픈소스 블록 익스플로러입니다. 마치 은행 거래 내역 조회 시스템처럼, 블록체인에서 일어난 모든 거래를 웹 브라우저에서 쉽게 확인할 수 있게 해줍니다.
Etherscan의 프라이빗 버전이라고 생각하면 이해하기 쉽습니다.
다음 코드를 살펴봅시다.
# Blockscout 기본 구조 확인
# docker-compose.yml에서 필요한 서비스들
services:
blockscout:
image: blockscout/blockscout:latest
# 웹 UI를 제공하는 메인 서비스
ports:
- "4000:4000"
postgres:
image: postgres:14
# 블록체인 데이터를 저장하는 데이터베이스
redis:
image: redis:alpine
# 캐싱을 위한 인메모리 저장소
김개발 씨는 입사 6개월 차 블록체인 개발자입니다. 회사에서 새로운 프로젝트를 맡게 되었는데, 바로 프라이빗 이더리움 네트워크 구축이었습니다.
Geth 노드도 띄우고, 스마트 컨트랙트도 배포했습니다. 그런데 한 가지 큰 불편함이 있었습니다.
"트랜잭션 해시를 복사해서 터미널에서 일일이 조회해야 하다니..." 김개발 씨는 한숨을 쉬었습니다. 메인넷에서 개발할 때는 Etherscan에 접속해서 클릭 몇 번이면 모든 정보를 볼 수 있었는데, 프라이빗 네트워크는 그렇지 않았습니다.
선배 개발자 박시니어 씨가 다가와 말했습니다. "Blockscout 써보셨어요?
우리 네트워크 전용 Etherscan을 만들 수 있어요." 그렇다면 Blockscout이란 정확히 무엇일까요? 쉽게 비유하자면, Blockscout은 마치 도서관의 도서 검색 시스템과 같습니다.
도서관에 있는 수많은 책들을 일일이 서가를 돌아다니며 찾을 필요 없이, 컴퓨터에서 제목이나 저자를 검색하면 바로 위치를 알려주죠. Blockscout도 마찬가지입니다.
블록체인에 기록된 수많은 트랜잭션과 컨트랙트를 웹 브라우저에서 쉽게 검색하고 조회할 수 있게 해줍니다. Blockscout이 없던 시절에는 어땠을까요?
개발자들은 eth_getTransactionReceipt 같은 RPC 명령어를 터미널에서 직접 실행해야 했습니다. JSON 형태로 출력되는 결과물을 눈으로 해석해야 했고, 여러 트랜잭션을 비교하려면 엄청난 노가다가 필요했습니다.
더 큰 문제는 QA 팀이나 기획자 같은 비개발자들은 이런 작업을 할 수 없었다는 것입니다. 바로 이런 문제를 해결하기 위해 Blockscout이 등장했습니다.
POA Network에서 처음 개발했고, 지금은 수많은 블록체인 프로젝트에서 사용하고 있습니다. Blockscout을 사용하면 웹 브라우저만으로 모든 블록체인 데이터를 조회할 수 있습니다.
또한 스마트 컨트랙트의 소스코드를 검증하고 공개할 수도 있습니다. 무엇보다 팀 전체가 같은 도구로 블록체인 상태를 확인할 수 있다는 큰 장점이 있습니다.
Blockscout의 핵심 구성 요소를 살펴보겠습니다. 메인 서비스인 blockscout은 Elixir로 작성된 웹 애플리케이션입니다.
PostgreSQL 데이터베이스는 블록체인에서 읽어온 데이터를 저장합니다. Redis는 자주 조회되는 데이터를 캐싱하여 성능을 높입니다.
실제 현업에서는 어떻게 활용할까요? DeFi 프로젝트를 개발한다고 가정해봅시다.
테스트넷에서 스왑 기능을 테스트할 때, Blockscout을 통해 트랜잭션의 내부 호출 구조를 확인할 수 있습니다. 어떤 컨트랙트가 어떤 순서로 호출되었는지 한눈에 파악할 수 있죠.
하지만 주의할 점도 있습니다. Blockscout은 자원을 많이 사용하는 애플리케이션입니다.
프로덕션 환경에서는 충분한 서버 사양을 확보해야 합니다. 최소 4GB RAM, 가능하면 8GB 이상을 권장합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 조언을 들은 김개발 씨는 Blockscout을 도입하기로 결정했습니다.
"이제 터미널에서 JSON 해석하는 건 안녕이네요!" Blockscout을 제대로 설정하면 프라이빗 네트워크도 메인넷 못지않은 개발 경험을 제공할 수 있습니다. 다음 장에서는 실제 설정 방법을 알아보겠습니다.
실전 팁
💡 - Blockscout은 Elixir 기반이므로 Erlang VM 관련 설정도 튜닝이 필요합니다
- 첫 동기화 시 많은 시간이 소요될 수 있으니 인덱싱 상태를 모니터링하세요
2. additional services 설정
김개발 씨는 Blockscout을 설치하려고 공식 문서를 열었습니다. 그런데 Docker Compose 파일이 예상보다 복잡했습니다.
"이 additional_services는 뭐고, 환경 변수는 왜 이렇게 많은 거죠?" 설정 하나를 잘못 건드리면 전체가 동작하지 않을 것 같은 불안감이 엄습했습니다.
additional_services는 Blockscout의 핵심 기능을 확장하는 부가 서비스들을 정의하는 설정입니다. 마치 스마트폰에 기본 앱 외에 추가 앱을 설치하는 것처럼, 필요한 기능에 따라 서비스를 추가하거나 제외할 수 있습니다.
스마트 컨트랙트 검증, 통계 수집, 시각화 등의 기능이 여기에 포함됩니다.
다음 코드를 살펴봅시다.
# additional_services.yml 설정 예시
services:
# 스마트 컨트랙트 검증 서비스
smart-contract-verifier:
image: ghcr.io/blockscout/smart-contract-verifier:latest
environment:
- SMART_CONTRACT_VERIFIER__SERVER__HTTP__ADDR=0.0.0.0:8050
ports:
- "8050:8050"
# 시각화 서비스 (트랜잭션 흐름 그래프)
visualizer:
image: ghcr.io/blockscout/visualizer:latest
environment:
- VISUALIZER__SERVER__HTTP__ADDR=0.0.0.0:8151
ports:
- "8151:8151"
# 통계 서비스
stats:
image: ghcr.io/blockscout/stats:latest
김개발 씨는 Blockscout 공식 저장소를 클론했습니다. docker-compose 디렉토리 안에 여러 개의 YAML 파일이 있었습니다.
그중 additional_services라는 이름이 눈에 띄었습니다. "이건 뭐하는 파일이지?" 김개발 씨가 파일을 열어보니, 여러 개의 서비스가 정의되어 있었습니다.
smart-contract-verifier, visualizer, stats... 이름만 봐서는 역할을 짐작할 수 있었지만, 어떤 것이 필수이고 어떤 것이 선택인지 알 수 없었습니다.
박시니어 씨가 설명해주었습니다. "Blockscout은 모듈형 아키텍처를 채택하고 있어요.
핵심 기능은 메인 서비스에 있고, 부가 기능은 별도 컨테이너로 분리했죠." additional_services를 레스토랑에 비유해보겠습니다. 메인 서비스인 Blockscout은 셰프가 요리를 만드는 주방입니다.
하지만 레스토랑에는 주방만 있는 게 아니죠. 와인 소믈리에, 디저트 전문 파티시에, 바리스타 등 전문 인력이 더 있습니다.
additional_services가 바로 이런 전문 인력들입니다. smart-contract-verifier는 가장 중요한 부가 서비스입니다.
사용자가 업로드한 Solidity 소스코드와 블록체인에 배포된 바이트코드가 일치하는지 검증합니다. 이 서비스가 없으면 컨트랙트 소스코드 검증 기능을 사용할 수 없습니다.
visualizer 서비스는 트랜잭션의 내부 호출 구조를 그래프로 시각화해줍니다. 복잡한 DeFi 트랜잭션에서 어떤 컨트랙트가 어떤 순서로 호출되었는지 한눈에 파악할 수 있습니다.
디버깅할 때 정말 유용한 기능입니다. stats 서비스는 네트워크 통계를 수집합니다.
일일 트랜잭션 수, 활성 주소 수, 가스 사용량 추이 등을 차트로 보여줍니다. 프로덕션 환경에서 네트워크 상태를 모니터링할 때 필수입니다.
환경 변수 설정도 중요합니다. 각 서비스는 자체적인 환경 변수를 가지고 있습니다.
특히 ADDR 설정은 서비스가 어떤 주소와 포트에서 요청을 받을지 정의합니다. 0.0.0.0으로 설정하면 모든 네트워크 인터페이스에서 접근을 허용합니다.
서비스 간 통신도 이해해야 합니다. 메인 Blockscout 서비스는 이 부가 서비스들과 HTTP로 통신합니다.
따라서 메인 서비스의 환경 변수에서 각 부가 서비스의 URL을 정확히 설정해야 합니다. 하나라도 잘못되면 해당 기능이 동작하지 않습니다.
실무에서 자주 하는 실수 중 하나는 모든 서비스를 한꺼번에 활성화하는 것입니다. 서버 자원이 충분하지 않으면 전체 시스템이 느려지거나 다운될 수 있습니다.
처음에는 필수 서비스만 활성화하고, 필요에 따라 하나씩 추가하는 것이 좋습니다. 김개발 씨는 고개를 끄덕였습니다.
"그러니까 처음에는 메인 서비스와 smart-contract-verifier만 띄우고, 나중에 필요하면 다른 것도 추가하면 되겠네요!" 정확합니다. additional_services를 이해하면 Blockscout을 자신의 환경에 맞게 커스터마이징할 수 있습니다.
다음 장에서는 실제로 이 서비스들을 배포하는 방법을 알아보겠습니다.
실전 팁
💡 - 개발 환경에서는 smart-contract-verifier만으로도 충분합니다
- 각 서비스의 포트가 충돌하지 않도록 주의하세요
3. Blockscout 서비스 추가 배포
설정 파일을 모두 작성한 김개발 씨는 드디어 배포를 시도했습니다. docker compose up 명령어를 입력하는 순간, 터미널에 로그가 쏟아지기 시작했습니다.
"이게 성공한 건가요, 실패한 건가요?" 로그 메시지를 해석하는 것도 쉽지 않았습니다.
Blockscout 배포는 Docker Compose를 사용하여 여러 서비스를 한 번에 실행하는 과정입니다. 마치 오케스트라 지휘자가 여러 악기를 동시에 연주하게 하는 것처럼, 하나의 명령어로 데이터베이스, 캐시, 웹 서버 등 모든 구성 요소를 조율합니다.
순서와 의존성을 이해하는 것이 성공적인 배포의 핵심입니다.
다음 코드를 살펴봅시다.
# 1. 환경 변수 파일 생성
cat > .env << 'EOF'
ETHEREUM_JSONRPC_HTTP_URL=http://host.docker.internal:8545
ETHEREUM_JSONRPC_TRACE_URL=http://host.docker.internal:8545
DATABASE_URL=postgresql://blockscout:password@postgres:5432/blockscout
SECRET_KEY_BASE=your_secret_key_minimum_64_characters_long_here
CHAIN_ID=1337
NETWORK=Private Network
SUBNETWORK=Development
EOF
# 2. 서비스 배포 실행
docker compose -f docker-compose.yml \
-f docker-compose.additional.yml \
up -d
# 3. 로그 확인으로 상태 모니터링
docker compose logs -f blockscout
김개발 씨는 드디어 배포 단계에 도달했습니다. 설정 파일도 작성했고, 환경 변수도 준비했습니다.
이제 실제로 Blockscout을 띄울 차례입니다. 하지만 첫 번째 시도는 실패했습니다.
"Database connection refused"라는 에러가 발생했습니다. 김개발 씨는 당황했지만, 박시니어 씨는 침착하게 말했습니다.
"서비스 시작 순서 문제예요. PostgreSQL이 완전히 준비되기 전에 Blockscout이 연결을 시도한 거죠." Docker Compose의 depends_on 옵션은 컨테이너 시작 순서만 보장합니다.
내부 서비스가 완전히 준비되었는지는 확인하지 않습니다. 이 미묘한 차이가 배포 실패의 원인이 되는 경우가 많습니다.
해결책은 healthcheck를 활용하는 것입니다. PostgreSQL 컨테이너에 헬스체크를 설정하고, Blockscout이 이 헬스체크가 통과한 후에 시작하도록 설정합니다.
최신 버전의 docker-compose 파일에는 이미 이런 설정이 포함되어 있습니다. 환경 변수 설정을 자세히 살펴보겠습니다.
ETHEREUM_JSONRPC_HTTP_URL은 가장 중요한 설정입니다. Blockscout이 데이터를 가져올 이더리움 노드의 주소를 지정합니다.
로컬에서 Geth를 실행 중이라면 host.docker.internal을 사용하여 호스트 머신에 접근할 수 있습니다. DATABASE_URL은 PostgreSQL 연결 문자열입니다.
형식은 postgresql://사용자:비밀번호@호스트:포트/데이터베이스 입니다. Docker 네트워크 내에서는 컨테이너 이름을 호스트로 사용할 수 있습니다.
SECRET_KEY_BASE는 세션 암호화에 사용됩니다. 최소 64자 이상의 랜덤 문자열을 사용해야 합니다.
openssl rand -hex 32 명령어로 생성할 수 있습니다. 배포 명령어에서 -f 플래그는 여러 compose 파일을 합쳐서 사용하겠다는 의미입니다.
기본 설정은 docker-compose.yml에, 부가 서비스는 docker-compose.additional.yml에 분리해두면 관리가 편합니다. -d 플래그는 백그라운드 실행을 의미합니다.
이 플래그 없이 실행하면 터미널이 로그 출력에 점유되어 다른 작업을 할 수 없습니다. 하지만 처음 배포할 때는 -d 없이 실행하여 로그를 실시간으로 확인하는 것도 좋은 방법입니다.
배포 후 가장 중요한 것은 인덱싱 상태 확인입니다. Blockscout은 시작 후 블록체인의 모든 데이터를 읽어와서 데이터베이스에 저장합니다.
블록 수가 많으면 이 과정에 상당한 시간이 걸립니다. 로그에서 "Indexed block" 메시지가 계속 출력되면 정상 동작 중입니다.
김개발 씨는 두 번째 시도에서 성공했습니다. 로그에 "Blockscout started" 메시지가 나타났고, 인덱싱이 진행되는 것을 확인할 수 있었습니다.
"드디어 됐다!" 성공적인 배포 후에도 모니터링은 계속해야 합니다. docker compose logs -f 명령어로 실시간 로그를 확인하고, 에러가 발생하면 즉시 대응할 수 있어야 합니다.
실전 팁
💡 - 첫 배포 시에는 백그라운드 실행 없이 로그를 실시간으로 확인하세요
- 인덱싱이 완료되기 전에도 웹 UI에 접근할 수 있지만, 데이터가 불완전할 수 있습니다
4. 웹 UI 접근하기
배포에 성공한 김개발 씨는 브라우저를 열고 localhost:4000을 입력했습니다. 잠시 로딩 후, 드디어 Blockscout 대시보드가 화면에 나타났습니다.
"오, 진짜 Etherscan이랑 비슷하게 생겼네요!" 하지만 화면에 표시된 숫자들이 무엇을 의미하는지는 아직 모호했습니다.
Blockscout 웹 UI는 블록체인 데이터를 시각적으로 탐색할 수 있는 대시보드 인터페이스입니다. 마치 자동차 계기판처럼 네트워크의 현재 상태를 한눈에 보여줍니다.
블록 높이, 트랜잭션 수, 평균 블록 시간 등 핵심 지표를 실시간으로 확인할 수 있습니다.
다음 코드를 살펴봅시다.
# Nginx 리버스 프록시 설정 (선택사항)
# 도메인으로 접근하고 싶을 때 사용
server {
listen 80;
server_name blockscout.example.com;
location / {
proxy_pass http://localhost:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
# WebSocket 지원 (실시간 업데이트용)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
김개발 씨는 브라우저에서 http://localhost:4000을 입력했습니다. 몇 초간 로딩 스피너가 돌더니, 익숙한 듯 낯선 화면이 나타났습니다.
Etherscan을 많이 사용해본 덕분에 대략적인 구조는 이해할 수 있었습니다. 화면 상단에는 네트워크 정보가 표시됩니다.
Network Name은 환경 변수에서 설정한 값이 나타납니다. 그 아래에는 실시간 블록 높이, 평균 블록 시간, 총 트랜잭션 수 등 핵심 지표가 표시됩니다.
메인 대시보드에서 가장 눈에 띄는 것은 최근 블록 목록과 최근 트랜잭션 목록입니다. 두 개의 열로 나뉘어 실시간으로 업데이트됩니다.
새로운 블록이 생성되면 목록 맨 위에 자동으로 추가되는 것을 볼 수 있습니다. 박시니어 씨가 설명했습니다.
"이 실시간 업데이트는 WebSocket으로 구현되어 있어요. 그래서 Nginx로 프록시할 때 WebSocket 설정을 꼭 해줘야 합니다." 상단 검색창은 Blockscout의 핵심 기능 중 하나입니다.
여기에 트랜잭션 해시, 블록 번호, 주소, 또는 컨트랙트 이름을 입력하면 해당 정보 페이지로 바로 이동합니다. Etherscan과 동일한 사용 경험을 제공합니다.
네비게이션 메뉴를 살펴보겠습니다. Blocks 메뉴에서는 모든 블록 목록을 볼 수 있습니다.
각 블록을 클릭하면 해당 블록에 포함된 트랜잭션, 마이너 정보, 가스 사용량 등 상세 정보가 나타납니다. Transactions 메뉴는 전체 트랜잭션 목록을 보여줍니다.
필터 기능을 사용하면 특정 유형의 트랜잭션만 볼 수도 있습니다. 예를 들어 컨트랙트 생성 트랜잭션만 필터링할 수 있습니다.
Tokens 메뉴에서는 네트워크에 배포된 ERC-20, ERC-721 토큰 목록을 확인할 수 있습니다. 각 토큰의 총 공급량, 홀더 수, 전송 내역 등을 추적할 수 있습니다.
APIs 메뉴도 중요합니다. Blockscout은 Etherscan과 호환되는 REST API를 제공합니다.
기존에 Etherscan API를 사용하던 도구나 스크립트를 그대로 사용할 수 있다는 의미입니다. 프로덕션 환경에서는 localhost 대신 도메인으로 접근하도록 설정하는 것이 좋습니다.
위의 Nginx 설정 예시처럼 리버스 프록시를 구성하면 됩니다. HTTPS 적용도 Let's Encrypt로 쉽게 할 수 있습니다.
김개발 씨는 여러 메뉴를 클릭하며 탐색했습니다. "Etherscan이랑 거의 똑같네요.
팀원들도 별도 교육 없이 바로 사용할 수 있겠어요." 웹 UI를 제대로 활용하면 커맨드라인에서 하던 모든 조회 작업을 마우스 클릭만으로 할 수 있습니다. 다음 장에서는 트랜잭션을 조회하고 검색하는 구체적인 방법을 알아보겠습니다.
실전 팁
💡 - 북마크에 자주 사용하는 주소 페이지를 저장해두면 편리합니다
- API 키 없이도 기본 API를 사용할 수 있지만, 속도 제한이 있습니다
5. 트랜잭션 조회 및 검색
QA 팀에서 버그 리포트가 왔습니다. "이 트랜잭션이 실패했는데, 원인을 모르겠어요." 김개발 씨는 트랜잭션 해시를 받아서 Blockscout 검색창에 붙여넣었습니다.
클릭 몇 번으로 문제의 원인을 찾을 수 있을까요?
트랜잭션 조회는 Blockscout의 가장 기본적이면서도 강력한 기능입니다. 트랜잭션 상세 페이지에서는 발신자, 수신자, 가스 사용량뿐 아니라 실패 원인, 내부 트랜잭션, 이벤트 로그까지 확인할 수 있습니다.
디버깅의 첫 단추는 항상 트랜잭션 조회에서 시작됩니다.
다음 코드를 살펴봅시다.
// 트랜잭션 정보 조회를 위한 Ethers.js 코드
// Blockscout API는 Etherscan API와 호환됩니다
import { ethers } from 'ethers';
// Blockscout API 엔드포인트 설정
const BLOCKSCOUT_API = 'http://localhost:4000/api';
// 트랜잭션 정보 조회
async function getTransactionInfo(txHash: string) {
const response = await fetch(
`${BLOCKSCOUT_API}?module=transaction&action=gettxinfo&txhash=${txHash}`
);
const data = await response.json();
// 트랜잭션 상태 확인
if (data.result.isError === '1') {
console.log('실패 원인:', data.result.errDescription);
}
return data.result;
}
김개발 씨는 QA 팀에서 받은 트랜잭션 해시를 복사했습니다. Blockscout 상단 검색창에 붙여넣고 엔터를 눌렀습니다.
잠시 후 트랜잭션 상세 페이지가 나타났습니다. 페이지 최상단에는 트랜잭션 상태가 크게 표시됩니다.
녹색 "Success"면 성공, 빨간색 "Failed"면 실패입니다. QA 팀이 보고한 트랜잭션은 예상대로 "Failed" 상태였습니다.
Transaction Details 섹션에서 기본 정보를 확인할 수 있습니다. From 주소와 To 주소, 전송된 Value, 사용된 Gas 등이 표시됩니다.
여기서 중요한 것은 Gas Used와 Gas Limit의 비교입니다. 두 값이 같다면 가스 부족으로 실패했을 가능성이 높습니다.
김개발 씨가 확인한 트랜잭션은 가스 부족은 아니었습니다. 아래로 스크롤하니 Revert Reason 섹션이 있었습니다.
"Insufficient balance"라는 메시지가 표시되어 있었습니다. 잔액 부족으로 실패한 것이었습니다.
박시니어 씨가 다가와 말했습니다. "Revert Reason이 바로 보인다니 편하죠?
예전에는 트랜잭션 데이터를 직접 디코딩해야 했어요." Internal Transactions 탭도 중요합니다. 스마트 컨트랙트가 다른 컨트랙트를 호출하면 내부 트랜잭션이 발생합니다.
복잡한 DeFi 트랜잭션에서는 수십 개의 내부 트랜잭션이 있을 수 있습니다. Blockscout은 이를 시각적으로 보여줍니다.
Logs 탭에서는 이벤트 로그를 확인할 수 있습니다. 컨트랙트에서 emit한 이벤트들이 여기에 표시됩니다.
컨트랙트가 검증되어 있다면 이벤트 이름과 파라미터가 디코딩되어 읽기 쉽게 표시됩니다. Raw Input 섹션에서는 트랜잭션의 원본 데이터를 볼 수 있습니다.
컨트랙트 호출의 경우 함수 시그니처와 파라미터가 인코딩되어 있습니다. Decode Input 버튼을 클릭하면 사람이 읽을 수 있는 형태로 변환해줍니다.
검색 기능은 트랜잭션 해시 외에도 다양한 입력을 지원합니다. 주소를 검색하면 해당 주소의 모든 트랜잭션 내역을 볼 수 있습니다.
블록 번호를 검색하면 해당 블록의 상세 정보로 이동합니다. 고급 검색 기능도 있습니다.
Transactions 페이지에서 필터를 적용하면 특정 조건의 트랜잭션만 볼 수 있습니다. 예를 들어 특정 주소로 보낸 트랜잭션만, 또는 특정 컨트랙트를 호출한 트랜잭션만 필터링할 수 있습니다.
김개발 씨는 QA 팀에 답변을 보냈습니다. "테스트 계정의 잔액이 부족해서 발생한 문제입니다.
계정에 이더를 충전하고 다시 시도해주세요." 문제 해결에 5분도 걸리지 않았습니다. Blockscout이 없었다면 로그를 뒤지고 RPC를 직접 호출하느라 한 시간은 걸렸을 것입니다.
실전 팁
💡 - Failed 트랜잭션은 Revert Reason을 먼저 확인하세요
- 내부 트랜잭션은 visualizer 서비스가 있으면 그래프로 더 직관적으로 볼 수 있습니다
6. 컨트랙트 검증하기
김개발 씨가 배포한 스마트 컨트랙트를 Blockscout에서 열어보니, 바이트코드만 표시되었습니다. "0x608060405234..." 이게 무슨 의미인지 누가 알 수 있을까요?
선배가 말했습니다. "컨트랙트를 검증해야 소스코드가 보여요.
그래야 다른 사람들이 뭘 하는 컨트랙트인지 알 수 있죠."
컨트랙트 검증은 배포된 바이트코드와 원본 Solidity 소스코드가 일치하는지 확인하는 과정입니다. 검증이 완료되면 누구나 웹에서 소스코드를 읽고, 함수를 직접 호출할 수 있습니다.
마치 식품의 원산지 인증처럼, 컨트랙트의 신뢰성을 보장하는 중요한 절차입니다.
다음 코드를 살펴봅시다.
// Hardhat을 사용한 컨트랙트 검증 설정
// hardhat.config.ts
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-verify";
const config: HardhatUserConfig = {
networks: {
private: {
url: "http://localhost:8545",
},
},
etherscan: {
apiKey: {
private: "any-string-will-work" // Blockscout은 API 키 검증 안 함
},
customChains: [
{
network: "private",
chainId: 1337,
urls: {
apiURL: "http://localhost:4000/api",
browserURL: "http://localhost:4000"
}
}
]
}
};
// 검증 실행: npx hardhat verify --network private CONTRACT_ADDRESS
김개발 씨는 Blockscout에서 자신이 배포한 컨트랙트 페이지를 열었습니다. Contract 탭을 클릭하니 16진수 바이트코드만 잔뜩 표시되었습니다.
일반인은 물론이고 개발자가 봐도 이게 어떤 로직인지 전혀 알 수 없는 상태였습니다. "컨트랙트 검증이 필요해요." 박시니어 씨의 설명이 이어졌습니다.
"검증을 하면 바이트코드가 아니라 원본 Solidity 코드가 표시돼요. 그리고 웹에서 직접 함수를 호출할 수도 있죠." 컨트랙트 검증을 식품 인증에 비유해보겠습니다.
마트에서 파는 제품에 "국내산 한우"라고 적혀 있다고 해서 다 믿을 수 있을까요? 인증 마크가 있어야 신뢰가 생깁니다.
컨트랙트 검증도 마찬가지입니다. "이 바이트코드는 정말 이 소스코드에서 컴파일된 것이 맞습니다"라는 인증을 받는 과정입니다.
검증 방법은 크게 두 가지입니다. 첫 번째는 웹 UI에서 직접 소스코드를 업로드하는 방법입니다.
컨트랙트 페이지에서 "Verify & Publish" 버튼을 클릭하면 소스코드 입력 폼이 나타납니다. 폼에서 요구하는 정보는 다음과 같습니다.
컴파일러 버전, 최적화 여부, 최적화 런 횟수, 그리고 소스코드 자체입니다. 이 정보들이 배포 시 사용한 설정과 정확히 일치해야 검증에 성공합니다.
두 번째 방법은 Hardhat 같은 개발 도구를 사용하는 것입니다. 위의 설정 코드처럼 hardhat.config.ts에 Blockscout API URL을 등록하면, 터미널에서 명령어 한 줄로 검증할 수 있습니다.
Hardhat 검증에서 주목할 점은 customChains 설정입니다. Blockscout은 Etherscan API와 호환되므로, Hardhat의 etherscan 플러그인을 그대로 사용할 수 있습니다.
다만 API URL만 Blockscout 주소로 변경해주면 됩니다. 검증 과정에서 가장 흔한 실패 원인은 컴파일러 버전 불일치입니다.
소스코드에 pragma solidity ^0.8.0이라고 적혀 있어도, 실제 컴파일에 사용된 버전은 0.8.19일 수 있습니다. 정확한 버전을 명시해야 합니다.
최적화 설정 불일치도 자주 발생합니다. 배포할 때 optimizer를 활성화했다면 검증할 때도 같은 설정을 사용해야 합니다.
runs 값까지 정확히 일치해야 합니다. 검증에 성공하면 Contract 탭의 모습이 완전히 바뀝니다.
바이트코드 대신 Solidity 소스코드가 구문 강조와 함께 표시됩니다. Read Contract와 Write Contract 버튼도 활성화됩니다.
Read Contract에서는 view 함수와 public 변수를 조회할 수 있습니다. 클릭 한 번으로 현재 상태를 확인할 수 있어 디버깅에 유용합니다.
Write Contract에서는 MetaMask 같은 지갑을 연결하여 상태를 변경하는 함수를 직접 호출할 수 있습니다. 김개발 씨는 Hardhat 명령어를 실행했습니다.
"Successfully verified contract!"라는 메시지가 나타났습니다. Blockscout을 새로고침하니 소스코드가 깔끔하게 표시되었습니다.
"이제 QA 팀도 컨트랙트 함수를 직접 테스트할 수 있겠네요." 김개발 씨는 뿌듯했습니다. 컨트랙트 검증은 단순한 절차가 아니라, 팀 전체의 생산성을 높이는 중요한 단계입니다.
실전 팁
💡 - 배포와 검증을 하나의 스크립트로 자동화하면 실수를 줄일 수 있습니다
- 라이브러리를 사용하는 컨트랙트는 flatten된 소스코드가 필요할 수 있습니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
마이크로서비스 배포 완벽 가이드
Kubernetes를 활용한 마이크로서비스 배포의 핵심 개념부터 실전 운영까지, 초급 개발자도 쉽게 따라할 수 있는 완벽 가이드입니다. 실무에서 바로 적용 가능한 배포 전략과 노하우를 담았습니다.
CloudFormation 기초 완벽 가이드
AWS 인프라를 코드로 관리하는 CloudFormation의 기초부터 실전까지 다룹니다. 템플릿 작성부터 스택 관리까지, 초급 개발자도 쉽게 따라 할 수 있는 실무 중심 가이드입니다.
AWS CodePipeline 구성 완벽 가이드
AWS CodePipeline을 처음 접하는 개발자를 위한 실전 가이드입니다. 파이프라인 생성부터 소스, 빌드, 배포 스테이지 구성까지 단계별로 배워봅니다. 자동화된 CI/CD 파이프라인을 직접 만들어보세요.
ECS 오토스케일링 완벽 가이드
AWS ECS에서 트래픽에 따라 자동으로 서비스를 확장하고 축소하는 오토스케일링 설정 방법을 초급 개발자도 쉽게 이해할 수 있도록 실무 중심으로 설명합니다. 비용 최적화와 안정적인 서비스 운영의 핵심 기술입니다.
Application Load Balancer 완벽 가이드
AWS의 Application Load Balancer를 처음 배우는 개발자를 위한 실전 가이드입니다. ALB 생성부터 ECS 연동, 헬스 체크, HTTPS 설정까지 실무에 필요한 모든 내용을 다룹니다. 초급 개발자도 쉽게 따라할 수 있도록 단계별로 설명합니다.