Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update esdt-tokens.mdx #790

Merged
merged 3 commits into from
Jan 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions docs/tokens/esdt-tokens.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,72 @@ Using the transaction in the example above, the receiver should be credited `12

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

## **Multiple tokens transfer to a smart contract**

Smart contracts may hold ESDT tokens and perform any kind of transaction with them, just like any Account. However, there are a few extra ESDT features dedicated to smart contracts:

**Payable versus non-payable contract**: upon deployment, a smart contract may be marked as _payable_, which means that it can receive either EGLD or ESDT tokens without calling any of its methods (i.e. a simple transfer). But by default, all contracts are _non-payable_, which means that simple transfers of EGLD or ESDT tokens will be rejected, unless they are method calls.

**ESDT transfer with method invocation**: it is possible to send ESDT tokens to a contract _as part of a method call_, just like sending EGLD as part of a method call. A transaction that sends ESDT tokens to a contract while also calling one of its methods has the following form:

```rust
MultiTokensTransferWithCallTransaction {
Sender: <account address of the sender>
Receiver: <same as sender>
Value: 0
GasLimit: 1_100_000 * num tokens + <an appropriate amount for the method call>
Data: "MultiESDTNFTTransfer" +
"@" + <account address of the smart contract bytes in hexadecimal encoding> +
"@" + <number of tokens to transfer in hexadecimal encoding> +
"@" + <token 0 identifier in hexadecimal encoding> +
"@" + <token 0 nonce in hexadecimal encoding> +
"@" + <token 0 quantity to transfer in hexadecimal encoding> +
"@" + <token 1 identifier in hexadecimal encoding> +
"@" + <token 1 nonce in hexadecimal encoding> +
"@" + <token 1 quantity to transfer in hexadecimal encoding> +
"@" + <name of method to call in hexadecimal encoding> +
"@" + <first argument of the method in hexadecimal encoding> +
"@" + <second argument of the method in hexadecimal encoding> +
...
}
```

:::tip
Each token requires the token identifier, the nonce and the quantity to transfer.

For fungible tokens (regular ESDT) the nonce has to be 0 (`00` hex-encoded)
:::

_For more details about how arguments have to be encoded, check [here](/developers/sc-calls-format)._

Example:

We send tokens and call the 'transfer' method on the smart contract. We also define the receiver as the argument of the transfer method.

```rust
MultiTokensTransferWithCallTransaction {
Sender: erd1sg4u62lzvgkeu4grnlwn7h2s92rqf8a64z48pl9c7us37ajv9u8qj9w8xg
Receiver: erd1sg4u62lzvgkeu4grnlwn7h2s92rqf8a64z48pl9c7us37ajv9u8qj9w8xg
Value: 0
GasLimit: 8_200_000
Data: "MultiESDTNFTTransfer" +
"@0000000000000000050032a3dc7511d6062c6a3b90ac02d8c3f474ef71c65008" + // smart contract address: erd1qqqqqqqqqqqqqpgqx23acag36crzc63mjzkq9kxr736w7uwx2qyqcmq7ar
"@02" + // 2 tokens to transfer
"@414c432d363235386432" + // ALC-6258d2
"@00" + // 0 -> the nonce is 0 for regular ESDT tokens
"@0c" + // 12 -> value to transfer
"@5346542d317134723869" + // SFT-1q4r8i
"@01" + // 1 -> the nonce of the SFT
"@03" + // 3 -> the quantity to transfer
"@7472616e73666572" + // method name is 'transfer'
"@f69adc800dca9e3ba3328d17ded25f3a8f328aa1e0e8a347f34ce5ea3aac5008" // there is one argument, the address: 'erd176ddeqqde20rhgej35taa5jl828n9z4pur52x3lnfnj75w4v2qyqa230vx'
}
```

Sending a transaction containing both an ESDT transfer _and a method call_ allows non-payable smart contracts to receive tokens as part of the call, as if it were EGLD. The smart contract may use dedicated API functions to inspect the name of the received ESDT tokens and their amount, and react accordingly.

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

## **Transfers done programmatically**

The [Rust framework](https://github.com/multiversx/mx-sdk-rs) exposes several ways in which you can transfer ESDT tokens. For example, in order to transfer _amount_ of _esdt_token_name_ to _address_, one would do the following:
Expand Down
Loading