DApp을 개발하면서 고려해야할 온체인-오프체인 동기화 문제

Yujeong Lee
Decipher Media |디사이퍼 미디어
15 min readJan 8, 2022

블록체인 기반의 DApp 서비스를 사용해보면 트랜잭션 처리가 완료되었다는 화면을 볼 수 있다. 필자는 이 화면을 보면서 “트랜잭션이 취소될 가능성도 있는데 트랜잭션의 처리가 완료되었다는 알림을 사용자에게 이렇게 빨리 알려줘도 되는 건가? 취소되면 어떻게 되는거지?”라는 생각을 해본 적이 있다. 블록체인 기반 서비스들은 트랜잭션의 처리 단계 중 언제 트랜잭션 처리가 완료되었다고 알려주며, 취소되면 사용자들에게 어떻게 알려주는걸까?

오늘 소개할 논문 “ÐArcher: Detecting On-Chain-Off-Chain Synchronization Bugs in Decentralized Applications”에서는 온체인-오프체인의 동기화 버그에 대해 설명하고, 2가지 타입의 온체인-오프체인의 버그에 대해 정의하고 실험을 통해 실제 이더리움 기반의 DApp에서 얼마나 많은 온체인-오프체인 동기화 버그가 발생하고 있는지 보여준다.

Introduction & Background

DApp

그림 1. DApp 구조

프로그래밍이 가능한 스마트 컨트랙트(Smart Contract)를 도입한 이더리움이 등장하면서 DApp(Decentralized Application) 서비스가 등장했다. DApp은 블록체인 위에서 동작하는 애플리케이션을 말하며, 우리가 많이 알고 있는 Defi, 크립토키티 등 모두 DApp 이다. 2021년 4월을 기준으로 이더리움에는 270만 이상의 DApp이 존재한다. DApp은 그림 1과 같이 온체인(on-chain)과 오프체인(off-chain)으로 구성되어 있다. 온체인은 블록체인에 데이터를 저장하고 상태를 업데이트할 수 있는 스마트 컨트랙트로 구성되어 있으며, 오프체인은 사용자와 상호작용하는 front-end client와 centralized Service로 구성되어 있다.

블록체인의 Finality

블록체인의 특성 중 완결성(Finality)이라는 특성이 있다. 완결성은 한번 실행되고 처리된 거래는 다시는 되돌려질 수 없다는 특성으로 블록체인에서 분기가 발생하는 경우 longest chain rule에 의해 가장 긴 체인이 선택되어 짧은 체인에 연결된 블록과 트랜잭션은 취소되어 완결성이 깨질 수 있다. 하지만 시간이 지나 블록이 많이 생겨날수록 블록은 취소되거나 되돌려지지 않을 확률이 높아진다. 즉, 내 트랜잭션이 포함된 블록 뒤에 많은 블록이 연결될수록 완결성이 높아져 내 거래가 취소되거나 되돌려질 걱정을 하지 않아도 된다. 각 블록체인마다 완결성을 보장하는 블록의 개수가 있다. 비트코인의 경우 6개로 한 블록이 생성되는데 평균 10분의 시간이 소요되어 약 1시간이 지나면 완결성을 보장한다. 이더리움도 완결성을 보장하는 블록의 개수는 6개, 한 블록이 생성되는데 평균 15초가 소요되어 약 1분 30초가 지나면 완결성을 보장한다.

METHODOLOGY

Transaction Lifecycle

그림 2. 이더리움 트랜잭션 생명 주기

그림 2는 이더리움 트랜잭션의 생명주기를 나타낸다. 사용자가 오프체인에서 블록체인에 트랜잭션을 전송하여 생성된(Created) 트랜잭션은 트랜잭션 풀에 추가되어 실행을 기다리는 보류(pending) 상태가 된다. 그리고 블록에 담겨 실행(Executed)되고 시간이 지나 현재 블록 뒤에 충분한 블록이 생성되면 완결(Finalized)상태가 된다. 트랜잭션이 항상 문제없이 완결상태까지 도달하면 좋겠지만, 그림과 같이 각 단계에서 트랜잭션이 삭제되거나 실행이 취소될 가능성도 있다.

