Set aside funds in an escrow that delivers them to a predetermined recipient when certain conditions are met. If the escrow has an expiration, the funds can also be returned to the sender after it expires. The conditions for release can include a specific maturity time, a hash-based cryptocondition, or a smart function.
To escrow fungible tokens you must take note of the following:
- Trust Line Tokens must have the Allow Trust Line Locking flag enabled on their account.
- Multi-Purpose-Tokens (MPTs) must have both the Can Escrow and Can Transfer flags enabled.
- If the token requires authorization, both sender and recipient must be pre-authorized by the issuer.
(Updated by the TokenEscrow amendment. )
(Updated by the SmartEscrow amendment. )
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"TransactionType": "EscrowCreate",
"Amount": "10000",
"Destination": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"CancelAfter": 533257958,
"FinishAfter": 533171558,
"Condition": "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
"DestinationTag": 23480,
"SourceTag": 11747
}In addition to the common fields, EscrowCreate transactions use the following fields:
| Name | JSON Type | Internal Type | Required? | Description |
|---|---|---|---|---|
Amount | Currency Amount | Amount | Yes | Amount of XRP, in drops, or fungible tokens to deduct from the sender's balance and escrow. Once escrowed, the payment can either go to the Destination address (after the FinishAfter time) or be returned to the sender (after the CancelAfter time). (Updated by the TokenEscrow amendment. |
Bytecode | String - Hexadecimal | Blob | No | Compiled WebAssembly (WASM) code with a Smart Escrow function that must return success for the escrow to finish. (Requires the SmartEscrow amendment. |
Data | String - Hexadecimal | Blob | No | Arbitrary data that can be read and written by this escrow's smart function. If present, must not be empty and must be less than the maximum bytecode size currently set by [fee voting][]. (Requires the SmartEscrow amendment. |
Destination | String - Address | AccountID | Yes | Address to receive escrowed funds. |
CancelAfter | Number | UInt32 | No | The time when this escrow expires, in seconds since the Ripple Epoch. This value is immutable; the funds can only be returned to the sender after this time. |
FinishAfter | Number | UInt32 | No | The time, when the escrowed funds can be released to the recipient, in seconds since the Ripple Epoch. This value is immutable, and the funds can't be accessed until this time. |
Condition | String - Hexadecimal | Blob | No | A PREIMAGE-SHA-256 crypto-condition that must be fulfilled for funds to be released to the recipient. If the condition is not fulfilled before the expiration time specified in the CancelAfter field, the funds can only revert to the sender. |
DestinationTag | Number | UInt32 | No | An arbitrary tag to further specify the destination for this escrowed payment, such as a hosted recipient at the destination address. |
You must specify one of the following combinations of fields:
| Summary | FinishAfter | Condition | CancelAfter | Bytecode |
|---|---|---|---|---|
| Time-based (XRP only) | ✅ | |||
| Time-based with expiration | ✅ | ✅ | ||
| Timed conditional (XRP only) | ✅ | ✅ | ||
| Timed conditional with expiration | ✅ | ✅ | ✅ | |
| Conditional with expiration | ✅ | ✅ | ||
| Function-based with expiration | ✅ | ✅ | ||
| Timed function with expiration | ✅ | ✅ | ✅ | |
| Conditional function with expiration | ✅ | ✅ | ✅ | |
| Timed conditional function with expiration | ✅ | ✅ | ✅ | ✅ |
It is not possible to create a conditional or function-based escrow with no expiration, but you can specify an expiration that is very far in the future.
If an escrow has multiple criteria for release, including any combination of a time-based release, a crypto-condition, or a smart function, the escrow can only release funds to the recipient if all of the criteria are met. For example, you can make an escrow that can only be released if the smart function returns success and a crypto-condition is fulfilled, but you cannot make an escrow that can be released if the smart function or crypto-condition are satisfied.
If the escrow has a Bytecode field, it has a special transaction cost of 10 times the base fee plus an additional 5 drops per byte. The exact formula is:
(base_fee × 10) + (bytecode_size × 5)base_feeis the reference transaction cost, in drops of XRP.bytecode_sizeis the size of theBytecodefield, in bytes.
The 5 drops per byte does not change even if fee voting changes the base fee.
Besides errors that can occur for all transactions, EscrowCreate transactions can result in the following transaction result codes:
| Error Code | Description |
|---|---|
tecDIR_FULL | Either the sender or the destination owns too many objects in the ledger. This error is effectively impossible to receive if fixDirectoryLimit |
tecDST_TAG_NEEDED | The destination account requires destination tags but this transaction did not provide one. |
tecFROZEN | For a trust line token escrow, the token is frozen: this includes the sender being individually frozen, the destination being deep frozen, or the token being globally frozen. (Requires the TokenEscrow amendment. |
tecINSUFFICIENT_FUNDS | For token escrows, the sender does not currently hold enough funds to pay for the escrow. (Note: XRP escrows return tecUNFUNDED for this case instead.) (Requires the TokenEscrow amendment. |
tecLOCKED | For an MPT escrow, the token is locked. (Requires the TokenEscrow amendment. |
tecNO_AUTH | For token escrows, the sender is not authorized to create this escrow. There are several cases that can cause this error, including:
(Requires the TokenEscrow amendment. |
tecNO_DST | The specified destination account does not exist in the ledger. |
tecNO_ISSUER | For a trust line token escrow, the issuer of the token (as specified in Amount) does not exist in the ledger. (Requires the TokenEscrow amendment. |
tecNO_LINE | For a trust line token escrow, the sender does not have a trust line for the specified token. (Requires the TokenEscrow amendment. |
tecNO_PERMISSION | The sender does not have permission to create this escrow. There are several cases that can cause this error, including:
(Updated by the TokenEscrow amendment. |
tecOBJECT_NOT_FOUND | For an MPT escrow, the MPT issuance does not exist or the sender does not hold the MPT; or, the MPT requires access to a permissioned domain but the domain does not exist in the ledger. (Requires the TokenEscrow amendment. |
tecPRECISION_LOSS | For a trust line token escrow, the amount of the escrow is too small relative to the sender's balance, which would cause it to be rounded to 0. (Requires the TokenEscrow amendment. |
tecUNFUNDED | For XRP escrows, the sender lacks sufficient spendable balance, which excludes XRP set aside for reserves. (Note: token escrows use tecINSUFFICIENT_FUNDS instead.) |
temBAD_AMOUNT | The Amount is invalid. For example, it is negative; it is not XRP and the TokenEscrow (Updated by the TokenEscrow amendment. |
temBAD_CURRENCY | The Amount specifies an invalid currency, such as a trust line token with the currency code for XRP. (Requires the TokenEscrow amendment. |
temBAD_EXPIRATION | The was a problem with the expiration (CancelAfter) or finish time (FinishAfter). For example, the transaction did not specify a required field, or the expiration is before the finish time. |
temINVALID_BYTECODE | The Bytecode field did not contain a valid smart function. (Requires the SmartEscrow amendment. |
temTEMP_DISABLED | Smart functions have been temporarily disabled by fee voting. (Requires the SmartEscrow amendment. |