Hooks 소개
Hooks 소개
"Hooks"는 XRP Ledger에 스마트 컨트랙트 기능을 추가하는 새로운 메커니즘입니다. XRP Ledger는 그동안 빠른 속도, 높은 트랜잭션 처리 능력 및 저렴한 수수료로 널리 알려져 왔습니다. 기존에도 다중 서명, 에스크로, 결제 채널 및 탈중앙화 거래소(DEX)와 같은 고급 트랜잭션 유형을 지원함으로써, XRP Ledger는 기업 및 개발자들에게 많은 기능을 제공해 왔습니다. 그러나 개발자와 기업들의 다양한 요구를 만족시키기 위한 추가적인 유연성이 필요하다는 인식이 커지면서 Hooks라는 혁신적인 기능이 도입되었습니다.
1. Hooks의 기본 이해
1.1. Hooks의 정의 및 핵심 개념
Hooks는 XRP Ledger에 스마트 컨트랙트 기능을 추가해주는 요소로서, 트랜잭션의 행동 및 흐름에 영향을 미치는 사용자 정의 코드를 제공합니다. Hooks는 XRP Ledger 계정에 정의되는 작고 효율적인 코드 조각으로, XRP Ledger 트랜잭션 전후에 실행될 로직을 제공합니다. 현재 많은 비즈니스 로직이 오프체인에서 운영되고 있지만, Hooks의 도입으로 XRP Ledger 상에서 더 효율적이며 높은 신뢰성을 가진 비즈니스 로직 구현이 가능해졌습니다.
예를 들어, 간단한 Hooks는 "10 XRP 미만의 결제 거부"나 "모든 나가는 결제에 대해 내 저축 계좌에 10% 보내기"와 같은 로직을 수행할 수 있습니다. 더욱 고급 기능을 위해서는, Hooks를 사용하여 작은 데이터 객체를 저장하고 이를 효율적인 로직 실행에 활용할 수도 있습니다. 고급 기능들을 사용하면 다른 체인의 여러 dApp들 같이 복잡한 로직을 구현할 수 있습니다.
중요한 점은, Hooks는 튜링 완전성(Turing-Completeness)을 목적으로 하지 않습니다. 튜링 완전성은 스마트 컨트랙트의 중요한 특성으로 여겨지는 반면, 실제로는 스마트 컨트랙트에 적절하지 않을 수 있습니다. 정지 문제(Halting Problem)는 임의의 프로그램이 튜링 완전한 시스템에서 영원히 실행될지 아니면 중지될지를 예측하는 것이 수학적으로 불가능하다는 것을 설명합니다. 이는 우리가 스마트 컨트랙트의 실행 완료 시점을 미리 결정할 수 있어야 하기 때문에 바람직하지 않습니다.
현재 Hooks는 공개 테스트넷에서 실행 중입니다. 이는 개발자들이 테스트하고, 코드를 작성하며, 시험하고, 문제를 찾아낼 수 있는 기회를 제공함으로써, 미래에 Hooks를 XRP Ledger 라이브넷에 안정적으로 도입할 수 있도록 돕고 있습니다.
1.2. Hooks의 주요 기능
트랜잭션 제어:
Hooks는 XRP Ledger 트랜잭션의 동작을 제어할 수 있게 해줍니다. 예를 들어, 특정 조건을 만족하는 경우 트랜잭션을 거부하거나 수정할 수 있습니다.
조건부 로직 실행:
Hooks를 사용하면, 특정 조건에 따라 다른 로직을 실행할 수 있습니다. 예를 들면, 들어오는 결제의 금액이 특정 값 이하일 경우 거부하는 로직을 수행할 수 있습니다.
데이터 저장 및 관리:
Hooks는 XRP Ledger 상에서 간단한 데이터 객체를 저장하고 사용할 수 있게 해줍니다. 이를 통해, 예를 들어, 특정 목록에 있는 계정에서의 입금을 거부하는 등의 로직을 구현할 수 있습니다.
사용자 정의 로직 적용:
Hooks를 사용하면, 개발자는 XRP Ledger 트랜잭션에 대한 사용자 정의 로직을 적용할 수 있습니다. 이를 통해, 예를 들면, 모든 나가는 결제에 대해 일정 비율을 저축 계좌로 자동 전송하는 등의 기능을 구현할 수 있습니다.
튜링 완전성을 배제한 설계:
Hooks는 의도적으로 튜링 완전하지 않게 설계되었습니다. 이는 트랜잭션의 예측 가능성과 안정성을 보장하며, 계산 비용을 최소화하기 위한 것입니다.
트랜잭션 수수료 관리:
Hooks를 사용하여 트랜잭션 수수료를 조절하거나, 특정 조건에서의 추가 수수료 부과 등의 로직을 구현할 수 있습니다.
1.3. Hooks 용어 설명
Hook
맥락에 따라 여러 가지를 나타낼 수 있습니다: 1. SetHook 트랜잭션 유형으로 XRP Ledger에 업로드 가능한 웹어셈블리 이진 파일(WebAssembly Binary File). 2. XRP Ledger 계정에 이미 업로드 및 설정 또는 구성된 웹어셈블리 이진 파일. 3. 그러한 이진 파일의 소스 코드.
Originating Transaction (발생 트랜잭션)
Hook이 작동하게 만든 트랜잭션. Hook이 설정된 계정으로 보내거나 그 계정에서 보낸 트랜잭션일 수 있습니다.
Originating Account (발생 계정)
Originating 트랜잭션을 보낸 계정입니다.
Hook Account (Hook 계정)
현재 실행 중인 Hook이 있는 계정입니다. 이 계정은 Hook을 소유하며, Hook을 생성한 SetHook 트랜잭션을 수행한 계정이며, 현재 실행 중인 Hook의 Hook 상태가 속한 계정입니다.
Installer (설치 계정)
현재 SetHook 트랜잭션을 사용하여 Hook를 설치하는 계정입니다.
Emitted Transaction (발행된 트랜잭션)
Hook의 실행 중에 Hook에 의해 생성된 새로운 트랜잭션으로, Originating 트랜잭션은 아닙니다. 주로 Originating 계정에 자금을 돌려 보내는 데 사용됩니다. 참조: Emitted Transactions.
State (상태)
계정별로 32 바이트 키에 임의의 데이터를 매핑하는 key-value 맵입니다. 계정에 존재하는 모든 Hook은 동일한 Hook 상태에 액세스하고 수정할 수 있습니다. Hook 상태는 발생 계정이 아닌 Hook 계정에 존재합니다. 참조: State Management.
SetHook (Hook 설정)
Hook 수정으로 도입된 새로운 트랜잭션 유형으로, XRP Ledger 계정에 Hook를 설정합니다. 참조: SetHook Transaction.
Guards
Hook에 루프를 작성할 때 사용해야하는 특별한 제어 메커니즘입니다. 참조: Loops and Guards.
Grants (권한 부여)
Hook 설치자가 다른 계정 또는 특정 Hook에게 (어디에 설치되었는지와 관계없이) 설치자의 계정에서 Hook 상태를 수정할 수 있는 특별한 권한을 부여할 수 있습니다.
Namespace
하나의 state 키 집합을 다른 state 키 집합과 구별하는 고유한 32 바이트 코드입니다. 이름 공간이 다른 경우 두 개의 다른 Hook에서 동일한 state 키를 사용하여 서로 간섭하지 않을 수 있습니다.
Parameters (매개변수)
Hook이 설치되는 시점에 선택적으로 설정할 수 있는 매개변수입니다.
Reference Counting (참조 카운팅)
ledger에 소유되지 않은 객체는 참조 카운팅될 수 있으며, 참조 (사용) 한 마지막 계정이 참조를 제거하면 삭제됩니다.
XFL or Floating Point (부동 소수점)
환율 계산과 같은 Hook에서 고정밀 수학을 수행하는 방법입니다. 참조: XFL.
Serialized Objects (STO) (직렬화된 객체)
xrpld가 ledger 객체를 전송하고 저장하는 방법입니다. 참조: Serialized Objects.
Slots and Keylets
Slot은 ledger 객체를 포함할 수 있으며 Keylet은 해당 객체를 식별합니다. 참조: Slots and Keylets.
Trace
Hook에서 xrpld 출력에 로그 줄을 인쇄하는 방법입니다. 참조: Debugging Hooks.
2. Hooks 예시 시나리오
추가 로직을 실행하는 수신 Hook
들어오는 트랜잭션을 차단하는 수신 Hook
나가는 트랜잭션을 차단하는 발신 Hook
기관 계정을 제어하는 Hook
3. Hooks의 작동 메커니즘
3.1. Hook의 Life Cycle (생애 주기)
Hook의 생애 주기는 크게 다음의 3가지 단계로 구분됩니다.
Creation (생성)
Hook은
SetHook
트랜잭션 유형을 통해 XRP Ledger에 업로드되는 WebAssembly 바이너리로 생성됩니다. 이 단계에서는 Hook의 로직이 XRP Ledger 계정에 정의되며, 그 계정에 연결된 특정 트랜잭션에 대한 반응이나 행동을 설정합니다. Hook을 생성할 때에는 해당 Hook의 기능, 동작 조건, 그리고 필요한 경우 저장될 데이터 객체의 초기 상태 등이 정의됩니다.Execution (실행)
Hook의 실행은 Originating Transaction (발생 트랜잭션)에 의해 트리거됩니다. 트랜잭션이 Hook이 설정된 XRP Ledger 계정으로 전송되거나 해당 계정에서 발송될 때, 해당 Hook의 로직이 실행됩니다. 이때, Hook은 트랜잭션의 행동 및 흐름에 영향을 줄 수 있으며, 간단한 조건부 로직부터 복잡한 비즈니스 로직까지 다양한 동작을 수행할 수 있습니다.
Termination (종료)
Hook의 종료는 Hook의 로직이 모두 실행된 후, 또는 특정 조건 하에 발생합니다. 예를 들어, 특정 계정에서 Hook이 제거되거나, Hook의 실행 중 오류가 발생할 경우 Hook의 실행이 종료될 수 있습니다. 또한, XRP Ledger의 합의 프로토콜에 의해 Hook의 실행이 중단되는 경우도 있습니다. Hook이 종료되면, 해당 Hook과 관련된 모든 데이터 객체나 상태 변경이 XRP Ledger에 기록되며, 해당 Hook은 더 이상 트랜잭션에 반응하거나 행동을 수행하지 않습니다.
3.2. Hook Fees (Hook 수수료)
XRP Ledger 상에서의 Hook 실행은 ledger의 스팸 방지 및 과도한 validator 자원 사용을 방지하기 위해 최대 Hook 실행 시간을 기반으로 수수료가 부과됩니다. 예방하는 것은 ledger의 안정성과 사용성에 있어 매우 중요하며, 이는 ledger 상에 기본 토큰 (XRP)을 갖는 이유 중 하나입니다.
Hook 내의 guard를 분석함으로써 Hook의 가능한 최장 실행 시간을 사전에 계산할 수 있습니다. Hook을 실행하는 데 필요한 수수료는 항상 호출자(즉, Hook을 활성화하는 트랜잭션)에 의해 지불되며 항상 Hook의 최대 계산 실행 시간에 비례합니다. 추가로, validator들은 전역 최대 Hook 실행 시간에 대해 투표할 수 있습니다: 계산된 최대 실행 시간이 이 값을 초과하는 Hook은 SetHook 작업 중에 거부되므로 계정에서 Hook이 활성화되지 않게 됩니다. 참고로, 여기서 언급하는 실행 시간은 천분의 일초에서 백만분의 일초의 범위로 측정됩니다.
3.3. Determinism (결정론성)
Hooks는 오직 ledger 상의 데이터만 읽고 영향을 줄 수 있으므로, 모든 validator에서 동일한 트랜잭션에 대해 동시에 실행된 Hook의 출력은 항상 동일한 결과를 생성해야 합니다. 이를 통해 합의를 도달할 수 있습니다.
보안 및 런타임 이슈를 해결했더라도 결정론성 없이는 이 모든 것이 무용지물입니다. 간단히 말해서, validator들이 계정에서 Hook을 실행할 때 동일한 Hook 코드, 동일한 계정, 동일한 입력을 사용하여 동일한 출력을 생성하고 동시에 이를 실행해야 합니다. 그렇지 않으면 validator들은 결과에 동의하지 않게 되며, 네트워크가 중단될 수 있습니다.
이를 위해 Hook은 예측 가능해야 하며 무작위적인 요소를 포함해서는 안 됩니다. 예를 들어, Hook이 (실제) 난수 생성기나 현재 시간과 같은 타임스탬프를 액세스하게 되면, 검증기 간에 일관된 실행 결과를 보장할 수 없습니다. 왜냐하면 각 검증기가 다른 난수 또는 타임스탬프 값을 받을 수 있기 때문입니다. 따라서 xrpld(즉, XRP Ledger의 노드 소프트웨어)는 Hook이 이러한 비결정론적 정보에 액세스 할 수 없도록 설계되었습니다. 이는 합의를 방해할 수 있는 요소를 제거하여 네트워크의 안정성을 보장하기 위한 조치입니다.
때로는 Hook이 발생시킨 트랜잭션 또는 다른 Hook의 실행 결과를 고유하게 식별할 필요가 있습니다. 그렇기 때문에 결정론적 방식으로 생성된 고유한 값을, 즉 'nonce'를 사용합니다. 이 nonce는 예측 불가능한 값이 아니라, 특정 규칙에 따라 항상 동일한 결과를 반환하는 결정론적 방식으로 생성됩니다. Hook API는 이러한 nonce 값을 생성하기 위한 함수, 즉 nonce() 함수를 제공합니다. 이 함수는 마지막으로 완료된 ledger의 상태와 Hook이 연결된 계정 정보를 기반으로 nonce 값을 생성합니다. 이렇게 생성된 nonce 값은 Hook의 트랜잭션 또는 실행 결과를 고유하게 식별하는 데 사용됩니다. nonce() 함수는 연속적으로 여러 번 호출될 수 있으며, 각 호출마다 유사 난수 생성기(PRNG)가 업데이트되어 다음 번 nonce 값이 준비됩니다.
4. Hooks의 기술 스택
Hooks는 세 가지의 기술 스택 위에서 동작합니다.
4.1. Rippled (xrpld)
Rippled(xrpld)는 XRP Ledger의 핵심 노드 소프트웨어입니다. Rippled는 XRP Ledger의 합의 프로토콜을 구현하고, ledger의 상태를 유지하며, ledger의 상태를 변경하는 트랜잭션을 처리합니다. Rippled는 C++로 작성되었습니다. Hooks 수정안은 rippled 소스 코드의 수정으로 C++로 작성되었습니다.
4.2. Hook 런타임 (SSVM)
Hooks는 런타임 엔진으로 WASM(웹어셈블리) 런타임 엔진인 SSVM(Second State Virtual Machine)을 사용합니다. SSVM은 다음과 같은 주요 특징과 기능을 제공합니다.
프로그래밍 언어의 독립성: SSVM을 통해 WASM으로 컴파일되는 다양한 프로그래밍 언어로 작성된 스마트 컨트랙트를 실행할 수 있습니다. 이렇게 함으로써, 개발자들은 자신이 선호하는 언어를 사용하여 컨트랙트를 작성할 수 있게 됩니다.
격리 및 보안: SSVM은 각 스마트 컨트랙트를 격리된 환경에서 안전하게 실행합니다. 이는 잘못된 동작이나 보안 취약점이 전체 네트워크에 해를 끼치는 것을 방지합니다.
계산 비용의 정량화: 블록체인 상에서의 작업은 리소스를 소모하며, SSVM은 이러한 리소스 사용을 정량화하고 해당 비용을 측정합니다.
결정적 실행: SSVM 덕분에 스마트 컨트랙트의 실행은 항상 일정하며, 모든 노드에서 동일한 결과를 보장합니다.
호환성 및 업그레이드 관리: 블록체인 기술이 발전함에 따라, 스마트 컨트랙트의 호환성은 중요한 이슈가 됩니다. SSVM은 이러한 호환성 문제를 해결하며 필요한 경우 업그레이드를 지원합니다.
표준화: SSVM은 스마트 컨트랙트 실행에 관한 통합된 표준과 규약을 제공합니다. 따라서 개발자들은 이 표준에 따라 안정적으로 스마트 컨트랙트를 개발하고 배포할 수 있습니다.
4.3. Rippled와 Hook 런타임의 소통 과정
Hook의 런타임과 rippled 노드가 소통하는 과정을 더 자세히 살펴보면 다음과 같습니다.
트랜잭션 수신: rippled 노드는 클라이언트로부터 스마트 컨트랙트 트랜잭션을 수신합니다.
Wasm 실행: 수신된 트랜잭션이 Hook 런타임에서 실행되어야 하는 특정 기능을 요청하면, rippled는 해당 트랜잭션을 Hook 런타임에 전달합니다. 여기서 Hook 런타임은 Wasm 바이트코드를 실행합니다.
호스트 함수: Hook 런타임은 특정 핵심 기능에 대한 액세스를 필요로 할 때 "호스트 함수"를 통해 rippled와 통신합니다. 예를 들어, 스마트 컨트랙트가 계정의 XRP 잔액을 조회하려고 할 때, Hook 런타임은 rippled의 호스트 함수를 호출하여 이 정보를 요청하게 됩니다.
응답 반환: 스마트 컨트랙트 실행이 완료되면, Hook 런타임은 결과를 rippled에 반환합니다. rippled는 이 결과를 처리하고, 필요한 경우 Ledger 상태를 업데이트하며, 실행 결과를 클라이언트나 다른 노드에 전송합니다.
4.4. Hook 언어
Hook은 WASM 바이트코드로 컴파일 될 수 있는 어떤 언어든 사용할 수 있습니다. 하지만 공식적으로 지원되는 언어는 C와 Hookscript(AssemblyScript의 변형)입니다. Hook은 WASM 바이트코드로 컴파일되어 XRP Ledger에 업로드되며, 이후에는 Hook의 로직이 Hook 런타임(SSVM)에서 실행됩니다.
5. Hooks의 보안 아키텍쳐
Hooks는 XRP Ledger의 Layer 1에서 트랜잭션의 논리적 흐름과 실행을 제어하는 웹 어셈블리 모듈입니다. 그러므로, 그들의 보안 아키텍처는 매우 중요합니다. 여기서는 해당 아키텍쳐의 주요 요소에 대해 알아보겠습니다.
5.1. 웹 어셈블리의 안전성
웹 어셈블리는 특정한 바이트 코드 형식으로 구성되어 있어, 이를 해석할 수 있는 것은 웹 어셈블리 표준에 따라 행동하는 가상 기계뿐입니다. 이러한 구조는 웹 어셈블리가 원시 하드웨어 명령어를 포함하지 않게 합니다, 따라서 공격 벡터가 줄어듭니다.
5.2. xrpld의 역할
xrpld는 웹 어셈블리 런타임 환경의 역할을 하면서 운영 체제처럼 동작합니다. 웹 어셈블리 바이너리(hook)는 xrpld 내에서 사용자 공간 애플리케이션처럼 작동합니다. 이 hook은 xrpld에 의해 샌드박스화되며, 오직 xrpld가 명시적으로 노출한 함수에만 호출을 할 수 있습니다.
5.3. 제한된 Hook 작업
Hook는 다음과 같은 제한 사항이 있습니다:
외부 또는 내부 프로세스, 서비스, 엔드포인트로의 호출은 할 수 없습니다. 오직 Hook API만 호출 가능합니다.
시스템의 일부를 수정하거나 읽을 수 없습니다. 오직 자체 정의된 및 사전 할당된 메모리만 조작 가능합니다.
메모리는 검증자 투표에 의해 64kib로 제한됩니다.
이러한 제한 사항은 Ledger의 안정성과 보안을 위해 필요합니다. 특히, 이러한 제한들은 각 Hook이 Ledger의 전반적인 운영에 부정적인 영향을 주지 않도록 보장합니다.
5.4. 메모리 관리 및 보안
Hook이 요청을 할 때, xrpld가 읽고 쓸 수 있는 자체 메모리 공간 내의 포인터를 제공합니다. 잘못된 포인터를 제공하면 Hook 자체의 메모리만 손상시킬 수 있고 주변 시스템에는 영향을 주지 않습니다. 이것은 시스템의 더 넓은 부분에 손상을 주는 것을 방지하는 중요한 보안 조치입니다.
Last updated