보류 상태에서는 두 가지 경우로 트랜잭션이 삭제(drop)될 수 있다.

  1. 사용자가 이전 트랜잭션과 중복된 트랜잭션을 전송하거나 더 빠른 처리를 위해 더 높은 수수료를 제안하면 이전 트랜잭션은 무시되어 삭제될 수 있다.
  2. 채굴자(miner)의 트랜잭션 풀 용량이 꽉 차거나 다른 이익을 위해 채굴자가 악의적으로 트랜잭션을 삭제할 수 있다.

실행 단계에서 변경될 수 있는 반전된(Reversed) 상태는 앞서 설명한 블록체인의 분기로 인해 변경될 수 있는 상태이다. 만약 트랜잭션이 담긴 블록이 취소되면 취소된 블록에 담겨있던 트랜잭션들은 다시 되돌려지며 트랜잭션의 풀로 돌아가 블록에 담겨 실행을 기다리는 반전상태로 변경된다. 반전상태에서도 보류상태와 같이 트랜잭션이 삭제될 수 있다.

본 논문에서는 4개월 동안 이더스캔(Etherscan)에서 이더리움 트랜잭션을 조사한 결과 이더리움에서 초당 발생하는 트랜잭션의 개수는 32.5개이며, 이더리움 초당 트랜잭션 처리 개수(TPS)가 16.4개이므로 절반이 넘는 트랜잭션은 즉시 실행되지 못한다고 한다. 또한 분기로 인한 체인 재구성이 평균 24.43(약 11.06분)블록마다 발생한다는 것을 발견했다. 1시간마다 평균 16.69개의 트랜잭션이 반전상태로 전환되기 때문에 절대 무시할 수 있는 수준이 아님을 보여주고 있다. 따라서 DApp 개발 시 온체인-오프체인 동기화 버그를 피하기 위해 반드시 비결정적(non-deterministic)인 트랜잭션을 고려해야 한다.

on-chain-off-chain synchronization bug

온체인-오프체인 버그(on-chain-off-chain synchronization bug)는 온체인과 오프체인 상태가 일관성을 유지하지 못할 때 생기는 버그를 말한다. 앞서 설명한 것과 같이 트랜잭션의 생명주기를 고려해보면 보류상태가 되어도 블록에 포함되지 않고 삭제될 수 있으며 실행이 완료된 후에도 트랜잭션이 포함된 블록이 취소되어 트랜잭션의 실행이 되돌려지고 삭제될 수 있어 비결정적인 특성이 있다. 하지만 DApp 개발자들은 트랜잭션의 비결정적인 특성을 고려하지 않고 개발하여 서비스에 잘못된 정보를 제공하는 경우가 있다. 온체인-오프체인 동기화 버그로 인해 잘못된 상태를 나타내고 있는 오프체인 서비스를 보고 사용자가 잘못된 작업을 요청 또는 수행하거나 수수료가 낭비되는 문제가 발생할 수 있다.

본 논문에서는 이를 온체인-오프체인 동기화 버그라고 정의하며 2가지 타입(Type-1, Type-2)의 온체인-오프체인 동기화 버그에 대해 설명한다.

Type-1 bug

그림 3. Type-1 버그

그림 3은 type-1 버그가 발생하는 상황을 나타낸다. Type-1 버그는 트랜잭션이 보류 상태일 때 오프체인의 상태를 변경시키는 경우 발생한다. 트랜잭션이 보류 상태일때 오프체인에서 트랜잭션 처리 완료로 상태를 변경하면 보류 상태 이후에 채굴자가 트랜잭션을 블록에 담지 않아 처리되지 않으면 온체인-오프체인 동기화 문제가 발생할 수 있으며 이를 type-1 버그로 정의한다.

Type-2 bug

그림 4. Type-2 버그

