Smart Assets Distinctions

Motivation

The forthcoming release will include smart assets and trading for smart accounts. This post is intended to highlight the distinctions that smart assets have.

Asset supported transactions

The following transaction types are validated by smart assets’ scripts:

  • TransferTransaction
  • ReissueTransaction
  • BurnTransaction
  • ExchangeTransaction
  • MassTransferTransaction
  • SetAssetScriptTransaction

The following transaction types are not validated by smart assets’ scripts:

  • IssueTransaction

An asset that is already issued cannot be issued again, so validating IssueTransactions by smart asset’s script doesn’t make sense.

  • SetSponsorshipTransaction

Sponsorship of smart assets was prohibited due to the fact that sponsorship actually allows you to transfer an asset to its issuer without executing the script, so it causes transfer of assets that is not validated by the script. Alternatively, if the script will validate this, it is not clear exactly how and with what branch. However, when an asset issuer sets sponsorship to the asset, they may foresee this situation. Therefore, smart asset sponsorship can be allowed, if necessary.

  • LeaseTransaction, LeaseCancelTransaction, AliasTransaction, DataTransaction, SetScriptTransaction

These transactions don’t involve any assets.

Access to proofs from scripts

Access to proofs from smart assets’ scripts is denied in order to guarantee no collisions with processing proofs in smart accounts’ scripts.

For example, if a smart asset’s script requires that all the transactions with this asset had a certain value written in proofs[1], then smart accounts that use multi-signature and refer to proofs[1], are not able use this asset.

Validation in smart trading

Smart accounts’ scripts validate both Orders and ExchangeTransactions. Smart assets’ scripts validate only ExchangeTransactions.

For example, you want to validate Orders that are placed by your account. You shouldn’t be able to filter counter-orders, because they are placed by someone else. Because of that an “order” branch has been made - in this branch you have access to your Order fields only.

You can also validate your ExchangeTransactions with your account’s script but in that case, the validation will have a different meaning: you will take on the role of a scripted matcher. In this case, you have access to all fields of the transaction, including the orders.

The smart assets’ scripts validate ExchangeTransactions but not Orders. There is no need to restrict access to a counter-order because the order does not belong to an asset. Moreover, the asset is present in both orders (asset pairs in both orders are the same), and there is no need to validate each of these orders separately with an asset script.

Fee Calculation Rules for Trading

If an asset pair contains a smart asset then the fee is increased by + 0.004 (+0.008 if both assets are smart). It doesn’t matter if any of the accounts is a smart account, smart accounts pay in the same way as non-smart accounts do.

Asset Pair Fee
Asset / Asset 0.003
Asset / Smart asset 0.003 + 0.004 = 0.007
Smart asset / Smart asset 0.003 + 0.008 = 0.011

This fee is paid to the matcher by every account that is placing an order. The same fee is paid by the matcher when an ExchangeTransaction is put into the blockchain.

If an ExchangeTransaction’s sender (the matcher or any other account) has a script then the total fee for the transaction is increased by 0.004 waves.

Example

Let’s consider an exchange of two smart assets:


Alice and Bob (both have smart accounts) place their orders to the matcher (the matcher has its own script). When the two orders have matched, the matcher creates an ExchangeTransaction and tries to put it into the blockchain.

In this case, the following validations are performed:

  1. Matcher validates Order1
  • with scriptAlice (case Order => )
  • with assetScriptA (case ExchangeTransaction => )*
  • with assetScriptB (case ExchangeTransaction => )*
  1. Matcher validates Order2
  • with scriptBob (case Order => )
  • with assetScriptA (case ExchangeTransaction => )*
  • with assetScriptB (case ExchangeTransaction => )*
  1. Node validates ExchangeTransaction
  • with scriptMatcher (case ExchangeTransaction => )
  • with assetScriptA (case ExchangeTransaction => )
  • with assetScriptB (case ExchangeTransaction => )
  • validates ExchangeTransaction.buyOrder with scriptAlice (case Order => )
  • validates ExchangeTransaction.sellOrder with scriptBob (case Order => )

*Matcher validates Orders by the assets’ scripts as follows: the matcher creates an auxiliary counter-order, puts the two orders to an ExchangeTransaction and validates this transaction via the assets scripts’ “case tx: ExchangeTx => …” branches.

As a result, for the Orders placement Alice pays fee=0.011 waves to the matcher, Bob pays fee=0.011 waves to the matcher. When the ExchangeTransaction is being put into the blockchain, the fee payed by the matcher is 0.011+0.004(because of the matcher’s script)=0.015 waves.

5 Likes

