# [Ride v5] dApp-to-App Invocation
A dApp callable function can invoke a callable function of another dApp, or another callable function of the same dApp, or even itself. The invocation is synchronous. The invoked function returns a value that the invoking function can use.
dApp-to-dApp invocation is processed as follows:
- A user sends an Invoke Script transaction that invokes the callable function 1.
- The callable function 1 invokes the callable function 2 via a strict variable initialized by the Invoke function.
- The callable function 2 is executed; the script actions and return value are calculated.
- The return value is assigned to the strict variable. The subsequent operations of callable function 1 are executed, taking into account script actions of callable function 2 (as if the actions are applied to the blockchain state).
- Finally, the script actions of callable functions 2 and 1 are applied to the blockchain state.
- dApp-to-dApp invocations can be nested.
- A dApp-to-dApp invocation can contain payments that will be transferred from the balance of the invoking dApp to the balance of the invoked dApp.
- All invoked callable functions are executed within a single Invoke Script transaction.
- dApp-to-dApp invocations are added in node version 1.3.0 and enabled with feature #16 “Ride V5, dApp-to-dApp invocations, Continuations”. Versions 1.3.x are now available for Stagenet only.
- The invoking dApp script uses Standard library version 5.
- If the dApp invokes itself, the invocation must not contain payments.
- The Invoke Script transaction version is 3.
- The total complexity is limited by 52,000 for all callable functions and asset scripts of involved smart assets. The sender's account script complexity is not included in that limit.
Continued computations and dApp-to-dApp invocation are mutually exclusive, that is, they cannot be initiated by the same transaction.
The minimum fee for the Invoke Script transaction is increased by 0.005 WAVES for each dApp-to-dApp invocation.
# Strict Variable
strict keyword defines a variable with eager evaluation. Unlike lazy variables defined with
let, a strict variable is evaluated immediately when script execution reaches it, that is, before the next expression.
# Invoke Function
Invoke(dApp: Address|Alias, function: String, arguments: List[Boolean|ByteVector|Int|String|List[Boolean|ByteVector|Int|String]], payments: List[AttachedPayments]): Any
|dApp: Address|Alias||Address or alias of a dApp to invoke|
|function: String|Unit||Name of a callable function. |
|arguments: List[Boolean|ByteVector|Int|String|List[Boolean|ByteVector|Int|String]]|Unit||Parameters of a callable function. |
|payments: List[AttachedPayment]||Payments to transfer from the invoking dApp to the invoked dApp, up to 2|
strict z = Invoke(dapp,foo,args,[AttachedPayment(unit,100000000)])
For details, see the dApp-to-dApp Invocation Function article.
# Invocation Fields
For dApp-to-dApp invocation, the fields of Invocation structure used by the invoked function are filled with the following values:
|1||caller||Address||Address of the dApp that invokes the callable function|
|2||callerPublicKey||ByteVector||Public key of the dApp that invokes the callable function|
|3||payments||List[AttachedPayment]||Payments indicated in the Invoke function|
|4||transactionId||ByteVector||ID of the Invoke Script transaction|
|6||feeAssetId||ByteVector|Unit||ID of the fee token|
# Callable Function Result
In Standard library version 5, a callable function result is a Tuple of two elements:
- List of script actions.
- Return value that is passed to the invoking function.
( [ ScriptTransfer(i.caller,100,unit) ], 42 )
In Standard library version 4 or 3, there is no return value, so
unit is implied.
For details, see the Callable Function article.
# Updating Balance and Account Data Storage Entries
If the callable function invoked by the
Invoke function performs script actions, the results of those actions are available to the invoking function:
- If the invoked function adds an entry to the account's data storage, the invoking function can obtain the entry after the invocation.
- If the invoked function deletes an entry from the account's data storage, the invoking function cannot obtain the entry after the invocation.
- If the invoked function performs actions with tokens (transfer, release/issue/burn, and others) and the invoking function obtains balances after the invocation, it receives the updated balances.
Payments attached to the dApp invocation are counted in the dApp balance before the script actions are executed. Therefore, tokens obtained in payments can be used in script actions, but cannot be used in payments attached to nested invocations.
# Transaction Fail
If the callable function's execution fails or throws an exception, the Invoke Script transaction could be rejected or saved on the blockchain as failed. This depends on whether the complexity of performed computations has exceeded the threshold for saving a failed transaction (currently 1000). The complexity is summed up for all invocations.
Consider the example: callable function 1 performs computations of 800 complexity, then invokes callable function 2 which performs computations of 300 complexity and then fails. The complexity 800 + 300 has exceeded the threshold, so the transaction is saved as failed, and the sender is charged a fee.
If the total complexity of executed callable functions and asset scripts exceeds the limit of 52,000, the transaction is saved as failed as well. For example, if the complexity of executed callable functions is 50,000 in total, and there is a smart asset in script action whose script's complexity is 2500.
In case of failure, no payments and script actions are applied to the blockchain state, even if some of the invoked functions are executed completely. The only state change the failed transaction entails is charging the fee.