그림 4는 type-2 버그가 발생하는 상황을 나타낸다. Type-2 버그는 트랜잭션이 보류 상태를 지나 실행 상태에서 오프체인의 상태를 변경할 때 발생한다. 실행 상태에서는 트랜잭션이 실행되었기 때문에 상태가 변경되지 않을 것이라고 생각할 수 있지만, 분기가 발생하여 해당 트랜잭션이 담긴 블록이 선택되지 않은 경우 해당 트랜잭션은 상태가 되돌려지고 삭제된다. 따라서 실행 상태에서 오프체인의 상태를 변경하게 되면 온체인-오프체인 동기화 문제가 발생할 수 있으며, 이를 type-2 버그로 정의한다.

ÐArcher 테스팅 프레임워크

ÐArcher 테스팅 프레임워크는 효과적으로 버그를 탐지하기 위해 테스트 오라클(test oracle)을 설계하고 사용한다.

Test oracle : 테스트를 수행한 결과가 참인지 거짓인지를 판단하기 위해서 미리 정의된 참 값을 대입하여 비교하는 소프트웨어 테스트 기법

Test Oracle for Type-1 bug

Assertion 1. For each transaction 𝑡,𝜎(𝑡,Created)≠𝜎(𝑡,Finalized) implies 𝜎 (𝑡, Pending) ≠ 𝜎 (𝑡, Finalized).

Type-1 버그는 트랜잭션(t)이 트랜잭션 풀에 추가될 때, DApp은 트랜잭션이 실행되어 완결된 것처럼 너무 빨리 상태를 변경하면 안된다. Assertion 1는 𝜎(𝑡,𝑠)는 트랜잭션 t가 트랜잭션 상태 s일 때 DApp의 오프체인 상태를 나타낸다. 𝜎(𝑡, Created)≠𝜎(𝑡, Finalized)는 트랜잭션이 생성되었을때 상태 변경은 가능하지만, 상태가 완결 상태로 변경되어서는 안된다는 것을 의미하며, 𝜎 (𝑡, Pending) ≠ 𝜎 (𝑡, Finalized)는 트랜잭션이 보류 상태에서 상태 변경은 가능하지만, 완결 상태로 변경되어서는 안된다는 것을 의미한다. 따라서 트랜잭션의 상태가 생성, 보류 상태일 때 오프체인에서 완결 상태로 변경한다면 type-1 버그가 있음을 나타낸다.

Test Oracle for Type-2 bug

Assertion 2. For each transaction 𝑡,𝜎(𝑡,Pending) =𝜎(𝑡,Reversed).

Type-2 버그는 트랜잭션(t)이 실행 상태가 될때 오프체인의 상태를 변경할 수 있다. 하지만 체인이 취소되어 트랜잭션이 반전(Reversed) 상태로 변경되면 오프체인의 상태가 변경되지 않는 버그를 말한다. 따라서 Assertion 2는 트랜잭션의 상태가 반전 상태가 되면 보류 상태와 같아야 한다는 것을 의미한다. Assertion 2를 위반하는 경우 Type-2의 버그가 있음을 나타낸다.

Assertion : 개발자가 반드시 참(true)이어야 한다고 생각하는 주장을 표현한 논리식이다. Assertion을 코드로 구현하여 위반하는 경우가 발견되면 버그나 문제가 발생했다고 간주한다.

Implementation

ÐArcher 구조

위 그림은 ÐArcher의 작업 흐름을 보여준다. 먼저 Front-End Explorer에서 UI 이벤트를 발생 시켜 트랜잭션을 전송하면 Controlled Blockchain에서 트랜잭션을 실행한다. ÐArcher는 트랜잭션의 상태 업데이트에 따라 오프체인의 상태를 확인하며 버그를 탐지한다. 위 그림에서 Controlled Blockchain은 트랜잭션의 생명주기를 생성(Created)-보류(Pending)-실행(Executed)-반전(Reversed)-실행(Executed)-완결(Finalized) 순서로 트랜잭션의 상태를 제어할 수 있도록 구현된 블록체인이다.

EVALUATION

