Skip to content

prepare ​

Summary. Take a partially-specified transaction template and fill in the fixed fields an emitted transaction requires — account, sequence, signing key, fee, ledger-sequence window, and sfEmitDetails — returning a completed blob ready for emit. Requires the HooksUpdate2 amendment.

Signature.

c
int64_t prepare(uint32_t write_ptr, uint32_t write_len,
                uint32_t read_ptr, uint32_t read_len);

Amendment gate. Registered with featureHooksUpdate2; on a network where that amendment is not enabled, the import is unavailable.

Parameters.

NameTypeDescription
write_ptruint32_tDestination buffer for the completed transaction.
write_lenuint32_tDestination buffer length.
read_ptruint32_tPointer to the template transaction (serialized).
read_lenuint32_tLength of the template.

Return value. Returns the length of the completed transaction written to write_ptr on success. Errors: OUT_OF_BOUNDS (-1) for a bad buffer; PREREQUISITE_NOT_MET (-9) if etxn_reserve was not called; INVALID_ARGUMENT (-7) if the template cannot be parsed or the completed transaction fails to serialize / price; INTERNAL_ERROR (-2) if the emit-details object cannot be built.

Fields filled (verified in HookAPI::prepare).

  • sfFee — computed via etxn_fee_base and written last.
  • sfSigningPubKey — forced to all-zero.
  • sfSequence — forced to 0.
  • sfAccount — set to the hook account.
  • sfFirstLedgerSequence — set to current seq + 1 if absent.
  • sfLastLedgerSequence — set to current seq + 5 if absent.
  • sfEmitDetails — inserted via etxn_details if absent.

Common failure patterns.

  • Calling it before etxn_reserve → PREREQUISITE_NOT_MET.
  • A template that is not a valid serialized transaction → INVALID_ARGUMENT.

Caveats / notes.

  • prepare replaces the manual "build the fixed fields by hand" work the ENCODE_* macros do in the older test hooks; you still supply the transaction-specific fields (type, amount, destination, etc.) in the template.
  • Fields you do provide in the template (for example an explicit sfLastLedgerSequence) are respected — prepare only fills the ledger-sequence and emit-details fields when they are absent, but always overrides sfAccount, sfSequence, sfSigningPubKey, and sfFee.
  • The template may contain 0x99 NOP bytes (see NOP Bytes (0x99)); the returned blob is re-serialized from the parsed fields and never contains them, so prepare also serves to turn a NOP-padded template into a clean blob the sto_* APIs can read.

Minimal example.

c
uint8_t out[512];
int64_t n = prepare((uint32_t)out, sizeof(out), (uint32_t)template, template_len);
if (n < 0)
    rollback(SBUF("prepare failed"), n);

Practical example.

c
int64_t hook(uint32_t r)
{
    _g(1, 1);
    etxn_reserve(1);

    // prepare validates its buffers just like emit
    ASSERT(prepare(1000000, 32, 0, 32) == OUT_OF_BOUNDS);

    // fill fixed fields on the template, then emit the completed transaction
    uint8_t out[512];
    int64_t n = prepare((uint32_t)out, sizeof(out), (uint32_t)tmpl, tmpl_len);
    if (n < 0)
        rollback(SBUF("prepare failed"), n);

    uint8_t hash[32];
    if (emit((uint32_t)hash, 32, (uint32_t)out, n) != 32)
        rollback(SBUF("emit failed"), 1);

    accept(SBUF("emitted via prepare"), 0);
}

Related APIs. emit, etxn_details, etxn_fee_base, etxn_reserve.