본문으둜 κ±΄λ„ˆλ›°κΈ°

Hooks 개발

이번 μž₯μ—μ„œλŠ” Hooksλ₯Ό κ°œλ°œν•˜λŠ” 방법에 λŒ€ν•΄ μ„€λͺ…ν•©λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄, λ¨Όμ € Hooksλ₯Ό κ°œλ°œν•˜κΈ° μœ„ν•œ ν™˜κ²½μΈ hooks builderλ₯Ό μ†Œκ°œν•˜κ³ , κ·Έ ν™˜κ²½μ—μ„œ Hooksλ₯Ό κ°œλ°œν•˜λŠ” 방법을 μ„€λͺ…ν•©λ‹ˆλ‹€.

Hooks κ°œλ°œμ— ν•„μš”ν•œ μžλ£Œλ“€μ€ μ „λΆ€ 이 링크에 μžˆμŠ΅λ‹ˆλ‹€.

1. Hooks Builder​

1.1 Hooks Builderλž€?​

Hooks BuilderλŠ” μ›Ή λΈŒλΌμš°μ € μƒμ—μ„œ Hook을 개발, ν…ŒμŠ€νŠΈ, 디버그, 배포할 수 μžˆλŠ” 온라인 IDEμž…λ‹ˆλ‹€. νŠΉλ³„νžˆ μ„€μΉ˜ν•  ν•„μš” 없이 μ›Ήμ–΄μ…ˆλΈ”λ¦¬(WebAssembly) 기반으둜 λ™μž‘ν•˜λ©°, μ‚¬μš©μžκ°€ 직접 Hook을 μ²˜μŒλΆ€ν„° κ°œλ°œν•˜κ±°λ‚˜ 제곡된 μ˜ˆμ‹œλ₯Ό ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ£Όμš” νŠΉμ§•:

  • μ„€μΉ˜ μ—†μŒ: λ³„λ„μ˜ μ„€μΉ˜λ‚˜ μ„€μ • κ³Όμ • 없이 μ›Ή λΈŒλΌμš°μ €μ—μ„œ 직접 κ°œλ°œμ„ μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ›Ήμ–΄μ…ˆλΈ”λ¦¬ 기반: μ›Ήμ–΄μ…ˆλΈ”λ¦¬ κΈ°μˆ μ„ ν™œμš©ν•˜μ—¬ λΉ λ₯΄κ³  μ•ˆμ •μ μΈ 개발 ν™˜κ²½μ„ μ œκ³΅ν•©λ‹ˆλ‹€.
  • μ½”λ“œ νžŒνŒ… 및 λ¬Έμ„œ 톡합: μ½”λ“œ μž‘μ„± μ‹œ μžλ™μœΌλ‘œ νžŒνŠΈμ™€ λ¬Έμ„œλ₯Ό μ œκ³΅ν•˜μ—¬ μ‚¬μš©μžμ˜ 개발 νš¨μœ¨μ„±μ„ λ†’μž…λ‹ˆλ‹€.
  • Gist ν†΅ν•œ μ €μž₯ 및 곡유: κ°œλ°œν•œ Hook μ½”λ“œλ₯Ό Gistλ₯Ό 톡해 μ†μ‰½κ²Œ μ €μž₯ν•˜κ³  κ³΅μœ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • λΈŒλΌμš°μ € λ‚΄ ν…ŒμŠ€νŠΈ, 디버그 및 배포: Hooks Builderλ₯Ό μ‚¬μš©ν•˜λ©΄ μ›Ή λΈŒλΌμš°μ € μƒμ—μ„œ 직접 Hook의 ν…ŒμŠ€νŠΈ, 디버그, 배포 과정을 μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Hooks Builderλ₯Ό ν™œμš©ν•˜λ©΄, ν…ŒμŠ€νŠΈλ„·μ—μ„œμ˜ Hook 개발 ν”„λ‘œμ„ΈμŠ€κ°€ λ”μš± κ°„νŽΈν•˜κ³  효과적으둜 μ§„ν–‰λ©λ‹ˆλ‹€.

이 링크λ₯Ό μ΄μš©ν•˜λ©΄ hooks builderλ₯Ό μ΄μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

