This is an old revision of the document!


Practical Session 04.

Fungible vs Non-Fungible Tokens:

  • Fungibility refers to an asset's ability to be exchanged for something else of equal value;
  • Some examples of fungible assets include currencies, commodities, and precious stones;
  • Non-fungible assets are unique, requiring much more complex valuation before a sale and include things like real estate, art, and sports cards.

Think about the following example if fungible or non-fungible:

  • Diamond rock;
  • Penthouse apartment in Manhattan;
  • Mona Lisa painting;
  • LeBron James sport card;
  • LeBron James shirt he played in the 2020 NBA Finals;
  • A character in World of Warcraft.

ESDT Tokens

ESDT stands for Elrond Standard Digital Token.

Custom tokens at native speed and scalability, like EGLD.

The Elrond network natively supports the issuance of custom tokens, without the need for contracts such as ERC20 (Ethereum), but addressing the same use-cases. And due to the native in-protocol support, transactions with custom tokens do not require the VM at all. In effect, this means that custom tokens are as fast and as scalable as the native EGLD token itself.

The balances of ESDT tokens held by an Account are stored directly under the data trie of that Account. It also implies that an Account can hold balances of any number of custom tokens, in addition to the native EGLD balance. The protocol guarantees that no Account can modify the storage of ESDT tokens, neither its own nor of other Accounts.

ESDT tokens can be issued, owned and held by any Account on the Elrond network, which means that both users and smart contracts have the same functionality available to them. Due to the design of ESDT tokens, smart contracts can manage tokens with ease, and they can even react to an ESDT transfer.

Issuance of fungible ESDT tokens

ESDT tokens are issued via a request to the Metachain, which is a transaction submitted by the Account which will manage the tokens. When issuing a token, one must provide a token name, a ticker, the initial supply, the number of decimals for display purpose and optionally additional properties. The issuance cost is set to 0.05 EGLD.

The receiver address erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u is a built-in system smart contract (not a VM-executable contract), which only handles token issuance and other token management operations, and does not handle any transfers. The contract will add a random string to the ticker thus creating the token identifier. The random string starts with “-” and has 6 more random characters (3 bytes - 6 characters hex encoded). For example, a token identifier could look like ALC-6258d2.

If you want to make an erdpy transaction use the info from Elrond documentation to correctly format your parameters.

You can find more details here.

Issuance example:

IssuanceTransaction {
    Sender: erd1sg4u62lzvgkeu4grnlwn7h2s92rqf8a64z48pl9c7us37ajv9u8qj9w8xg
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
    Value: 50000000000000000 # (0.05 EGLD)
    GasLimit: 60000000
    Data: "issue" +
          "@416c696365546f6b656e73" +  // "AliceTokens" hex encoded
          "@414c43" +                  // "ALC" hex encoded
          "@f3d7b4c0" +                // 4091000000 hex encoded
          "@06"                        // 6 hex encoded  
}

You can use this tool for conversion.

TASK

Issue an ESDT token of your own.

Mint fungible ESDT tokens

Actions issue and mint are distinct! First, one must issue the token to exist on the blockchain. Second, the owner/issuer of the token must mint tokens.

On Mainnet, starting with epoch 432, global mint is disabled so one has to use local mint instead.

LocalMintTransaction {
    Sender: <address with ESDTRoleLocalMint role>
    Receiver: <same as sender>
    Value: 0
    GasLimit: 300000
    Data: "ESDTLocalMint" +
          "@" + <token identifier in hexadecimal encoding> +
          "@" + <supply to mint in hexadecimal encoding>
}

Verify if the transaction worked.

Setting ESDTRoleLocalMint

Assign ESDTRoleLocalMint to your address:

RolesAssigningTransaction {
    Sender: <address of the ESDT manager>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
    Value: 0
    GasLimit: 60000000
    Data: "setSpecialRole" +
          "@" + <token identifier in hexadecimal encoding> +
          "@" + <address to assign the role(s) in a hexadecimal encoding> +
          "@" + <role in hexadecimal encoding> +
          "@" + <role in hexadecimal encoding> +
          ...
}

You can find more details here

TASK

Set roles for your address.

Minting ESDT Tokens

An account with the ESDTRoleLocalMint role set can perform a local mint.

LocalMintTransaction {
    Sender: <address with ESDTRoleLocalMint role>
    Receiver: <same as sender>
    Value: 0
    GasLimit: 300000
    Data: "ESDTLocalMint" +
          "@" + <token identifier in hexadecimal encoding> +
          "@" + <supply to mint in hexadecimal encoding>
}
TASK

Mint 1.000.000 ESDT Tokens you created.

Burning ESDT Tokens

Anyone that holds an amount of ESDT tokens may burn it at their discretion, effectively losing them permanently. This operation reduces the total supply of tokens, and cannot be undone, unless the token manager mints more tokens.

