0100 XLS-100d: Smart Escrows #270
Replies: 4 comments 2 replies
-
Should this be "Must have at least one of |
Beta Was this translation helpful? Give feedback.
-
|
Can Smart Even if the Smart |
Beta Was this translation helpful? Give feedback.
-
|
This spec was updated today, 2025-08-08. The main changes:
|
Beta Was this translation helpful? Give feedback.
-
|
This spec was updated today, 2025-09-26. The main changes:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
1. Abstract
This proposal introduces a new layer of programmability to XRPL Escrows, enabling conditions beyond the current time-based or crypto-conditional constraints. The idea is to allow a small piece of code to reside on the
Escrowobject itself, controlling whether the escrow can be released or canceled. By adding programmatic conditions, we can expand the XRPL’s utility, making Escrows more versatile for scenarios such as notary approvals, compliance holds, and P2P conditional transactions.2. Motivation
Smart Escrows are a first step toward expanding XRPL’s on-ledger functionality, enhancing use cases like auction mechanics, cascading real estate escrows, and peer-to-peer bets using oracle data, all within the security of the XRPL itself.
2.1. Example Use-Cases
3. Overview
The design involves a minimal, programmable code block attached to an Escrow object that executes logic to determine whether the Escrow can be completed. This follows the model of a restricted, on-ledger “smart contract,” where conditions can be coded and verified directly on-chain. This is an incremental extension of XRPL's CryptoConditions, enhancing flexibility with custom validation while maintaining computational limits and simplicity.
The code block is attached to the Escrow on creation (in an
EscrowCreatetransaction) and executed on anEscrowFinishtransaction for that escrow.This design is essentially an extension of the idea of using an Escrow as a Smart Contract.
The details of the WASM engine and the API are in a separate XLS.
This proposal involves:
EscrowandFeeSettingsledger objectsEscrowCreate,EscrowFinish, andSetFeetransactionsThis feature will require an amendment, tentatively titled
SmartEscrow.3.1. Background: XRPL Escrows
There are currently two ways to release an escrow: Time-based and Condition-based.
A time-based escrow releases its funds after a certain specified time. In more technical terms, a time-based escrow has the
FinishAfterfield and can be released anytime after the time specified in theFinishAfterfield.A condition-based escrow essentially only releases its funds if a password is provided. In more technical terms, a condition-based escrow has the
Conditionfield and can be released if the matchingFulfillmentfield (essentially the reverse of a hash) is provided on theEscrowFinishtransaction.3.1.1. Table of Allowed Options
Currently, these are the combinations of allowed escrow options:
FinishAfterConditionCancelAfter3.2. Background: Crypto-Conditions
Crypto conditions are a standardized way to express a wide range of conditional requirements. These include something like hashlocks (essentially a password), but crypto-conditions also support more complex constructions like multi-signature requirements (note: this is different from the existing XRPL multi-signature design) or conditions involving specific data. When used to execute Escrows, the XRP Ledger currently only supports hashlock-like conditions, and not the full suite of available Crypto Conditions.
For more information around how crypto-conditions work with escrows, see here.
3.3. Background: XRPL Extensions
An XRPL Extension is a small piece of code attached to an XRPL building block, which allows users to add some custom logic to the existing primitives. This can be very useful for projects that like the existing features of the XRPL, but need a minor modification to a feature to be able to use it.
See the blog post here for more details.
4. Serialized Type:
STInt324.1.
STypeValueThe
STypevalue forInt32is12.4.2. JSON Representation
An
Int32will be represented as anumber(orint) in JSON, in a fairly standard manner.4.3. Additional Accepted JSON Inputs
Alternate inputs include:
uint(if the value is less thanint32::max)string(decimal unless a0xor0bprefix is used)4.4. Binary Encoding
An
Int32will be encoded in standardinttwo's complement encoding.4.5. Example JSON and Binary Encoding
1will be encoded as0001.-1will be encoded asffff.5. Ledger Entry:
EscrowThe
Escrowobject already exists on the XRPL. We propose a slight modification to support Smart Escrows.5.1. Fields
As a reference, here are the existing fields for the
Escrowobject.AccountstringAccountIDAmountstringAmountCancelAfternumberUInt32ConditionstringBlobEscrowFinishtransaction must contain a fulfillment that satisfies this condition.DestinationstringAccountIDDestinationNodestringUInt64DestinationTagnumberUInt32FinishAfternumberUInt32EscrowFinishtransaction before this time fails.LedgerEntryTypestringUInt160x0075, mapped to the stringEscrow, indicates that this is anEscrowentry.OwnerNodestringUInt64PreviousTxnIDstringHash256PreviousTxnLgrSeqnumberUInt32SourceTagnumberUInt32We propose two additional fields:
FinishFunctionstringBlobDatastringBlobFinishFunction(size limits TBD).5.1.1.
FinishFunctionThe compiled WASM code included in this field must contain a function named
finishthat takes no parameters and returns a signed integer (int32). If the function returns a value greater than 0, the escrow can be finished. Otherwise, the escrow cannot be finished. The function is triggered by anEscrowFinishtransaction.See Section 7 for more details.
5.2. Reserves
An
Escrowobject with aFinishFunctionwill cost 1. additional object reserve per 500 bytes (beyond the first 500 bytes, which are included in the first object reserve).6. Transaction:
EscrowCreateThe
EscrowCreatetransaction already exists on the XRPL. We propose a slight modification to support Smart Escrows.6.1. Fields
As a reference, here are the existing fields for the
EscrowCreatetransaction.AmountAmountAmountDestinationstringAccountIDConditionstringBlobCancelAfterfield, the funds can only revert to the sender.CancelAfternumberUInt32FinishAfternumberUInt32DestinationTagnumberUInt32We propose two additional fields:
FinishFunctionstringBlobDatastringBlobFinishFunction.Some rules about what conditions must be satisfied for a valid
EscrowCreatetransaction:CancelAfter,FinishAfter, orFinishFunction. AConditionmay still be specified, if desired.FinishFunctionfield is included, thenCancelAftermust also be included. For at least initial release of this feature, the escrow must be cancellable, in case something goes wrong with theFinishFunctioncode. Note: A function-based escrow without an expiration could be added in the future.This table format is taken from here.
Bold = new options
FinishAfterConditionCancelAfterFinishFunction6.2. Transaction Fee
An$base_fee * 10$ ) + 5. drops per byte in the
EscrowCreatewith aFinishFunctioncosts costs 100 drops (FinishFunction.6.3. Failure Conditions
The existing failure conditions still apply.
These failure conditions are added, if
FinishFunctionis included:FinishAfter,Condition,CancelAfter, andFinishFunctionis not allowed based on the above table.FinishFunctionis not valid WASM, or does not follow the specifications of theFinishFunction(specified in section 7).FinishFunctionis greater than the size limit (specified inFeeSettingsbelow)6.4. State Changes
There are no additional state changes, other than adding the new fields to the
Escrowobject.7. Transaction:
EscrowFinishThe
EscrowFinishtransaction already exists on the XRPL. We propose a slight modification to support Smart Escrows.7.1. Fields
As a reference, here are the existing fields for the
EscrowFinishtransaction.OwnerstringAccountIDOfferSequencenumberUInt32EscrowCreatetransaction that created the escrow to finish.ConditionstringBlobCredentialIDsarrayVector256FulfillmentstringBlobCondition.We propose one additional field:
ComputationAllowancenumberUInt32Escrowobject has aFinishFunctionfield.7.2. Transaction Fee
There will be a higher transaction fee for executing an
EscrowFinishtransaction when there is aFinishFunctionattached to the escrow. The exact amounts will be determined during the implementation process (and added to the spec here).7.3. Failure Conditions
The existing failure conditions still apply.
These failure conditions are added:
ComputationAllowanceis included, but theEscrowdoesn't have aFinishFunctionEscrowhas aFinishFunction, but aComputationAllowanceisn't includedComputationAllowanceprovided is not enough gas to complete the processing of theFinishFunction.FinishFunctionreturns a0or negative number.7.4. State Changes
There are no additional state changes.
7.5. Metadata Changes
There are two additional metadata fields:
GasUsedUInt32FinishFunctionin the escrow.WasmReturnCodeInt32FinishFunction.8. Ledger Object:
FeeSettingsThe
FeeSettingsledger object already exists on the XRPL. TheFeeSettingsentry contains the current base transaction and reserve amounts as determined by fee voting.We propose a slight modification to support Smart Escrows. This will allow the UNL to vote on limits and prices of Smart Escrow execution, so that the network does not need a separate amendment to adjust them, and they can be adjusted on an as-needed basis (e.g. increasing caps and lowering fees as performance improvements are made).
8.1. Fields
As a reference, here are the existing fields for the
FeeSettingsledger object.BaseFeeDropsstringAmountFlagsnumberUInt32FeeSettingsobjects. The value is always0.LedgerEntryTypestringUInt160x0073, mapped to the stringFeeSettings, indicates that this object contains the ledger's fee settings.ReserveBaseDropsstringAmountReserveIncrementDropsstringAmountPreviousTxnIDstringUInt256PreviousTxnLgrSeqnumberUInt32We propose three additional fields:
ExtensionComputeLimitnumberUInt32ExtensionSizeLimitnumberUInt32GasPricenumberUInt329. Transaction:
SetFeeA
SetFeepseudo-transaction marks a change in transaction cost or reserve requirements as a result of fee voting.We propose a slight modification to support Smart Escrows. This will allow the UNL to vote on limits and prices of Smart Escrow execution, so that the network does not need a separate amendment to adjust them, and they can be adjusted on an as-needed basis (e.g. increasing caps and lowering fees as performance improvements are made).
9.1. Fields
As a reference, here are the existing fields for the
SetFeetransaction.BaseFeeDropsstringAmountReserveBaseDropsstringAmountReserveIncrementDropsstringAmountLedgerSequencenumberUInt32We propose three additional fields:
ExtensionComputeLimitnumberUInt32ExtensionSizeLimitnumberUInt32GasPricenumberUInt3210. How the
FinishFunctionField WorksThe
FinishFunctionfield will contain compiled WebAssembly (WASM) code that is uploaded to the XRPL. The details of how the WASM engine will execute the code will be provided in a separate XLS.Some guidelines on what you can/cannot do in the WASM code:
ExtensionComputeLimitfield inFeeSettings)Datafield)Datafield of theEscrow)11. Invariants
Any escrow with a
FinishFunctionfield must have aCancelAfterfield. This provides better security in case something goes wrong with theFinishFunction, either due to user error or due to a bug. This restriction may be relaxed in the future.12. Security
The implementation will undergo rigorous testing and security audits to ensure that smart escrow developers cannot edit any other ledger object, and continue to obey all other rules of the XRPL.
13. Rationale
Smart Escrows are designed to address the limitations of XRPL’s current escrow mechanisms, which only support time-based and hashlock (crypto-condition) releases. The idea is to enable more expressive, programmable conditions for escrow release, unlocking use cases such as notary approvals, compliance holds, and oracle-driven transactions directly on XRPL.
13.1. Design Choices
finish()function with limited access to ledger data and a small, escrow-localDatafield. This reduces attack surface and complexity, while still enabling meaningful programmability.CancelAfterfor Smart Escrows: To mitigate risks of stuck funds due to buggy or malicious WASM code, every Smart Escrow must be cancellable. This was debated, but consensus was that safety outweighs flexibility for initial deployment.FeeSettingsandSetFeeallow the network to dynamically adjust resource usage and pricing, preventing abuse and adapting to future improvements.13.2. Alternatives Considered
13.3. Related Work
Other blockchains support similar programmable escrow mechanisms:
XRPL’s approach is intentionally minimal and tightly scoped to maintain performance and security.
13.4. Objections and Concerns
Overall, Smart Escrows balance programmability, safety, and simplicity, providing a foundation for future XRPL extensions.
14. Code Examples
14.1. Notary Release
Only one notary account may release the escrow.
14.2. Temporary Hold
The escrow can only be released if the destination holds a specific credential.
14.3. Pseudo-Options
The escrow can only be released if the price of an oracle says that a token is at least $1.
Appendix
Appendix A: FAQ
A.1: Isn't this kind of useless if I can only store XRP in an escrow?
Support for Issued Currencies and MPTs is currently (as of August 2025) up for voting as a part of the TokenEscrow amendment.
A.2: Can an existing escrow be updated to have a
FinishFunction?No. An Escrow’s release condition(s) cannot be updated after it is created. The escrow's "contract" (in the legal sense, not in the smart contract sense) must remain the same after creation.
A.3: Can the
FinishFunctionfield be updated after the escrow has been created?No. An Escrow’s release condition(s) cannot be updated after it is created.
A.4: Can the
Datafield be updated with a transaction?No, at this time the
Datafield can only be updated by theFinishFunctioncode.A.5: Do all nodes and validators need to run the
FinishFunctioncode?Yes. They need to in order to ensure that the error code returned (and validated) in the transaction is correct.
A.6: How does this design prevent abuse/infinite loops from eating up rippled resources, while allowing for sufficient compute for Smart Escrow developers?
The UNL can adjust the parameters based on the needs and limitations of the network, to ensure that developers have enough computing resources for their needs, while also preventing them from overrunning the network with their extensions.
A.7: Why not use an
STDatatype for theDatafield?The
Datafield is an optional 4KB raw on ledger storage area attached to a (smart) escrow ledger object. It is currently treated as an opaque blob, with read and write operations applied to the entire 4KB block. This makes it somewhat difficult to work with. Theoretically, we could enhance the host functions to support partial reads and writes, or add utilities to assist with serialization.We decided to keep the current design for the smart escrow feature for now and revisit it later, once we have a better sense of how people will use the field.
A.8: Can there be an additional
initfunction that is run onEscrowCreate?The calling
init()byEscrowCreatehas at least the following two benefits:Datafield of theEscrowledger object, though a separateEscrowFinishtransaction after theEscrowCreatecan initialize theDatafield too, or the user can upload their desiredDatafield in theEscrowCreate.Escrowcreation can be conditional depending on theinit()result.We think those benefits are meaningful, but not sure how much. We can always add this feature as an amendment later on, depending on Smart Escrow usage and need.
Beta Was this translation helpful? Give feedback.
All reactions