Pular para o conteúdo

Objetos Serializados

O Xahau tem formas serializadas canônicas de todos os objetos sujeitos ao consenso. Ao escrever um Hook, é inevitável que você se depare com objetos serializados. Estes se manifestam como buffers contendo o que pode parecer ao desenvolvedor como blobs binários opacos. Na verdade, você pode lê-los com o XRPL-Binary-Visualiser.

Por exemplo, um campo sfAmount serializa para uma coleção de bytes como 61D50F26109A32B7EC

Para auxiliar os desenvolvedores de Hooks a trabalhar com objetos serializados, o namespace sto foi criado dentro da API de Hooks. Essas funções manipulam ponteiros dentro de um buffer fornecido pelo Hook. Veja a tabela abaixo.

API de HookO que faz
sto_subfieldIndexa em um objeto serializado xrpld e retorna a localização e comprimento de um subcampo
sto_subarrayIndexa em um array serializado xrpld e retorna a localização e comprimento de um índice
sto_emplaceInsere um campo em um STObject existente em seu posicionamento canônico
sto_eraseRemove um campo de um STObject
sto_validateValida um STObject

Onde aplicável, essas APIs retornam um offset e um comprimento codificados em um único int64_t. Veja a documentação individual para detalhes.

Um cenário típico no qual você usaria a API STO é no processamento de memos em uma Transação de Origem. Como você provavelmente precisará de acesso ao memo completo de qualquer forma, uma forma eficiente de processar um conjunto de memos é simplesmente despejar o campo sfMemos inteiro em um buffer e então indexar dentro dele. Embora também seja possível usar a API de slot para fazer isso inserindo a Transação de Origem em um slot, isso resultaria em código adicional e cópia adicional.

#define SUB_OFFSET(x) ((int32_t)(x >> 32))
#define SUB_LENGTH(x) ((int32_t)(x & 0xFFFFFFFFULL))
#define SBUF(str) (uint32_t)(str), sizeof(str)
uint8_t memos[2048];
int64_t memos_len = otxn_field(SBUF(memos), sfMemos);
for (int i = 0; GUARD(3), i < 3; ++i)
{
int64_t memo_lookup = sto_subarray(memos, memos_len, i);
if (memo_lookup < 0)
rollback(SBUF("Memo lookup error"), 1);
uint8_t* memo_ptr = SUB_OFFSET(memo_lookup) + memos;
uint32_t memo_len = SUB_LENGTH(memo_lookup);
// o acima agora aponta para o memo ... faça algo aqui
}

Você pode notar alguma sobreposição entre as APIs de slot e as APIs STO. A diferença principal aqui é quem possui os dados subjacentes:

  • Se você estiver usando slots, então o xrpld possui o objeto com o qual você está interagindo.
  • Se você estiver usando a API STO, então o Hook possui o buffer com o qual você está interagindo.

Ambos os conjuntos de funções indexam em um Objeto Serializado sem cópias desnecessárias.