1.2 Hooks Builder μ‚¬μš©λ²•β€‹

  1. Hooks Builder 접속

    이 링크λ₯Ό 톡해 Hooks Builder에 μ ‘μ†ν•©λ‹ˆλ‹€.

  2. ν”„λ‘œμ νŠΈ 선택

    Hooks builderμ—μ„œ μ œκ³΅ν•˜λŠ” 예제 ν”„λ‘œμ νŠΈ 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•˜κ±°λ‚˜ μƒˆλ‘œμš΄ ν”„λ‘œμ νŠΈλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. μƒˆ ν”„λ‘œμ νŠΈ 생성 μ‹œμ—λ„ hookapiλ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ starter projectλ₯Ό μ„ νƒν•˜λŠ” 것을 μΆ”μ²œν•©λ‹ˆλ‹€.

    hooks-builder-1

  3. μ½”λ“œ μž‘μ„± 및 컴파일

    Develop νƒ­μ—μ„œ Hooks Builderμ—μ„œ μ œκ³΅ν•˜λŠ” μ½”λ“œ 힌트λ₯Ό μ°Έκ³ ν•˜μ—¬ μ½”λ“œλ₯Ό μž‘μ„±ν•©λ‹ˆλ‹€. μ½”λ“œ μž‘μ„±μ΄ μ™„λ£Œλ˜λ©΄, Compile λ²„νŠΌμ„ ν΄λ¦­ν•˜μ—¬ μ»΄νŒŒμΌμ„ μ§„ν–‰ν•©λ‹ˆλ‹€.

    hooks-builder-2

  4. 계정 생성 및 Hook Deploy

    Deploy νƒ­μ—μ„œ 계정을 μƒμ„±ν•˜κ±°λ‚˜ import ν•œ ν›„, 계정 μ˜†μ˜ Set Hook λ²„νŠΌμ„ ν΄λ¦­ν•˜μ—¬ 계정에 Hook을 deployν•©λ‹ˆλ‹€.

    hooks-builder-3

    hooks-builder-4

  5. ν…ŒμŠ€νŠΈ 및 디버깅

    Test νƒ­μ—μ„œ μ›ν•˜λŠ” νŠΈλžœμž­μ…˜μ„ Hook κ³„μ •μœΌλ‘œ 보내 ν…ŒμŠ€νŠΈλ₯Ό μ§„ν–‰ν•©λ‹ˆλ‹€. ν…ŒμŠ€νŠΈ κ³Όμ •μ—μ„œ λ°œμƒν•˜λŠ” 둜그λ₯Ό ν™•μΈν•˜μ—¬ 디버깅을 μ§„ν–‰ν•©λ‹ˆλ‹€.

    hooks-builder-5

2. Hook API​

2.1 Hook APIλž€?​

Hook APIλŠ” Hook κ°œλ°œμ— ν•„μš”ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” λΌμ΄λΈŒλŸ¬λ¦¬μž…λ‹ˆλ‹€. Hook APIλ₯Ό ν™œμš©ν•˜λ©΄, Hook 개발 κ³Όμ •μ—μ„œ ν•„μš”ν•œ λ‹€μ–‘ν•œ κΈ°λŠ₯을 κ°„νŽΈν•˜κ²Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. hookapiλŠ” builder의 예제 ν”„λ‘œμ νŠΈλ“€μ— μžˆμœΌλ―€λ‘œ ν•΄λ‹Ή νŒŒμΌλ“€μ„ ν”„λ‘œμ νŠΈ 디렉토리에 μœ„μΉ˜μ‹œν‚¨ ν›„, #include "hookapi.h"λ₯Ό 톡해 hookapiλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2.2 Hook API κ·œμΉ™ (Conventions)​

