waves_logo Docs
  • Overview
    Overview
  • How-to Guides
    • Reading Blockchain Data
      Reading Blockchain Data
    • Creating & Broadcasting Transactions
      Creating & Broadcasting Transactions
    • Tokenization
      Tokenization
    • Airdrop
      Airdrop
    • Payments
      Payments
    • Exchange Tokens
      Exchange Tokens
    • Simple Voting
      Simple Voting
    • List as argument
      List as argument
    How-to Guides
  • Waves Smart Contracts
    Waves Smart Contracts
  • dApp
    • Creating & Launching dApp
      Creating & Launching dApp
    dApp
  • Smart Account
    • Creating smart account
      Creating smart account
    • Creating and deploying a script manually
      Creating and deploying a script manually
    • Video tutorials
      • Introduction to the Waves blockchain, Waves Smart Accounts and Waves Smart Assets
        Introduction to the Waves blockchain, Waves Smart Accounts and Waves Smart Assets
      • Waves Smart Account with multisignature
        Waves Smart Account with multisignature
      • Waves Smart Account with escrow service
        Waves Smart Account with escrow service
      • Creating multisignature account via Waves IDE tools
        Creating multisignature account via Waves IDE tools
      • Creating multisignature account via Waves Client
        Creating multisignature account via Waves Client
      • Waves console explained
        Waves console explained
      Video tutorials
    Smart Account
  • Smart Asset
    Smart Asset
  • Developer Tools
    • Waves IDE
      Waves IDE
    • Visual Studio Code Extension
      Visual Studio Code Extension
    • Surfboard
      Surfboard
    • Ride REPL
      Ride REPL
    Developer Tools
  • Signer ◆
    Signer ◆
  • Waves API
    • Data Service API
      Data Service API
    • Node REST API
      Node REST API
    • Node gRPC Server
      Node gRPC Server
    • Blockchain Updates
      Blockchain Updates
    Waves API
  • Client Libraries
    • Waves C#
      • Install SDK
        Install SDK
      • Run Code Sample
        • Send Transactions
          Send Transactions
        • Use Crypto Utilities
          Use Crypto Utilities
        • Interact With Node
          Interact With Node
        • Set Up Smart Contracts
          Set Up Smart Contracts
        Run Code Sample
      Waves C#
    • Gowaves
      • Install SDK
        Install SDK
      Gowaves
    • WavesJ
      • Install SDK
        Install SDK
      WavesJ
    • Ts-lib-crypto
      • Install SDK
        Install SDK
      Ts-lib-crypto
    • Waves-PHP
      • Install SDK
        Install SDK
      Waves-PHP
    • Waves-python
      • Install SDK
        Install SDK
      Waves-python
    • Waves-rust
      • Install SDK
        Install SDK
      Waves-rust
    Client Libraries
      • English
      • Русский
      On this page
        • Asset Script
        • Examples of Using Smart Asset
          • Freeze Token
          • Unburnable token
          • Fee in Sponsored Asset
          • Recipient Allowlist/Denylist
          • Trade Only against BTC
          • Trade at Given Price
        • Creating Smart Asset
        • Modifying Smart Asset Script
        • Smart Asset Fees
        • Waves Tech Blog Articles
      waves_logo Docs

          # What is Smart Asset

          Any user can create their own token on the Waves blockchain and also set the rules for its circulation by assigning a script to it. For example, for in-game currency, you can allow only transactions between characters with certain properties. A token with an assigned script is called a smart asset, and the assigned script is called an asset script.

          # Asset Script

          Asset script checks transactions involving the asset against the specified conditions. The script contains a logical expression. Possible results of the expression calculation are:

          • true: the transaction is allowed,
          • false: the transaction is denied,
          • error: the transaction is denied.

          If the asset script denied the transaction, it can either be discarded or saved on the blockchain as failed. If the transaction is saved as failed, the sender is charged a fee and no further changes are made on the blockchain. See the Transaction Validation article for details.

          Using the match ... case operator, you can set up different conditions depending on the type of the transaction.

          An asset script can use blockchain data: the current height, account balances, entries in account data storages, parameters of the asset itself and other tokens. The script also has access to the fields of the current transaction, except proofs.

          More about the format and features of the asset script

          # Examples of Using Smart Asset

          # Freeze Token

          Transactions with a smart asset can be prohibited until (or after) the moment when the blockchain reaches a certain height.

          {-# STDLIB_VERSION 8 #-}
          {-# CONTENT_TYPE EXPRESSION #-}
          {-# SCRIPT_TYPE ASSET #-}
          
          let targetHeight = 100500
          height >= targetHeight
          

          # Unburnable token

          For the smart asset in the example, Burn transactions are prohibited.

          {-# STDLIB_VERSION 8 #-}
          {-# CONTENT_TYPE EXPRESSION #-}
          {-# SCRIPT_TYPE ASSET #-}
          
          match tx {
            case t : BurnTransaction => false
             case _ => true
          }
          

          # Fee in Sponsored Asset

          The following script allows transfers of the smart asset only if the fee for the Transfer transaction is specified in the sponsored asset R9yNZwP1VkUksacNjtLqua6CePGGX9dYwBEj2TyjYkv. The same condition applies to Invoke Script transactions that contain a payment in the smart asset.

          The transaction fee in the sponsored asset means that the sponsor receives the fee in the sponsored asset from the account of the transaction's sender. The equivalent amount of WAVES is charged from the sponsor's account in favor of block generators. The sponsor can sell the sponsored asset to users at a higher price and thus make a profit. More about sponsorship

          The following script also denied Mass Transfer transactions, because the sponsored fee is not allowed for this type of transactions.

          {-# STDLIB_VERSION 8 #-}
          {-# CONTENT_TYPE EXPRESSION #-}
          {-# SCRIPT_TYPE ASSET #-}
          
          match tx {
             case t : TransferTransaction|InvokeScriptTransaction =>
                t.feeAssetId == base58'R9yNZwP1VkUksacNjtLqua6CePGGX9dYwBEj2TyjYkv'
             case m : MassTransferTransaction => false
             case _ => true
          }
          

          # Recipient Allowlist/Denylist

          Transfer of a smart asset can be prohibited to specified addresses or, conversely, allowed only to specified addresses.

          In this script, the list of allowed addresses is stored on the account 3MsuUWABLwFDU4FY5n1zHqbDYnPUspJHeuF in the following format: entry key is an allowed address, value is true.

          {-# STDLIB_VERSION 8 #-}
          {-# CONTENT_TYPE EXPRESSION #-}
          {-# SCRIPT_TYPE ASSET #-}
          
          match tx {
             case t : TransferTransaction =>
                let allowlist = Address(base58'3MsuUWABLwFDU4FY5n1zHqbDYnPUspJHeuF')
                # Checking that the allowlist contains the recipient's address
                getBooleanValue(allowlist,toBase58String(addressFromRecipient(t.recipient).bytes))
             case _ => false
          }
          

          # Trade Only against BTC

          ⚠️ Buying and selling smart assets on the WX Network exchange developed by the third-party team from the community is temporarily unavailable.

          An asset script cannot check an order directly, but when checking an Exchange transaction the script can use parameters of orders as a part of the transaction.

          A smart asset with the script below can only be bought or sold for BTC.

          {-# STDLIB_VERSION 8 #-}
          {-# CONTENT_TYPE EXPRESSION #-}
          {-# SCRIPT_TYPE ASSET #-}
          
          let BTCId = base58'8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS'
          match tx {
             case e : ExchangeTransaction =>
               e.sellOrder.assetPair.priceAsset == BTCId || e.sellOrder.assetPair.amountAsset == BTCId
             case _ => true
          }
          

          # Trade at Given Price

          ⚠️ Buying and selling smart assets on the WX Network exchange developed by the third-party team from the community is temporarily unavailable.

          An asset script can allow exchanges only at the price specified in the oracle.

          In the example below, the account 3MqBeuDhyc9Zr5MM54CtYm7PivApGEYrEDB serves as an oracle. Its data storage contains token prices: entry key is the token ID, value is the token price in WAVES.

          The smart asset ID can be obtained through the built-in variable this. In the asset script, this is the Asset structure containing parameters of the asset to which this script is assigned.

          {-# STDLIB_VERSION 8 #-}
          {-# CONTENT_TYPE EXPRESSION #-}
          {-# SCRIPT_TYPE ASSET #-}
          
          let oracle = Address(base58'3MqBeuDhyc9Zr5MM54CtYm7PivApGEYrEDB')
          
          match tx {
            # Prohibiting transfers of the asset
            case t: TransferTransaction | MassTransferTransaction | InvokeScriptTransaction =>
              false
            case e: ExchangeTransaction =>
              # Checking that trading is at the price fixed in the oracle's state for this asset
              let correctPrice = e.price == getIntegerValue(oracle, toBase58String(this.id))
              # Checking that the exchange is for WAVES
              # If the asset’s ID is not defined, it is WAVES by default
              let correctPriceAsset = !isDefined(e.sellOrder.assetPair.priceAsset)
              correctPrice && correctPriceAsset
            case _ => true
          }
          

          # Creating Smart Asset

          ⚠️ Please note:

          • If a token is issued without a script, then the script cannot be added later. However, you can issue a token with the script that always returns true and change the script later.
          • Smart asset cannot be sponsored.

          To create a smart asset, you have to send an Issue transaction version 2 or higher that contains the compiled script in base64. It is most convenient to do this in Waves IDE , see instructions in the Issuing Smart Asset section. The minimum fee for this type of transaction is 1 WAVES.

          # Modifying Smart Asset Script

          The Set Asset Script transaction is intended for changing the script. The minimum transaction fee is 1 WAVES.

          Only the account that issued the smart asset can change the script, and only if the asset script itself allows the transaction (as well as the account script of issuer allows the transaction).

          For example, the following script prohibits all types of transactions except for Transfer transactions, so it is impossible to change such a script.

          {-# STDLIB_VERSION 8 #-}
          {-# CONTENT_TYPE EXPRESSION #-}
          {-# SCRIPT_TYPE ASSET #-}
          
          match tx {
            case t : TransferTransaction => true
            case _ => false
          }
          

          The script cannot be removed, so it is impossible to turn a smart asset into a regular one. However, you can set a script that always returns true, that is, allows all transactions.

          # Smart Asset Fees

          The minimum fee for transaction is increased by 0.004 WAVES for each smart asset involved, except for:

          • Invoke Script transactions,
          • smart assets used as matcher fee in Exchange transaction.

          Examples:

          • The minimum fee for a Transfer transaction is 0.001 WAVES; in case of transferring a smart asset, 0.005 WAVES.
          • The minimum fee for an Exchange transaction is 0.003 WAVES. In case of exchanging a smart asset for a regular asset the minimum fee is 0.007 WAVES, exchanging of two smart assets — 0.011 WAVES. (The fee for the Exchange transaction is paid by the matcher. See the Exchange Transaction article for details.)

          ⚠️ Buying and selling smart assets on the WX Network exchange developed by the third-party team from the community is temporarily unavailable.

          # Waves Tech Blog Articles

          • Waves Smart Asset Applications: Whitelists, Blacklists and Interval Trading (Mar 21, 2019)
          • Application of Waves Smart Accounts and Smart Assets for Financial Instruments (Mar 15, 2019)
          Waves console explained
          Developer Tools
          Waves console explained
          Developer Tools