Do you have roles for burning?

Check the creation transaction.

LocalBurnTransaction {
    Sender: <address with ESDTRoleLocalBurn role>
    Receiver: <same as sender>
    Value: 0
    GasLimit: 300000
    Data: "ESDTLocalBurn" +
          "@" + <token identifier in hexadecimal encoding> +
          "@" + <supply to burn in hexadecimal encoding>
}
Task

Burn 30% of your ESDTTokens

Other actions for ESDTTokens

Pausing and Unpausing

The manager of an ESDT token may choose to suspend all transactions of the token, except minting, freezing/unfreezing and wiping. Check more details here.

Freezing and Unfreezing

The manager of an ESDT token may freeze the tokens held by a specific Account. As a consequence, no tokens may be transferred to or from the frozen Account. Freezing and unfreezing the tokens of an Account are operations designed to help token managers to comply with regulations. The manager of an ESDT token may choose to suspend all transactions of the token, except minting, freezing/unfreezing and wiping. Check more details here.

Wiping

The manager of an ESDT token may wipe out all the tokens held by a frozen Account. This operation is similar to burning the tokens, but the Account must have been frozen beforehand, and it must be done by the token manager. Wiping the tokens of an Account is an operation designed to help token managers to comply with regulations. The manager of an ESDT token may choose to suspend all transactions of the token, except minting, freezing/unfreezing and wiping. Check more details here.

Non-Fungible Tokens

The Elrond protocol introduces native NFT support by adding metadata and attributes on top of the already existing ESDT. This way, one can issue a semi-fungible token or a non-fungible token which is quite similar to an ESDT, but has a few more attributes, as well as an assignable URI. Once owning a quantity of a NFT/SFT, users will have their data store directly under their account, inside the trie.

The flow of issuing and transferring non-fungible or semi-fungible tokens is:

  1. register/issue the token
  2. set roles to the address that will create the NFT/SFTs
  3. create the NFT/SFT
  4. transfer quantity(es)

Issuance of Non-Fungible Tokens

One has to perform an issuance transaction in order to register a non-fungible token. Non-Fungible Tokens are issued via a request to the Metachain, which is a transaction submitted by the Account which will manage the tokens. When issuing a token, one must provide a token name, a ticker and optionally additional properties.

IssuanceTransaction {
    Sender: <account address of the token manager>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
    Value: 50000000000000000 # (0.05 EGLD)
    GasLimit: 60000000
    Data: "issueNonFungible" +
          "@" + <token name in hexadecimal encoding> +
          "@" + <token ticker in hexadecimal encoding>
}

Optionally, the properties can be set when issuing a token. Example:

IssuanceTransaction {
    Sender: <account address of the token manager>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
    Value: 50000000000000000 # (0.05 EGLD)
    GasLimit: 60000000
    Data: "issueNonFungible" +
          "@" + <token name in hexadecimal encoding> +
          "@" + <token ticker in hexadecimal encoding> +
          "@" + <"canFreeze" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
          "@" + <"canWipe" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
          "@" + <"canPause" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
          "@" + <"canTransferNFTCreateRole" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
          "@" + <"canChangeOwner" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
          "@" + <"canUpgrade" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
          "@" + <"canAddSpecialRoles" hexadecimal encoded> + "@" + <"true" or "false" hexadecimal encoded> +
          ...
}

The receiver address erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u is a built-in system smart contract (not a VM-executable contract), which only handles token issuance and other token management operations, and does not handle any transfers. The contract will add a random string to the ticker thus creating the token identifier. The random string starts with “-” and has 6 more random characters. For example, a token identifier could look like ALC-6258d2.

Issuance of Semi-Fungible Tokens

One has to perform an issuance transaction in order to register a semi-fungible token. Semi-Fungible Tokens are issued via a request to the Metachain, which is a transaction submitted by the Account which will manage the tokens. When issuing a semi-fungible token, one must provide a token name, a ticker and optionally additional properties.

IssuanceTransaction {
    Sender: <account address of the token manager>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
    Value: 50000000000000000 # (0.05 EGLD)
    GasLimit: 60000000
    Data: "issueSemiFungible" +
          "@" + <token name in hexadecimal encoding> +
          "@" + <token ticker in hexadecimal encoding>
}
TASK

Issue your own SFT or NFT.

NFT Roles

In order to be able to perform actions over a token, one needs to have roles assigned. The existing roles are:

For NFT:

  • ESDTRoleNFTCreate : this role allows one to create a new NFT
  • ESDTRoleNFTBurn : this role allows one to burn quantity of a specific NFT
  • ESDTRoleNFTUpdateAttributes : this role allows one to change the attributes of a specific NFT
  • ESDTRoleNFTAddURI : this role allows one add URIs for a specific NFT
  • ESDTTransferRole : this role enables transfer only to specified addresses. The owner of the NFT and the address with the ESDTTransferRole should be located on the same shard. The addresses with the transfer role can transfer anywhere.