Hook APIλ₯Ό 효과적으둜 μ‚¬μš©ν•˜λ €λ©΄ λͺ‡ 가지 핡심 κ·œμΉ™μ„ μ΄ν•΄ν•˜κ³  따라야 ν•©λ‹ˆλ‹€. μ•„λž˜μ— 이 κ·œμΉ™λ“€μ„ κ°„λ‹¨ν•˜κ²Œ λ‚˜μ—΄ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

  1. 넀이밍 κ·œμΉ™

    λͺ¨λ“  Hook APIλŠ” νŠΉμ •ν•œ 넀이밍 κ·œμΉ™μ„ λ”°λ¦…λ‹ˆλ‹€. μ΄λŠ” API의 ν•¨μˆ˜ 이름을 톡해 κ·Έ κΈ°λŠ₯을 μ‰½κ²Œ νŒŒμ•…ν•  수 μžˆλ„λ‘ λ„μ™€μ€λ‹ˆλ‹€.

    ꡬ쑰: namespace*[noun #1]*[verb]\_[noun #2]

    • 첫 번째 λͺ…사가 λˆ„λ½λ˜λ©΄ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ™€ λ™μΌν•˜κ²Œ κ°„μ£Όλ©λ‹ˆλ‹€.
    • 동사가 λˆ„λ½λ˜λ©΄ 기본적으둜 get으둜 κ°„μ£Όλ©λ‹ˆλ‹€.

    μ˜ˆμ‹œ:

    • state()λŠ” hook의 μƒνƒœλ₯Ό κ°€μ Έμ˜¨λ‹€λŠ” μ˜λ―Έμž…λ‹ˆλ‹€.
    • state_set()λŠ” hook μƒνƒœλ₯Ό μ„€μ •ν•œλ‹€λŠ” μ˜λ―Έμž…λ‹ˆλ‹€.
    • state_foreign()λŠ” μ™ΈλΆ€ hook의 μƒνƒœλ₯Ό κ°€μ Έμ˜¨λ‹€λŠ” μ˜λ―Έμž…λ‹ˆλ‹€.
  2. λ©”λͺ¨λ¦¬ 관리

    각 HookλŠ” 독립적인 μŠ€νƒ ν”„λ ˆμž„ λ‚΄μ—μ„œ μ‹€ν–‰λ©λ‹ˆλ‹€. λ”°λΌμ„œ λͺ¨λ“  μž‘μ—… λ©”λͺ¨λ¦¬λŠ” 이 μŠ€νƒ ν”„λ ˆμž„ λ‚΄μ—μ„œ κ΄€λ¦¬λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. νž™κ³Ό 동적 λ©”λͺ¨λ¦¬ 할당을 μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

  3. 톡신 κ·œμΉ™

    Hook이 xrpld와 톡신할 λ•ŒλŠ” μ •μˆ˜ κ°’λ§Œ 전달할 수 μžˆμŠ΅λ‹ˆλ‹€. 이 μ •μˆ˜ 값은 λŒ€μ²΄λ‘œ Hook의 λ©”λͺ¨λ¦¬ λ‚΄ 포인터λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

  4. ν—ˆμš©λœ ν•¨μˆ˜

    Hook λ‚΄μ—μ„œλŠ” hook()와 cbak() 두 가지 ν•¨μˆ˜λ§Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ API λ¬Έμ„œλ₯Ό μ°Έμ‘°ν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€.

  5. λ§€κ°œλ³€μˆ˜ 전달

    Hook API ν•¨μˆ˜μ— μ „λ‹¬λ˜λŠ” λͺ¨λ“  λ§€κ°œλ³€μˆ˜λŠ” νŠΉμ • νƒ€μž…μ„ λ”°λ₯΄λ©°, νŠΉλ³„ν•œ μˆœμ„œλ‘œ λ°°μ—΄λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

    • ν—ˆμš©λ˜λŠ” 데이터 νƒ€μž…: uint32_t, int32_t, uint64_t, int64_t

      • λŒ€λΆ€λΆ„μ˜ 경우, 이듀은 Hook의 μŠ€νƒ ν”„λ ˆμž„ λ‚΄μ˜ ν¬μΈν„°λ‚˜ λ²„νΌμ˜ 길이λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
    • λ§€κ°œλ³€μˆ˜ μˆœμ„œ:

      1. μ“°κΈ° 포인터(μžˆμ„ 경우)
      2. μ“°κΈ° 길이(μžˆμ„ 경우)
      3. 읽기 포인터(μžˆμ„ 경우)
      4. 읽기 길이(μžˆμ„ 경우)
      5. νŠΉμ • ν•„λ“œλ‚˜ 기타 λ§€κ°œλ³€μˆ˜(μžˆμ„ 경우)
  6. λ°˜ν™˜ μ½”λ“œ

    λͺ¨λ“  Hook APIλŠ” signed integerλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. 이 λ°˜ν™˜ μ½”λ“œλŠ” ν•¨μˆ˜ 호좜의 성곡 λ˜λŠ” μ‹€νŒ¨, 그리고 λ‹€μ–‘ν•œ 였λ₯˜ 상황을 λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ μ‚¬μš©λ©λ‹ˆλ‹€.

2.3 Hook API ν•¨μˆ˜β€‹

Hook APIμ—λŠ” λ‹€μ–‘ν•œ ν•¨μˆ˜κ°€ μžˆμ§€λ§Œ, μ—¬κΈ°μ„œλŠ” κ·Έ 쀑 핡심적인 ν•¨μˆ˜μ— λŒ€ν•΄ κ°„λ‹¨νžˆ μ†Œκ°œν•˜κ³ μž ν•©λ‹ˆλ‹€. λͺ¨λ“  Hook API ν•¨μˆ˜μ— λŒ€ν•œ μƒμ„Έν•œ λ‚΄μš©μ€ 이 λ§ν¬μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

1. hook ν•¨μˆ˜β€‹

  • κ°œμš”: hook은 μ‚¬μš©μžκ°€ μ •μ˜ν•˜λŠ” μ£Όμš” ν•¨μˆ˜λ‘œ, xrpld에 μ˜ν•΄ ν˜ΈμΆœλ˜μ–΄ hook을 μ‹€ν–‰μ‹œν‚΅λ‹ˆλ‹€.

  • λ™μž‘ 방식:

    • hook은 μ›λž˜μ˜ νŠΈλžœμž­μ…˜μ„ μˆ˜λ½ν•˜κ±°λ‚˜ κ±°λΆ€ν•˜κΈ° μœ„ν•΄ accept λ˜λŠ” reject ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€.
    • ν•¨μˆ˜μ˜ 싀행이 끝날 λ•ŒκΉŒμ§€ μ–΄λ– ν•œ λ°˜ν™˜ 값도 μ—†λ‹€λ©΄, μ•”μ‹œμ μœΌλ‘œ accept둜 κ°„μ£Όλ©λ‹ˆλ‹€.
  • μ •μ˜:

int64_t hook (uint32_t reserved);
  • μ˜ˆμ‹œ:
int64_t hook(uint32_t reserved)
{
return 0;
}
  • λ§€κ°œλ³€μˆ˜:

    • 이름: reserved
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: ν–₯ν›„ μ‚¬μš©μ„ μœ„ν•΄ μ˜ˆμ•½λœ λ§€κ°œλ³€μˆ˜.
  • λ°˜ν™˜ μ½”λ“œ:

    • νƒ€μž…: int64_t
    • μ„€λͺ…: Hookμ—μ„œ λ°˜ν™˜ν•˜κ³ μž ν•˜λŠ” μž„μ˜μ˜ λ°˜ν™˜ μ½”λ“œμž…λ‹ˆλ‹€. 이 μ½”λ“œλŠ” μ›λž˜μ˜ νŠΈλžœμž­μ…˜ 메타데이터에 ν¬ν•¨λ©λ‹ˆλ‹€.

이 hook ν•¨μˆ˜λŠ” Hook 개발의 기본이 λ˜λŠ” μ€‘μš”ν•œ ν•¨μˆ˜μž…λ‹ˆλ‹€. κ°œλ°œμžλŠ” 이 ν•¨μˆ˜λ₯Ό 톡해 νŠΈλžœμž­μ…˜μ˜ λ™μž‘μ„ μ œμ–΄ν•˜κ³ , μ›ν•˜λŠ” λ‘œμ§μ— 따라 νŠΈλžœμž­μ…˜μ„ μˆ˜λ½ν•˜κ±°λ‚˜ κ±°λΆ€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2. cbak ν•¨μˆ˜β€‹

  • κ°œμš”: cbak은 μ‚¬μš©μžκ°€ μ •μ˜ν•˜λŠ” 콜백 ν•¨μˆ˜λ‘œ, 이전에 μ „μ†‘λœ νŠΈλžœμž­μ…˜μ˜ μƒνƒœμ— λŒ€ν•΄ hook에 μ•Œλ €μ£ΌκΈ° μœ„ν•΄ xrpld에 μ˜ν•΄ ν˜ΈμΆœλ©λ‹ˆλ‹€.

  • λ™μž‘ 방식:

    • cbak은 μƒνƒœ λ³€κ²½κ³Ό 좔가적인 emit ν˜ΈμΆœμ„ ν•  수 μžˆμ§€λ§Œ, 이미 μˆ˜ν–‰λœ νŠΈλžœμž­μ…˜μ„ λ‘€λ°±ν•˜λŠ” 것은 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€.
    • cbak이 싀행될 λ•Œ, 콜백이 κ΄€λ ¨λœ νŠΈλžœμž­μ…˜μ΄ 이제 μ›λž˜μ˜ νŠΈλžœμž­μ…˜μœΌλ‘œ κ°„μ£Όλ©λ‹ˆλ‹€.
  • μ •μ˜:

int64_t cbak (uint32_t what);
  • μ˜ˆμ‹œ:
int64_t cbak(uint32_t what)
{
return 0;
}
  • λ§€κ°œλ³€μˆ˜:

    • 이름: what
      • νƒ€μž…: uint32_t
      • μ„€λͺ…:
        • 값이 0이면: 이 콜백과 κ΄€λ ¨λœ μ „μ†‘λœ νŠΈλžœμž­μ…˜μ΄ μ„±κ³΅μ μœΌλ‘œ 원μž₯에 μˆ˜μš©λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
        • 값이 1이면: 콜백과 κ΄€λ ¨λœ μ „μ†‘λœ νŠΈλžœμž­μ…˜μ΄ 만료되기 전에 μ„±κ³΅μ μœΌλ‘œ 원μž₯에 μˆ˜μš©λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
  • λ°˜ν™˜ μ½”λ“œ:

    • νƒ€μž…: int64_t
    • μ„€λͺ…: Hookμ—μ„œ λ°˜ν™˜ν•˜κ³ μž ν•˜λŠ” μž„μ˜μ˜ λ°˜ν™˜ μ½”λ“œμž…λ‹ˆλ‹€. 이 μ½”λ“œλŠ” μ›λž˜μ˜ νŠΈλžœμž­μ…˜ 메타데이터에 ν¬ν•¨λ©λ‹ˆλ‹€.

cbak ν•¨μˆ˜λ₯Ό 톡해 κ°œλ°œμžλŠ” 이전에 μ „μ†‘λœ νŠΈλžœμž­μ…˜μ˜ μƒνƒœλ₯Ό νŒŒμ•…ν•˜κ³ , 그에 λ”°λ₯Έ 좔가적인 μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

3. emit ν•¨μˆ˜β€‹

  • κ°œμš”: emit은 hookμ—μ„œ μƒˆλ‘œμš΄ νŠΈλžœμž­μ…˜μ„ μ „μ†‘ν•˜κΈ° μœ„ν•œ ν•¨μˆ˜μž…λ‹ˆλ‹€.

  • λ™μž‘ 방식:

    • read_ptrλ‘œλΆ€ν„° νŠΈλžœμž­μ…˜μ„ μ½μŠ΅λ‹ˆλ‹€.
    • 전솑 κ·œμΉ™μ— 따라 νŠΈλžœμž­μ…˜μ˜ μœ νš¨μ„±μ„ κ²€μ¦ν•©λ‹ˆλ‹€.
    • μœ νš¨ν•œ 경우, νŠΈλžœμž­μ…˜μ„ ν•©μ˜μ— ν¬ν•¨μ‹œν‚΅λ‹ˆλ‹€.
    • write_ptr에 μ •κ·œν™”λœ νŠΈλžœμž­μ…˜ ν•΄μ‹œλ₯Ό μž‘μ„±ν•©λ‹ˆλ‹€.
  • μ •μ˜:

int64_t emit (
uint32_t write_ptr,
uint32_t write_len,
uint32_t read_ptr,
uint32_t read_len
);
  • μ˜ˆμ‹œ:
if (emit(tx, tx_len) < 0)
rollback("Failed to emit!", 15, 1);
  • λ§€κ°œλ³€μˆ˜:

    • 이름: write_ptr
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: νŠΈλžœμž­μ…˜ ν•΄μ‹œλ₯Ό μ“Έ λ²„νΌμ˜ 포인터
    • 이름: write_len
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: νŠΈλžœμž­μ…˜ ν•΄μ‹œλ₯Ό μ“Έ λ²„νΌμ˜ 크기 (32이어야 ν•©λ‹ˆλ‹€.)
    • 이름: read_ptr
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: 전솑할 νŠΈλžœμž­μ…˜μ˜ 포인터
    • 이름: read_len
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: νŠΈλžœμž­μ…˜μ˜ 길이
  • λ°˜ν™˜ μ½”λ“œ:

    • νƒ€μž…: int64_t
    • μ„€λͺ…: 성곡적인 경우, μž‘μ„±λœ νŠΈλžœμž­μ…˜ ν•΄μ‹œμ˜ λ°”μ΄νŠΈ 수(32)λ₯Ό λ°˜ν™˜ν•˜κ±°λ‚˜:
      • 음수인 경우, 였λ₯˜:
        • OUT_OF_BOUNDS: hook λ©”λͺ¨λ¦¬ 밖에 μ§€μ •λœ 포인터/길이
        • PREREQUISITE_NOT_MET: λ¨Όμ € emit_reserveλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•©λ‹ˆλ‹€.
        • TOO_MANY_EMITTED_TXN: 이전에 호좜된 emit_reserve μ‹œ μ•½μ†λœ 것보닀 μ „μ†‘λœ νŠΈλžœμž­μ…˜μ˜ μˆ˜κ°€ 더 λ§Žμ•„μ‘ŒμŠ΅λ‹ˆλ‹€.
        • EMISSION_FAILURE: 전솑 κ·œμΉ™μ— 따라 νŠΈλžœμž­μ…˜μ΄ 잘λͺ» κ΅¬μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

emit ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ κ°œλ°œμžλŠ” νŠΉμ • 쑰건 ν•˜μ—μ„œ μƒˆλ‘œμš΄ νŠΈλžœμž­μ…˜μ„ 전솑할 수 μžˆμŠ΅λ‹ˆλ‹€.

4. hook_param ν•¨μˆ˜β€‹

  • κ°œμš”: hook_param ν•¨μˆ˜λŠ” λͺ…λͺ…λœ hook λ§€κ°œλ³€μˆ˜μ˜ 값을 κ²€μƒ‰ν•©λ‹ˆλ‹€.

  • λ™μž‘ 방식:

    • read_ptr에 μ§€μ •λœ λͺ…λͺ…λœ λ§€κ°œλ³€μˆ˜μ˜ 값을 μ‘°νšŒν•©λ‹ˆλ‹€.
    • λ§€κ°œλ³€μˆ˜μ˜ 값을 write_ptr에 μž‘μ„±ν•©λ‹ˆλ‹€.
  • μ •μ˜:

int64_t hook_param (
uint32_t write_ptr,
uint32_t write_len,
uint32_t read_ptr,
uint32_t read_len
);
  • μ˜ˆμ‹œ:
uint8_t pname[] = {0xCAU, 0xFEU};
uint8_t pvalue[32];
int64_t value_len =
hook_param(pvalue, 32, pname, 2);
  • λ§€κ°œλ³€μˆ˜:

    • 이름: write_ptr
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: 좜λ ₯값을 μ €μž₯ν•˜κΈ° μœ„ν•œ μ μ ˆν•œ 크기의 버퍼에 λŒ€ν•œ 포인터. μ΅œμ†Œ 32 λ°”μ΄νŠΈμ—¬μ•Ό ν•©λ‹ˆλ‹€.
    • 이름: write_len
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: 좜λ ₯ λ²„νΌμ˜ 길이.
    • 이름: read_ptr
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: λ§€κ°œλ³€μˆ˜ 이름이 ν¬ν•¨λœ 버퍼에 λŒ€ν•œ 포인터.
    • 이름: read_len
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: λ§€κ°œλ³€μˆ˜ μ΄λ¦„μ˜ 길이.
  • λ°˜ν™˜ μ½”λ“œ:

    • νƒ€μž…: int64_t
    • μ„€λͺ…: μž‘μ„±λœ λ°”μ΄νŠΈμ˜ 수.
      • 음수인 경우, 였λ₯˜:
        • OUT_OF_BOUNDS: hook λ©”λͺ¨λ¦¬ 밖에 μ§€μ •λœ 포인터/길이.
        • DOESNT_EXIST: μ§€μ •λœ λ§€κ°œλ³€μˆ˜κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šκ±°λ‚˜ nullμž…λ‹ˆλ‹€.
        • TOO_SMALL: λ§€κ°œλ³€μˆ˜ 이름은 null일 수 μ—†μŠ΅λ‹ˆλ‹€.
        • TOO_BIG: λ§€κ°œλ³€μˆ˜ 이름이 32 λ°”μ΄νŠΈλ³΄λ‹€ ν½λ‹ˆλ‹€.

hook_param ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ hook에 μ„€μ •λœ νŠΉμ • λ§€κ°œλ³€μˆ˜μ˜ 값을 μ‰½κ²Œ 검색할 수 μžˆμŠ΅λ‹ˆλ‹€.

5. state_set ν•¨μˆ˜β€‹

  • κ°œμš”: state_set ν•¨μˆ˜λŠ” 주어진 킀와 값에 λŒ€ν•œ Hook μƒνƒœλ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.

  • λ™μž‘ 방식:

    • kread_ptrμ—μ„œ 32 λ°”μ΄νŠΈ Hook μƒνƒœ ν‚€λ₯Ό μ½μŠ΅λ‹ˆλ‹€.
    • read_ptrμ—μ„œ μž„μ˜μ˜ μ–‘μ˜ 데이터(κ°’)λ₯Ό μ½μŠ΅λ‹ˆλ‹€.
    • κ·Έ 값을 μ‚¬μš©ν•˜μ—¬ Hook μƒνƒœ ν‚€λ₯Ό μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€.
  • μ •μ˜:

int64_t state_set (
uint32_t read_ptr,
uint32_t read_len,
uint32_t kread_ptr,
uint32_t kread_len
);
  • μ˜ˆμ‹œ:
#define SBUF(str) (uint32_t)(str), sizeof(str)
if (state_set(SBUF(vault), SBUF(vault_key)) < 0)
rollback(SBUF("Error: could not set state!"), 1);
  • λ§€κ°œλ³€μˆ˜:

    • 이름: read_ptr
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: Hook μƒνƒœμ— μž‘μ„±ν•  데이터(κ°’)에 λŒ€ν•œ ν¬μΈν„°μž…λ‹ˆλ‹€. 0(null)인 경우 ν•΄λ‹Ή ν‚€μ˜ 데이터λ₯Ό μ‚­μ œν•©λ‹ˆλ‹€. null일 수 μžˆμŠ΅λ‹ˆλ‹€.
    • 이름: read_len
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: λ°μ΄ν„°μ˜ 길이. 0(null)인 경우 ν•΄λ‹Ή ν‚€μ˜ 데이터λ₯Ό μ‚­μ œν•©λ‹ˆλ‹€. null일 수 μžˆμŠ΅λ‹ˆλ‹€.
    • 이름: kread_ptr
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: 값을 μ €μž₯ν•  Hook μƒνƒœ 킀에 λŒ€ν•œ 포인터.
    • 이름: kread_len
      • νƒ€μž…: uint32_t
      • μ„€λͺ…: ν‚€μ˜ 길이. 항상 32μ—¬μ•Ό ν•©λ‹ˆλ‹€.
  • 주의 사항:

    • Xrpl은 λ‚΄λΆ€μ μœΌλ‘œ μ΅œλŒ€ hook 데이터 크기λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€. μž‘μ„± μ‹œμ κ³Ό 곡개 ν…ŒμŠ€νŠΈλ„·μ˜ 경우 μ΄λŠ” 128 λ°”μ΄νŠΈλ‘œ ν•˜λ“œμ½”λ”© λ˜μ–΄ μžˆμ§€λ§Œ, λ―Έλž˜μ—λŠ” κ²€μ¦μžκ°€ νˆ¬ν‘œν•  수 μžˆλŠ” μˆ«μžκ°€ 될 κ²ƒμž…λ‹ˆλ‹€.
  • λ°˜ν™˜ μ½”λ“œ:

    • νƒ€μž…: int64_t
    • μ„€λͺ…: Hook μƒνƒœμ— μž‘μ„±λœ λ°”μ΄νŠΈ 수(λ°μ΄ν„°μ˜ 길이).
      • 음수인 경우, 였λ₯˜:
        • OUT_OF_BOUNDS: hook λ©”λͺ¨λ¦¬ 밖에 μ§€μ •λœ 포인터/길이.
        • TOO_BIG: kread_len이 32보닀 ν¬κ±°λ‚˜ read_len이 μ΅œλŒ€ hook 데이터 크기보닀 큼.
        • TOO_SMALL: kread_len이 0.

state_set ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ Hook μƒνƒœμ˜ νŠΉμ • 킀에 값을 μ„€μ •ν•˜κ±°λ‚˜ μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

6. otxn_field ν•¨μˆ˜β€‹

  • κ°œμš”: otxn_field ν•¨μˆ˜λŠ” μ›λž˜μ˜ νŠΈλžœμž­μ…˜μ—μ„œ μ§€μ •λœ sf ν•„λ“œλ₯Ό μ°Ύμ•„ 좜λ ₯ 버퍼에 κ·Έ ν•„λ“œμ˜ μ§λ ¬ν™”λœ 버전을 μž‘μ„±ν•©λ‹ˆλ‹€.

  • λ™μž‘ 방식:

    • μ›λž˜ νŠΈλžœμž­μ…˜μ—μ„œ μ§€μ •λœ sf ν•„λ“œλ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€.
    • 좜λ ₯ 버퍼에 ν•΄λ‹Ή ν•„λ“œμ˜ μ§λ ¬ν™”λœ 버전을 μž‘μ„±ν•©λ‹ˆλ‹€.
  • μ •μ˜:

int64_t otxn_field (
uint32_t write_ptr,
uint32_t write_len,
uint32_t field_id
);
  • μ˜ˆμ‹œ:
int64_t account_field_len =
otxn_field(account_field, 20, sfAccount);
  • λ§€κ°œλ³€μˆ˜:

    • 이름: write_ptr

      • νƒ€μž…: uint32_t
      • μ„€λͺ…: 좜λ ₯을 μ €μž₯ν•˜κΈ° μœ„ν•œ μ μ ˆν•œ 크기의 버퍼에 λŒ€ν•œ 포인터.
    • 이름: write_len

      • νƒ€μž…: uint32_t
      • μ„€λͺ…: 좜λ ₯ λ²„νΌμ˜ 길이.
    • 이름: field_id

      • νƒ€μž…: uint32_t

      • μ„€λͺ…: μ°Ύκ³  μžˆλŠ” ν•„λ“œμ˜ sf μ½”λ“œ.

        예λ₯Ό λ“€λ©΄, sfEmitNonceλŠ” μœ ν˜•μ΄ 5이고 ν•„λ“œκ°€ 11μ΄λ―€λ‘œ κ·Έ 값은 0x050BUμž…λ‹ˆλ‹€.

  • μ£Όμš” 사항:

    • 좜λ ₯ λ²„νΌμ—λŠ” ν•„λ“œ μ½”λ“œκ°€ μž‘μ„±λ˜μ§€ μ•ŠμœΌλ©°, ν•„λ“œμ˜ νŽ˜μ΄λ‘œλ“œλ§Œ μž‘μ„±λ©λ‹ˆλ‹€.
    • Hooks Public Testnet의 μž‘μ„± μ‹œμ μ—μ„œ, sfAccount와 같은 STI_ACCOUNT ν•„λ“œλŠ” μ„ ν–‰ λ³€μˆ˜ 길이 λ°”μ΄νŠΈ 없이 λ°˜ν™˜λ©λ‹ˆλ‹€.
  • λ°˜ν™˜ μ½”λ“œ:

    • νƒ€μž…: int64_t
    • μ„€λͺ…: μž‘μ„±λœ λ°”μ΄νŠΈ 수.
      • 음수인 경우, 였λ₯˜:
        • OUT_OF_BOUNDS: hook λ©”λͺ¨λ¦¬ 밖에 μ§€μ •λœ 포인터/길이.
        • TOO_SMALL: μ§λ ¬ν™”λœ ν•„λ“œλ₯Ό μ €μž₯ν•˜κΈ°μ— 좜λ ₯ 버퍼가 μΆ©λΆ„νžˆ 크지 μ•ŠμŒ.
        • INVALID_FIELD: sf field_idκ°€ μœ νš¨ν•˜μ§€ μ•ŠμŒ.
        • DOESNT_EXIST: μ›λž˜ νŠΈλžœμž­μ…˜μ—μ„œ ν•΄λ‹Ή ν•„λ“œλ₯Ό 찾을 수 μ—†μŒ.

otxn_field ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ›λž˜μ˜ νŠΈλžœμž­μ…˜μ—μ„œ νŠΉμ • ν•„λ“œλ₯Ό κ²€μƒ‰ν•˜κ³  κ·Έ ν•„λ“œμ˜ μ§λ ¬ν™”λœ 버전을 κ°€μ Έμ˜¬ 수 μžˆμŠ΅λ‹ˆλ‹€.