본 논문에서는 다음과 같은 3가지 질문에 대한 실험을 진행한다.

  • RQ1 (Bug Detection Capability)
    ÐArcher가 실제 DApp에서 온체인-오프체인 동기화 버그를 효과적으로 감지할 수 있는가?
  • RQ2(Efficacy of Our Oracles)
    본 논문에서 제안한 오라클의 효율성은 어느정도인가?
  • RQ3 (Usefulness)
    ÐArcher가 개발자에게 유용한가?

실험 환경

표 1. 실험에 사용된 DApp 리스트

본 논문에서는 실험을 위해 Github에서 100개 이상의 star를 받은 DApp 프로젝트 중에서 웹 애플리케이션으로 구현되어 있고, local controlled blockchain에 배포가 가능한 스마트 컨트랙트를 사용하는 11개 프로젝트를 선정했다. Local Controlled Blockchain에 선정된 DApp들을 배포해서 실험을 진행하며 Baseline-1과 Baseline-2를 ÐArcher과 비교한다.

실험 결과

본 논문에서는 실험을 위해 Local Controlled Blockchain에 선정된 DApp들을 배포해서 실험을 진행한다. 그리고 ÐArcher의 대기시간을 이더리움의 평균 블록 생성 시간인 15초로 설정하고 테스트를 10회 반복하여 무작위성을 완화했다.

표 2. 실험 결과

TP : True Positives(실제 값과 측정된 값이 모두 true인 경우)
FP : False Positives(실제 값은 false이지만 측정된 값은 true인 경우)
FN : False Negatives(실제값은 true이지만 측정된 값은 false인 경우)
Pre : Precision(정밀도)
Rec : Recall(재현율)
Acc : Accuracy(정확도)

RQ1(Bug Detection Capability)

RQ1은 ÐArcher가 버그를 얼마나 효과적으로 탐지할 수 있는지 확인한다. 위 표 2는 ÐArcher와 Baseline-1, Baseline-2의 실험 결과를 나타낸다. 트랜잭션 3,134개를 전송했을 때 369개의 type-1 버그가 탐지되었고, 1,862개의 type-2 버그가 탐지되었다. 그리고 16개의 type-1 버그가 탐지되었는데, 이는 FP값으로 실제 type-1버그가 발생하지 않았지만 type-1 버그로 탐지된 경우이다. 그리고 실제 버그가 발생했지만 ÐArcher에서 탐지하지 못한 FN값이 type-1에서 52개, type-2에서 264개가 탐지되었다. 실험에서 일부 잘못 측정된 데이터도 있었지만, 여전히 ÐArcher는 높은 정밀도(99.3%)와 재현율(87.6%) 그리고 높은 d정확도(89.4%)로 DApp에서 온체인 오프체인 동기화 버그를 효과적으로 감지할 수 있다.

RQ2(Efficacy of Our Oracles)

RQ2에서는 직접 설계한 2가지 오라클과 2가지 Baseline을 비교하여 직접 설계한 오라클이 얼마나 효과적인지 비교한다. Baseline-1은 ContractFuzzer, Baseline-2는 javascript에서 런타임 에러가 발생하면 버그를 탐지하여 보고한다. 표 2에서 Baseline-1을 확인해보면 FP에서 7개의 트랜잭션이 탐지되어 온체인-오프체인 동기화 버그를 탐지할 수 없다는 것을 확인할 수 있다. Baseline-2는 257개의 트랜잭션을 탐지했다. 하지만 Baseline-II의 전체 정밀도, 재현율, 정확도는 각각 56.9%, 10.1%, 20.7%로 ÐArcher보다 효율성이 떨어진다는 것을 확인할 수 있다. 따라서 본 논문에서 제안한 오라클은 온체인-오프체인 동기화 버그 감지 측면에서 기존 오라클보다 효율적이다.

RQ3 (Usefulness)