For SFT:

  • ESDTRoleNFTCreate : this role allows one to create a new SFT
  • ESDTRoleNFTBurn : this role allows one to burn quantity of a specific SFT
  • ESDTRoleNFTAddQuantity : this role allows one to add quantity of a specific SFT
  • ESDTTransferRole : this role enables transfer only to specified addresses. The owner of the SFT and the address with the ESDTTransferRole should be located on the same shard. The addresses with the transfer role can transfer anywhere.

Roles can be assigned by sending a transaction to the Metachain from the ESDT manager. Within a transaction of this kind, any number of roles can be assigned (minimum 1).

RolesAssigningTransaction {
    Sender: <address of the ESDT manager>
    Receiver: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u
    Value: 0
    GasLimit: 60000000
    Data: "setSpecialRole" +
          "@" + <token identifier in hexadecimal encoding> +
          "@" + <address to assign the role(s) in a hexadecimal encoding> +
          "@" + <role in hexadecimal encoding> +
          "@" + <role in hexadecimal encoding> +
          ...
}

NFT/SFT Fields

Fields of an NFT/SFT:

  • Name
  • Quantity (for NFT must be 1)
  • Royalties (allows creator to receive royalties for any transaction involving their NFT)
  • Hash (of NFT metadata)
  • Attributes (additional
  • URIs (mandatory, png, jpeg, mp3, gif, etc.)

Creation of an NFT

NFTCreationTransaction {
    Sender: <address with ESDTRoleNFTCreate role>
    Receiver: <same as sender>
    Value: 0
    GasLimit: 3000000 + Additional gas (see below)
    Data: "ESDTNFTCreate" +
          "@" + <token identifier in hexadecimal encoding> +
          "@" + <initial quantity in hexadecimal encoding> +
          "@" + <NFT name in hexadecimal encoding> +
          "@" + <Royalties in hexadecimal encoding> +
          "@" + <Hash in hexadecimal encoding> +
          "@" + <Attributes in hexadecimal encoding> +
          "@" + <URI in hexadecimal encoding> +
          "@" + <URI in hexadecimal encoding> +
          ...
}
TASK

Create your own NFT.

Example of NFT Creation:

{
    Sender: <address with ESDTRoleNFTCreate role>
    Receiver: <same as sender>
    Value: 0
    GasLimit: 3000000
    Data: "ESDTNFTCreate" +
          "@414c432d317132773365" +  # previously fetched token identifier
          "@01" + # quantity: 1
          "@42656175746966756c20736f6e67" + # NFT name: 'Beautiful song' in hexadecimal encoding
          "@1d4c" + # Royalties: 7500 =75%c in hexadecimal encoding
          "@00" + # Hash: 00 in hexadecimal encoding
          "@6d657461646174613a697066734349442f736f6e672e6a736f6e3b746167733a736f6e672c62656175746966756c2c6d75736963" + # Attributes: metadata:ipfsCID/song.json;tags:song,beautiful,music   in hexadecimal encoding> +
          "@55524c5f746f5f646563656e7472616c697a65645f73746f726167652f736f6e672e6d7033" + # URI: URL_to_decentralized_storage/song.mp3 in hexadecimal encoding> +
          "@" + <additional optional URI in hexadecimal encoding> +
}

Other management operations

Transfer NFT

TransferTransaction {
    Sender: <account address of the sender>
    Receiver: <same as sender>
    Value: 0
    GasLimit: 1000000 + length of Data field in bytes * 1500
    Data: "ESDTNFTTransfer" +
          "@" + <collection identifier in hexadecimal encoding> +
          "@" + <the NFT nonce in hexadecimal encoding> +
          "@" + <quantity to transfer in hexadecimal encoding> +
          "@" + <destination address in hexadecimal encoding>
}
TASK

Transfer your NFT to erd1xex9ptczwwce4w9zejpjranj6mt8q5sqseenfj7ym55gfcpgq7cq5e9amz.

Transfer to a Smart Contract

TransferTransaction {
    Sender: <account address of the sender>
    Receiver: <same as sender>
    Value: 0
    GasLimit: 1000000 + extra for smart contract call
    Data: "ESDTNFTTransfer" +
          "@" + <collection identifier in hexadecimal encoding> +
          "@" + <the nonce after the NFT creation in hexadecimal encoding> +
          "@" + <quantity to transfer in hexadecimal encoding> +
          "@" + <destination address 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> +
          <...>
}
fob/laboratoare/04.1668086651.txt.gz · Last modified: 2022/11/10 15:24 by costin.carabas
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0