SetHook Transaction
A new Transaction Type for the XRPL that sets a Hook onto an XRPL account.
SetHook Transaction
Hook web assembly bytecode is installed onto an XRPL account using the SetHook transaction.
An example appears below:
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Fee: "2000000",
Hooks:
[
{
Hook: {
CreateCode: fs.readFileSync('accept.wasm').toString('hex').toUpperCase(),
HookOn: '0000000000000000',
HookNamespace: addr.codec.sha256('accept').toString('hex').toUpperCase(),
HookApiVersion: 0
}
}
]
}
The transaction is deceptively simple, but hides significant complexity, described below.
Hooks Array
The main body of the SetHook transaction is the hooks array:
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Hooks: // This is the Hooks Array
[
{ Hook: { ... } }, // HookSet Object (position 0)
{ Hook: { ... } },
{ Hook: { ... } },
{ Hook: { ... } }. // HookSet Object (position 3)
]
}
This array mirrors the Hook Chain installed on the account:
- Position 0 in the array corresponds to position 0 in the Hook Chain.
- Position 3 in the array corresponds to position 3 in the Hook Chain, etc.
HookSet Object and Corresponding Hook
Each entry in the Hooks Array (in the SetHook Transaction) is called a HookSet Object, and its corresponding Hook in the account's Hook Chain is called the Corresponding Hook.

Example: A user performs an operation on each Hook in his/her Hook chain with a SetHook transaction.
HookDefinition
Each Corresponding Hook is an object containing a reference (pointer) to a HookDefinition object.
The HookDefinition object is an unowned reference-counted ledger object that provides for de-duplication of identical web assembly bytecode. Two users using an identical hook will both point to the same HookDefinition.

