Skip to content

Commit

Permalink
contract calls fixes after review
Browse files Browse the repository at this point in the history
  • Loading branch information
andrei-marinica committed Sep 29, 2023
1 parent 246be4b commit 03b41a0
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions docs/developers/developer-reference/sc-contract-calls.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ fn callee_contract_proxy(&self, sc_address: ManagedAddress) -> callee_proxy::Pro

The point of the proxies is to help us build contract calls in a type-safe manner. But this is by no means compulsory. Sometimes we specifically want to build contract calls manually and serialize the arguments ourselves.

The point is to create a `ContractCallNoPayment` object. We'll discuss how to add the payments later.
We are looking to create a `ContractCallNoPayment` object. We'll discuss how to add the payments later.

The `ContractCallNoPayment` has two type arguments: the API and the expected return type. If we are in a contract, the API will always be the same as for the entire contract. To avoid having to explicitly specify it, we can use the following syntax:

Expand All @@ -178,7 +178,7 @@ contract_call.push_raw_argument(arg1_encoded);
contract_call.push_raw_argument(arg2_encoded);
```

If we are not in a smart contract we might do the same thing using the same, equivalent syntax:
If we are trying to create the same object outside of a smart contract, we do not have the `self.send()` API available, but we can always use the equivalent syntax:

```rust
let mut contract_call = ContractCallNoPayment::<StaticApi, ResultType>::new(to, endpoint_name);
Expand All @@ -195,13 +195,17 @@ contract_call.push_raw_argument(arg2_encoded);

Up to here we have created a contract call without payment, so an object of type `ContractCallNoPayment`, in the following ways:

<div style={{textAlign: 'center'}}>

```mermaid
graph LR
gen-proxy[Generated Proxy] --> ccnp[ContractCallNoPayment]
man-proxy[Manual Proxy] --> ccnp
ccnp-new["ContractCallNoPayment::new(to, function)"] --> ccnp
```

</div>

---

[comment]: # (mx-context-auto)
Expand All @@ -221,6 +225,8 @@ fn my_payable_endpoint(&self, arg: BigUint) -> BigUint {
}
```

More on payable endpoints and simple transfers [here](/developers/developer-reference/sc-payments). This section refers to transfers during contract calls only.


[comment]: # (mx-context-auto)

Expand Down Expand Up @@ -312,6 +318,8 @@ self.callee_contract_proxy(callee_sc_address)

To recap, these are all the various ways in which we can specify value transfers for a contract call:

<div style={{textAlign: 'center'}}>

```mermaid
graph LR
ccnp[ContractCallNoPayment]
Expand All @@ -323,6 +331,8 @@ graph LR
ccnp -->|".with_egld_or_single_esdt_transfer"| cc-egld-single[ContractCallWithEgldOrSingleEsdt]
```

</div>

---

[comment]: # (mx-context-auto)
Expand All @@ -337,6 +347,12 @@ Not all contract calls require explicit specification of the gas limit, leaving

On the other hand, promises and transfer-execute calls do require gas to be explicitly specified.

```rust
self.callee_contract_proxy(callee_sc_address)
.callee_endpoint(my_biguint_arg)
.with_gas_limit(gas_limit)
}
```

---

Expand All @@ -347,7 +363,7 @@ On the other hand, promises and transfer-execute calls do require gas to be expl
There are several ways in which contract calls are launched from another contract. Currently they are:
- asynchronous calls:
- single asynchronous calls:
- promises (multi ple asynchronous calls),
- promises (multiple asynchronous calls),
- transfer-execute calls,
- synchronous calls:
- executed on destination context,
Expand Down Expand Up @@ -409,7 +425,7 @@ fn callee_endpoint_callback(
}
```

The `#[call_result]` argument interprets the output of the called endpoint, and must almost always be of type `ManagedAsyncCallResult`. This type decodes the error status from the VM, more about it [here](/developers/data/multi-values#standard-multi-values). Its type argument must match the return type of the called endpoint.
The `#[call_result]` argument interprets the output of the called endpoint and must almost always be of type `ManagedAsyncCallResult`. This type decodes the error status from the VM, more about it [here](/developers/data/multi-values#standard-multi-values). Its type argument must match the return type of the called endpoint.

To assign this callback to the aforementioned async call, we hook it after `async_call`, but before `call_and_exit`:

Expand Down Expand Up @@ -457,7 +473,7 @@ Assume there is some additional context that we want to pass from our contract d

This context forms the contents of our callback closure.

More specifically, all callback arguments other than the `#[call_result]` will be passed to it before launching the call, they will be saved by the framework somewhere in the contract storage, then given to the callback and deleted.
More specifically, all callback arguments other than the `#[call_result]` will be passed to it before launching the call, they will be saved by the framework in the contract storage automatically, then given to the callback and deleted.

Example:

Expand Down Expand Up @@ -513,7 +529,9 @@ You can then use `original_caller` in the callback like any other function argum

### Promises

Promises (or multi-async calls) are a new feature that will be introduced in mainnet release 1.6. They are very similar to the old asynchronous calls, with the difference that launching them does not terminate current execution, and there can be several launched from the same transaction.
Promises (or multi-async calls) are a new feature that will be introduced in mainnet release 1.6. They are very similar to the old asynchronous calls, with the following differences:
- launching them does not terminate current execution;
- there can be several launched from the same transaction.

:::caution
Because this feature is currently not available on mainnet, contracts need to enable the "promises" feature flag in `Cargo.toml` to use the functionality:
Expand Down Expand Up @@ -708,6 +726,7 @@ It shares a lot in common with the contract calls, with these notable difference
- They get executed slightly differently.


<div style={{textAlign: 'center'}}>

```mermaid
flowchart TB
Expand All @@ -722,6 +741,8 @@ flowchart TB
.deploy_from_source()"| exec-upg["⚙️ Upgrade contract"]
```

</div>

The object encoding these calls is called `ContractDeploy`. Unlike the contract calls, there is a single such object.

Creating this object is done in a similar fashion: either via proxies, or manually. Constructors in proxies naturally produce `ContractDeploy` objects:
Expand Down

0 comments on commit 03b41a0

Please sign in to comment.