RQ3에서는 ÐArcher가 개발자들에게 얼마나 유용하게 사용할 수 있을지 설명한다. ÐArcher로 탐지한 버그 리포트를 각 DApp 개발자들에게 전달한 결과 15개의 버그 중 6개가 확인되었고 3개가 수정되었다고 하며, 개발자의 응답에 따르면 ÐArcher는 온체인 오프체인 동기화 버그를 감지하는 데 유용하다고 한다.

Conclusion

이 논문에서는 온체인-오프체인의 동기화 문제에 대해 정의하고 온체인-오프체인 동기화 버그를 탐지하기 위한 오라클과 ÐArcher 프레임워크를 설계하고 개발했다. 개발한 프레임워크로 실험을 진행한 결과 많은 DApp에서 온체인-오프체인 동기화 버그가 발생했고, 개발한 버그 탐지 프레임워크와 오라클은 온체인-오프체인 동기화 버그를 탐지할 수 있었다. 이 논문의 저자는 DApp을 개발하는 개발자들이 스마트 컨트랙트의 테스트와 검증에는 많은 시간을 쓰면서 정작 트랜잭션 생명주기를 고려하지 않는다고 지적한다. 트랜잭션 생명주기를 고려하지 않아 온체인과 오프체인의 상태가 달라질 경우 사용자가 의도하지 않은 결과를 초래하고, 수수료가 낭비될 수 있다. 따라서 DApp을 개발하는 개발자는 사용자에게 올바른 정보를 제공하기 위해 트랜잭션의 생명주기를 고려해서 오프체인의 상태를 업데이트해야 한다.

지금까지 개발된 많은 DApp들은 트랜잭션이 트랜잭션 풀에 담겼거나 실행만 되어도 트랜잭션 처리가 완료되었다고 사용자에게 알려주고, 트랜잭션이 취소된 후에는 어떠한 조치도 없었다. 오프체인에서 온체인의 상태를 계속 확인하기 어렵고, 완결성을 보장하는데 시간이 오래 걸리는 경우도 있기 때문에 반드시 트랜잭션이 완결된 상태가 될 때까지 기다리는 것도 정답은 아니다. 하지만 필자는 적어도 트랜잭션이 실행되었을 때 사용자에게 트랜잭션 처리가 완료되었다고 알려줄 필요가 있다고 생각한다. 블록에 담긴 트랜잭션은 체인이 변경되더라도 변경된 체인에 트랜잭션이 담겨있을 확률이 높기 때문에 실제로 트랜잭션이 완전히 취소될 확률은 적다고 생각하기 때문이다. 또한 트랜잭션의 완결성을 보장하지 않는 블록체인 위에서 DApp을 개발하는 경우 개발자는 언제 오프체인 상태를 업데이트할지, 트랜잭션이 취소된 경우에는 오프체인의 상태를 업데이트하고 사용자에게도 알려줄 수 있는 방법을 생각해볼 필요가 있다.

- CURG(Crypto United Research Group)는 2018년 5월 대학(원), 기업, 스타트업 등 다양한 분야의 열정적인 블록체인-er들이 모인 연합 연구 그룹입니다. CURG는 2018년 5월 출범된 이후, ‘Trendy, Thoughtful, and Transdisciplinary’ 한 자세로 한 주도 빠짐없이 블록체인 연구를 지속해오고 있습니다.

- 디사이퍼(DECIPHER)는 “건강한 블록체인 생태계 조성에 기여한다” 라는 미션 아래 블록체인에 대해 연구하고 이를 실용적으로 응용하는 서울대 블록체인 연구 학회입니다. 2018년 3월에 처음 조직 되어 현재까지 블록체인 기술을 다방면에서 연구하고 산업계에 응용하고 있는 100명 이상의 회원들을 배출해왔습니다. 다양한 팀별 연구활동과 프로젝트, 컨퍼런스 개최, 서울대학교 블록체인 강의 개설, 유수 기업들과의 산학협력과 파트너십 체결을 해오며 국내 최고의 블록체인 학회로 자리 잡았습니다.

커그와 디사이퍼는 향후 적극적인 협력을 통해 블록체인 필드에서의 강력한 시너지를 구축하고자 합니다.

--

--