Example: Hook Definitions on the XRP Ledger
For more information see: Reference Counting
Hook Defaults
When a HookDefinition is created it contains the initial Parameters, Namespace and Grants supplied by the user. These become the Hook Defaults. Any Hook referencing this Hook Definition will use these defaults unless the SetHook Transaction that creates that reference explicitly overrides those defaults, or a subsequent Update Operation overrides them.
HookSet Operations
There are six possible operations: No Operation, Create, Update, Delete, Install and Namespace Delete
Each operation is specified by the inclusion or omission of certain HookSet Object fields. This might seem confusing at first but by working through a few examples the reader should find it intuitive; Essentially HookSet operations are a type of diff between a specific Hook's defaults, existing and newly specified fields.
Achieving each type of operation is explained in a subsection below.
No Operation
Occurs when:
- The HookSet Object is empty
Behaviour:
- No change of any kind is made.
Example:
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Fee: "2000000",
Hooks:
[
{
Hook: {}
}
]
}
Create Operation
Occurs when:
All of the following conditions are met:
- The Corresponding Hook does not exist or
FLAG_OVERRIDEis specified. CreateCodefield is specified and is not blank and contains the valid web assembly bytecode for a valid Hook.- No instance of the same web assembly bytecode already exists on the XRPL. (If it does and all other requirements are met then interpret as an Install Operation — see below.)
Behaviour:
- A reference counted
HookDefinitionobject is created on the XRPL containing the fields in the HookSet Object, with all specified fields (Namespace, Parameters, HookOn) becoming defaults (but not Grants.) - A
Hooksarray is created on the executing account, if it doesn't already exist. (This is the structure that contains the Corresponding Hooks.) - A
Hookobject is created at the Corresponding Hook position if one does not already exist. - The
Hookobject points at theHookDefinition. - The
Hookobject contains no fields exceptHookHashwhich points at the createdHookDefinition. - If
hsfNSDELETEflag is specified then any HookState entires in the destination namespace are deleted if they currently exist.
Example:
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Fee: "2000000",
Hooks:
[
{
Hook: {
CreateCode: fs.readFileSync('accept.wasm').toString('hex').toUpperCase(),
HookOn: '0000000000000000',
HookNamespace: addr.codec.sha256('accept').toString('hex').toUpperCase(),
HookApiVersion: 0
}
}
]
}
Install Operation
Occurs when:
All of the following conditions are met:
- The Corresponding Hook does not exist or
FLAG_OVERRIDEis specified. HookHashfield is specified and is not blank and contains the hash of a Hook that already exists as aHookDefinitionon the ledger orCreateCodefield is specified and is not blank and contains the valid web assembly bytecode for a valid hook that already exists on the ledger as aHookDefinition.
Behaviour:
- The reference count of the
HookDefinitionobject is incremented. - A
Hooksarray is created on the executing account, if it doesn't already exist. (This is the structure that contains the Corresponding Hooks.) - A
Hookobject is created at the Corresponding Hook position if one does not already exist. - The
Hookobject points at theHookDefinition. - The
Hookobject contains all the fields in the HookSet Object, except and unless: - A field or key-pair within a field is identical to the Hook Defaults set on the
HookDefinition, in which case it is omitted due to defaults. - If
hsfNSDELETEflag is specified then any HookState entires in the destination namespace are deleted if they currently exist.
Example:
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Fee: "2000000",
Hooks:
[
{
Hook: {
HookHash: "A5663784D04ED1B4408C6B97193464D27C9C3334AAF8BBB4FA5EB8E557FC4A2C",
HookOn: '0000000000000000',
HookNamespace: addr.codec.sha256('accept').toString('hex').toUpperCase(),
}
}
]
}
Update Operation
Occurs when:
All of the following conditions are met:
- The Corresponding Hook exists.
HookHashis absent.CreateCodeis absent.- One or more of
HookNamespace,HookParametersorHookGrantsis present.
General Behaviour:
- The Corresponding Hook is updated in such a way that the desired changes are reflected in the Corresponding Hook.
Specific Behaviour:
If HookNamespace is specified and differs from the Corresponding Hook's Namespace:
- the Corresponding Hook's
HookNamespaceis updated, and - if the
hsfNSDELETEflag is specified all HookState entires in the old namespace are deleted.
If HookParameters is specified, then for each entry:
- If
HookParameterNameexists butHookParameterValueis absent and the Corresponding Hook's Parameters (either specifically or via defaults) contains thisHookParameterNamethen the parameter is marked as deleted on the Corresponding Hook. - If
HookParameterNameexists andHookParameterValueexists then the Corresponding Hook's Parameters are modified to include the new or updated parameter.
If HookGrants is specified then:
- The Corresponding Hook's
HookGrantsarray is replaced with the array.
Example:
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Fee: "2000000",
Hooks:
[
{
Hook: {
HookNamespace: addr.codec.sha256('new_accept').toString('hex').toUpperCase(),
}
}
]
}
Delete Operation
Occurs when:
All of the following conditions are met:
- The Corresponding Hook exists.
hsfOVERRIDEis specified.- optionally
hsfNSDELETEis also specified. HookHashis absent.CreateCodeis present but empty.
Behaviour:
- The reference count of the
HookDefinitionobject is decremented. - If the reference count is now zero the
HookDefintionis removed from the ledger. - The
Hookobject in the Corresponding Hook position is deleted, leaving an empty position. - If
hsfNSDELETEis specified the namespace and all HookState entries are also deleted.
Example:
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Fee: "2000000",
Hooks:
[
{
Hook: {
CreateCode: "",
Flags: 1,
}
}
]
}
Namespace Reset
Occurs when:
All of the following conditions are met:
flagsis present andhsfNSDELETEis set.hsfOVERRIDEcan optionally also be specified if the Hook at this position is to be deleted.HookNamespaceis specified.CreateCodeis absent.HookHashis absent.HookGrants,HookParameters,HookOnandHookApiVersionare absent.
Behaviour:
- If the Corresponding Hook exists, it remains, nothing happens to it.
- A subset of HookState objects and the HookState directory for the specified namespace are removed from the ledger, up to the defined limit of 512. Further transactions are needed to continue the deletion process until all relevant records are removed.
Example:
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Fee: "2000000",
Hooks:
[
{
Hook: {
HookNamespace: addr.codec.sha256('accept').toString('hex').toUpperCase(),
Flags: 3,
}
}
]
}
Updated over 1 year ago