SCW 거래 디코딩
스마트 계약 지갑(SCW)에서는 스왑이 전통적인 이더리움/EVM 지갑과는 매우 다른 경로를 거칩니다. 이 차이는 특히 문제가 발생했을 때 혼란스러울 수 있습니다. 하지만 흐름의 주요 참여자들과 앱 및 익스플로러에서 단계별로 무슨 일이 일어났는지 읽는 방법을 이해하면 상황이 이해되기 시작합니다.
같이 살펴봅시다.
한 번의 탭에서 온체인 실행까지: 실제로 무슨 일이 일어나는가
앱에서 “스왑”을 탭하면 한 번의 동작처럼 느껴집니다. 실제로는 이더리움의 계정 추상화(ERC-4337) 위에 구축된 다층 프로세스를 시작하는 것입니다. 당신의 트랜잭션은 일반 지갑처럼 곧바로 블록체인으로 가지 않습니다. 대신 우회 경로를 탑니다:
우리는 경로를 구성합니다. 라우팅 엔진(예: 1inch)에게 스왑에 가장 적합한 경로를 찾도록 요청하고, 작동하는지 시뮬레이션합니다. 가스를 추정하고 토큰 보유를 확인한 뒤 지침을 특수 형식으로 포장합니다:
UserOperation
.A
번들러
가 개입합니다. 이는 UserOperation을 블록체인에 제출하는 오프체인 행위자입니다. 번들러는 당신의 오퍼레이션을 검사하고 유효한지 확인하며 가스를 선결제합니다(나중에 상환받습니다).당신의 UserOp은
EntryPoint
스마트 계약을 통해 블록체인에 들어갑니다. EntryPoint를 모든 SCW 트랜잭션이 통과하는 하나의 관문으로 생각하세요. EntryPoint는 최종 검사를 수행하고, 모든 것이 정상이라면…EntryPoint는 당신의 스마트 계약 지갑(SCW)에게 스왑을 실행하라고 지시합니다. 당신의 SCW가 라우터(예: 1inch)를 호출하고, 라우터가 풀을 호출하며, 토큰이 이동하고 출력이 다시 지갑으로 돌아옵니다.
정리하면: 당신이 스왑을 탭 → 우리가 시뮬레이션 → 번들러가 제출 → EntryPoint가 검증 → 당신의 SCW가 실행합니다.
실제 예시를 살펴봅시다
이제 상위 수준의 흐름을 이해했으니, 실제 스왑에서는 어떻게 진행되는지 앱에서 먼저, 그다음 온체인에서 살펴봅시다:
우리가 보는 내용은 다음과 같습니다:
우리는 1 USDC를 0.765 KTA로 스왑했습니다.
스왑은 Base에서 실행되었습니다(코인 심볼의 Base 아이콘을 확인하세요).
우리가 지불한 것:
$0.03 가스(ETH로)
goodcryptoX에 0.22% 스왑 수수료
1inch에 0.05% 라우터 수수료
경로는 단순했습니다: 100% Uniswap v4 풀을 통해.
번들러: Alchemy (위의 2단계 요약 참조)
익스플로러 링크는 트랜잭션이 블록체인에 도달해 블록에 기록된 경우(실패한 경우에도) 표시됩니다
지금까지 괜찮습니다. 다음으로 BaseScan 링크를 클릭하여 이 트랜잭션이 온체인에서 어떻게 보이는지 봅시다:
보낸 주소(From): 이것은 당신의 지갑이 아니라 Alchemy의 번들러입니다. 번들러가 트랜잭션을 제출했으므로 이는 예상된 것입니다.
받는 주소(To): EntryPoint (v0.6.0). 다시 말하지만, 예상된 것입니다 — 모든 SCW 트랜잭션은 여기로 들어갑니다.
내부 트랜잭션(Internal Transactions): 트랜잭션 내에서 기본 토큰(여기서는 Base의 ETH)의 흐름을 보여줍니다. 우리가 보는 내용은 다음과 같습니다:
우리 지갑(…0A5)이 가스 비용을 위해 ETH를 EntryPoint로 보냈습니다.
EntryPoint는 번들러에게 실제 가스 비용을 상환했습니다(번들러가 대신 가스를 선결제했기 때문입니다; 위의 2단계 참조). 남은 ETH는 향후 트랜잭션을 위한 예치금으로 EntryPoint에 남아 있었습니다.
ERC-20 전송(ERC-20 Transfers): 실제 토큰 이동을 보여줍니다:
우리 지갑이 USDC를 직접 전송하지 않았습니다. 대신 USDC 토큰 계약(…2A8)이 전송을 처리하고 발송했습니다. 이는 정상입니다: EVM 체인에서는 토큰 전송이 스마트 계약 지갑의 지시를 받은 후 토큰 계약 자체에 의해 처리됩니다.
USDC 계약은 우리의 1 USDC를 세 건의 전송으로 분할했습니다:
0.0022 USDC는 우리의 프로토콜 수수료 지갑(…608A)으로
0.0005 USDC는 1inch의 수수료 지갑(…1DE5)으로
나머지 0.9973 USDC는 Uniswap v4 라우터(…Universal Router)로
Uniswap v4 라우터는 이를 Uniswap v4 풀 매니저(모든 v4 풀을 처리하는 단일 계약)로 전달했습니다.
풀 매니저는 스왑을 실행했습니다: USDC 투입 → KTA 배출.
KTA는 1inch의 Aggregation Router를 통해 다시 라우팅되어 우리 지갑(…0A5)으로 전달되었습니다.
🧩 실패한 SCW 트랜잭션을 해독하는 방법
이제 스마트 계약 지갑(SCW) 스왑이 어떻게 작동하는지 — 그리고 성공적인 거래를 통해 살펴본 내용을 — 이해했으므로 같은 도구를 사용해 실패한 거래를 해석해봅시다.
또 다른 실제 사례를 사용하겠습니다: EntryPoint 계약 내부에서 스왑과 가스 비용을 모두 충당할 충분한 ETH가 없어 실패한 이더리움에서 토큰으로의 스왑입니다.
앱에서 스왑 상태가 "Error"로 보이거나 스왑 실패 푸시 알림을 받았습니다. 무엇을 해야 할까요?
1단계 — goodcryptoX에서 주문 세부 정보를 확인하세요
이 경우에 보이는 것은 다음과 같습니다:
우리가 앞서 개발한 프레임워크를 사용하면, 당신은 빠르게 다음을 알아차립니다:
스왑 상태는
Error
(실패?)오류 메시지가 표시되지 않음 (그건 이상함)
가스 요금이 있음 (블록체인에 도달했나?)
경로가 표시됨 (시뮬레이션은 괜찮았나?)
블록체인 익스플로러 링크가 있음 (트랜잭션을 블록체인에서 확인할 수 있다!).
직감(직관)을 확인해봅시다:
그
Error
상태는 스왑이 실패했음을 의미합니다사람이 읽을 수 있는 오류 메시지(원문에서 번역된 것)와 원문 오류 메시지 둘 다 있어야 합니다. 오류 메시지가 없다는 것은 확실히 무언가 비정상적인 일이 발생했음을 의미합니다
가스 요금이 존재한다는 것은 트랜잭션이 블록체인에 도달했고 일부 온체인 활동이 있었음을 의미합니다(가스를 소모함)
경로는 트랜잭션 시뮬레이션이 통과되어 실행 가능한 명확한 경로가 있었음을 확인합니다
익스플로러 링크는 트랜잭션이 실패했더라도 블록체인에 도달했음을 확인합니다. 우리는 반드시 그 중 하나를 열어 더 조사해야 합니다
2단계 – 블록체인 익스플로러에서 트랜잭션 열기
무슨 일이 있었는지 보려면 Etherscan 링크를 탭하세요:
언뜻 보면 상황은 더 혼란스러워집니다:
상태에 ✅ 성공(Success)이라고 표시됩니다 — 잠깐, 뭐지?!
하지만 우리는 이미 스왑이 성사되지 않았다는 것을 알고 있습니다
“To” 필드(EntryPoint) 아래에 작은 노란 메시지가 있습니다:
“하나 이상의 오류가 발생했음 [execution reverted] 계약 실행 완료”
그럼 실제로 무슨 일이 일어나고 있는 걸까요?
이전에 다룬 SCW 트랜잭션 흐름을 기억하세요:
번들러는 당신의 스왑을
UserOperation
(스왑 로직이 포함된 데이터 패키지)로 감싸고그다음 이를 EntryPoint 스마트 계약으로 보냅니다
EntryPoint는 이를 검증합니다(잔액, 서명, 논스 검사)
모든 검사가 통과하면 의도를 실행합니다 — 라우터와 풀을 호출하고 토큰을 이동시킵니다.
그러나 블록체인의 관점에서 보면 이 모든 것은 단지 "번들러가 데이터를 EntryPoint로 보냈다"처럼 보입니다.
SCW 관점에서 이 단계는 외부(outer)
트랜잭션이라고 불립니다.
그리고 그 트랜잭션은 성공했습니다: 데이터가 전달되었고 EntryPoint는 내부 로직을 실행하기 시작했습니다. 따라서 상단에 ✅ 성공이 표시됩니다.
그러나 익스플로러는 예의상 내부에서 뭔가 실패했음을 알려줍니다 EntryPoint 내부에서의 실패를 그 작은 노란색 알림으로 표시합니다. 익스플로러에게 내부 실패만으로는 트랜잭션을 실패로 표시하기에 충분하지 않습니다.
이제 Overview 탭에서 또 다른 상세가 눈에 띕니다:
약 $6 상당의 ETH가 당신의 지갑에서 EntryPoint로 전송되었습니다(가스 선결제).
오직 $2.3 상당의 ETH만이 번들러에게 상환되었습니다.
그리고 상단에 표시된 트랜잭션 수수료는 더 낮습니다 — 약 $2.15.
언뜻 보기에 이 숫자들은 합이 맞지 않는 것처럼 보입니다. 계속 조사하기 전에 이를 먼저 풀어봅시다
3단계 – 가스 불일치 이해하기
분해하면 다음과 같습니다:
SCW → EntryPoint (~$6): 이는 가스 선결제입니다. EntryPoint는 UserOp가 실행될 수 있도록 항상 필요한 것보다 더 많이 수집합니다.
EntryPoint → 번들러 (~$2.3): 이는 실제 가스 상환입니다. 이것이 이 실패한 시도에 대해 당신이 실제로 지불한 금액 입니다.
트랜잭션 수수료 (~$2.15): 이는 번들러가 당신의 UserOp를 EntryPoint로 보내기 위해 사용한 비용입니다. EntryPoint 자체가 검증하고 번들러에게 상환하는 동안 추가 가스를 사용했기 때문에 이 비용은 더 낮게 보입니다 — 그 추가 비용은 당신에게 부과되었습니다.
일반 규칙:
👉 당신의 실제 가스 비용은 항상 EntryPoint ➜ 번들러 상환금입니다(상단에 표시된 “트랜잭션 수수료”가 아님).
그리고 당신이 선결제한 금액($6)과 상환된 금액($2.3)의 차이는 사라지지 않았습니다. 그것은 향후 트랜잭션에 자동으로 적용될 당신의 예치금으로 EntryPoint에 남아 있습니다.
4단계 – AA Transactions 탭 확인하기
익스플로러에서 당신은 AA Transactions 탭(AA = Account Abstraction)을 볼 수 있습니다. SCW 활동은 여기에서 확인할 수 있는데, SCW가 계정 추상화(ERC-4337)로 실행되기 때문입니다.
Overview에서 그 탭으로 전환해봅시다:
여기에서 마침내 번들러의 외부 트랜잭션 안에 별도의 항목으로 나열된 우리의 UserOperation을 볼 수 있습니다:
"From" 필드는 이제 우리 지갑 주소를 표시하여 이것이 우리의 오퍼레이션임을 확인합니다.
외부 트랜잭션 해시와 다른 별도의 AA Txn Hash가 있습니다. 왜일까요?
외부 Txn Hash는 당신의 UserOp를 포함한 번들러->EntryPoint 트랜잭션에 속합니다(여러 사용자의 여러 UserOp를 포함했을 수도 있습니다).
AA Txn Hash는 그 번들 안에서 당신의 UserOperation의 고유 식별자입니다.
이것이 번들링의 핵심 아이디어입니다:
번들러는 여러 UserOp를 하나의 트랜잭션으로 패키징할 수 있습니다.
각 UserOp는 자체 AA Txn Hash를 받아 번들 내에서 별도로 추적될 수 있습니다.
우리의 경우, 이 트랜잭션은 오래된(400일 이상 전) 것으로 SCW가 아직 드물었고 번들에 우리 UserOp만 포함되어 있었기 때문에 탭에 “AA Transactions (1)”이라고 표시됩니다. 최신 트랜잭션에서는 여러 UserOp가 하나의 번들로 배치된 것을 자주 보게 될 것입니다.
이 뷰에서 AA Txn Hash 옆에 (!) 아이콘이 표시된 것도 보게 될 것입니다 — 이것은 당신의 스왑이 실행되지 않았음을 확인해줍니다.
다음 단계는 AA Txn Hash를 클릭하는 것입니다. 그러면 전용 UserOperation 페이지가 열리며, 그곳에서 수수료, 전송 및 실패 지점을 포함한 우리의 스왑 시도에 대한 전체 세부 정보를 볼 수 있습니다.
5단계 – AA 트랜잭션 상세 페이지 열기
AA Txn Hash를 클릭하면 당신의 UserOperation 전용 상세 페이지로 이동합니다:
여기에서 마침내 우리의 실제 스왑 시도가 명확하게 표시됩니다:
상태: x 실패(Fail) (이번에는 모호함 없음)
From: 당신의 스마트 계약 지갑 주소
AA 트랜잭션 수수료: 약 0.00231 ETH ($2.31). 이것이 당신이 실제로 지불한 가스 비용 — 번들러에게 상환된 금액입니다.
내부 트랜잭션: 당신의 SCW에서 EntryPoint로 약 0.00145 ETH (~$6.36)의 한 건의 전송 = 가스 선결제. 다른 전송은 발생하지 않아 스왑 자체는 실행되지 않았음을 확인합니다.
번들 Txn 해시: 외부 번들러 트랜잭션으로 다시 연결되는 해시도 표시됩니다.
이 페이지는 마침내 당신의 직관과 일치합니다: 이것이 실제 트랜잭션 — 당신의 스왑 시도를 나타내는 UserOperation입니다.
조사가 거의 끝났습니다. 하지만 여기까지 왔으니 Internal Txns.
도 클릭해봅시다.
6단계 – Internal Transactions 탭 확인하기
AA 트랜잭션 뷰 내에서 Internal Txns 탭으로 전환하세요:
여기에서 EntryPoint가 당신을 대신해 시도하려 했던 단계별 동작을 볼 수 있습니다:
✅ 당신의 SCW → EntryPoint로의 전송 (~0.00145 ETH, 약 $6.36) = 가스 선결제. 이는 성공했습니다.
❌ 당신의 SCW → Uniswap Universal Router로의 실행 (~0.002 ETH) = 시도된 스왑. 이는 실패했습니다.
이 분석은 실패의 이유를 설명합니다:
당신은 가스 선결제로 ETH를 EntryPoint로 성공적으로 보냈습니다.
그러나 EntryPoint가 스왑을 위해 ETH를 Uniswap으로 전달하려 했을 때 그 시도는 실패했습니다.
가장 자세한 분해를 보려면 Logs 탭을 여십시오.
7단계 – Logs 탭 검사하기
Logs (3)를 클릭하세요:
여기에서 세 가지 주요 이벤트를 찾을 수 있습니다: Deposited
→ 당신의 가스 선결제가 EntryPoint에 수신되었음을 확인합니다. BeforeExecution
→ EntryPoint가 당신의 UserOperation 처리를 시작했음을 보여줍니다. UserOperationEvent
→
success: False
— 당신의 UserOp가 실패했음을 나타내는 정식 온체인 기록입니다.
실제로 무슨 일이 일어났는가(모두 종합하면)
이 유형의 실패는 입력이 기본 토큰(ETH, BNB, MATIC 등)인 SCW 스왑에서 EVM에서 발생하는 특정한 상황입니다. 격차: 번들러나 EntryPoint 둘 다 당신이 가스 선결제와 스왑을 함께 충당할 만큼 충분한 기본 토큰
을 가지고 있는지 확인하지 않습니다. 이들은 이를 별도로만 검사합니다 — “가스는 충분한가?” 그리고 “스왑은 충분한가?” 그래서 시뮬레이션이 통과된 것입니다.
우리는 앱에 이런 경우를 대비한 실패 방지 장치를 만들어 인터페이스에서 가스가 부족할 수 있음을 경고했습니다. 그러나 시뮬레이션이 괜찮아 보였기 때문에 당신은 계속 진행할 수 있었습니다.
당신이 확인하자 번들러가 당신의 UserOperation을 EntryPoint에 제출했습니다.
EntryPoint는 약 $6 상당의 ETH를 선결제로 가져갔습니다. 스왑을 실행하려 했을 때, 스왑과 선결제를 동시에 충당할 만큼 남은 ETH가 없었습니다.
스왑 호출은 EntryPoint 내부에서 되돌아갔습니다(reverted).
당신은 여전히 약 $2.3의 가스(번들러에 대한 상환금)를 지불했습니다.
사용되지 않은 약 $3.7는 당신의 예치금으로 EntryPoint에 남아 다음 트랜잭션에 자동으로 사용될 것입니다.
Last updated