Boa noite!
Já tenho um ativo emitido, consigo fazer o congelamento de uma determinada quantidade do ativo?

Hi,

If you issued an asset with a script then you’re able to change the script later (if the asset’s script allows this).

If your asset doesn’t have a script then you can’t add a script to the asset.

1 Like

Ok, obrigado.

Meu ativo é sem script

Hi @dkiselev,

I would love to have the functionality of sponsoring smart assets. I know that sponsoring causes an extra asset transfer to the issuer (which I don’t know it’ll be checked by the asset script if so), but the issuer should know this when creating a smart asset (for example if they have a whitelist for receiving the smart asset). I think the feeAssetId should be checked too, because it still is an asset transfer, and this would be a big plus. I actually need this for two projects.

right now there are sponsored assets that are misused by spammers, doing cheap airdrops. If we can check the feeAssetId in the asset script together with the assetId (both since checking script when smart asset is feeAssetId too) we can limit the usage of sponsoring to certain assets. This function is very wanted by some projects.

if the asset script isn’t triggered and checked on feeAssetId, it will only be checked when sending the asset itself, therefor sponsored assets still can be used for spamdrops.

Having sponsored assets with the feeAssetId trigger functionality would be a big plus for new projects on waves, since they actually can create an own economy build on waves, and still paying waves fees for those transactions.

3 Likes

Hi @w0utje ,

Thanks for your feedback, we really appreciate it.

We see the interest that the community shows in sponsored smart assets, and now we are considering the possibility of including this functionality in one of the next releases.

1 Like

awesome. you guys are the best :grin:

1 Like

thanks, very helpful!

1 Like

Can anyone explain more detail of “auxiliary counter-order” to me?
Thanks!

It is an original order’s copy with the opposite order type: if the order is BuyOrder then the counter-order will be SellOrder and vice versa, all other fields are the same.

2 Likes

Hi @dkiselev
After the matcher creates an auxiliary counter-order, and then puts the two orders to an ExchangeTransaction
=> so this transaction has field “sender” is matcher address?
Thanks

I want to send the waves that come into the smart wallet evenly on two separate wallets. Can you help with script

@ngocdv,
Yes, this transaction has matcher address as “sender”.

1 Like

@mngrcoin, this will be possible with RIDE4DApps which will be released soon.

1 Like

As to this text "case Order => " for scriptAlice verified twice on steps 1 and 3. And "Case ExchangeTransaction => " never. Is that correct? Or it should be revised for:
“* validates ExchangeTransaction.buyOrder with scriptAlice (case ExchangeTransaction => )”?

Matcher pre-validates orders before putting transactions into the blockchain. So this validation is made by both matcher and node.

Then could you help me with the script?

let verified = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)

match (tx) {
case tr : TransferTransaction => 
        let this = tr.sender
        let accountbalance = wavesBalance(this)
        let txheight = extract(getInteger(this, "txheight"))
        let minbalance =  extract(getInteger(this, "bal"))
        if (accountbalance < minbalance) then throw("Low balance") 
        else if (height < txheight) then throw("Transfer not allowed on this height") 
        else verified

case or : Order => 
        let this = or.sender
        let accountbalance = wavesBalance(this)
        let txheight = extract(getInteger(this, "txheight"))
        let minbalance =  extract(getInteger(this, "bal"))
        if (accountbalance < minbalance) then throw("Low balance") 
        else if (height < txheight) then throw("Trading not allowed on this height") 
        else verified

case other : DataTransaction | SetScriptTransaction | ExchangeTransaction => 
        verified

case _ => throw()
}

There is no problems verifying transfer transaction. But while making order I get “Function getInteger is inaccessible when running script on matcher”.
If I do another way:

let verified = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)

match (tx) {
case tr : TransferTransaction => 
        let this = tr.sender
        let accountbalance = wavesBalance(this)
        if (accountbalance < 100000000) then throw("Low balance") 
        else verified

case or : Order => 
        let this = or.sender
        let accountbalance = wavesBalance(this)
        if (accountbalance < 100000000) then throw("Low balance") 
        else verified

case other : DataTransaction | SetScriptTransaction | ExchangeTransaction => 
        verified

case _ => throw()
}

then i get “function ‘User(wavesBalance)’ not found”.
Can’t I verify orders using functions wavesBalance and getInteger?

Waves matcher validates transactions in the limited context. Functions that get data from the current blockchain state are not accessible for validation on matcher:

  • Get transactions from state (transactionById, transactionHeightById)
  • Get data from state (getInteger, getBoolean, getBinary, getString)
  • Generate addresses (addressFromPublicKey, addressFromString, addressFromRecipient)
  • Get balances (assetBalance, wavesBalance)