📜 ⬆️ ⬇️

Waves Smart Assets: Black and White Lists, Interval Trading

image

In the two previous articles, we talked about smart accounts and how they can be used to conduct auctions and create loyalty programs , as well as help ensure the transparency of financial instruments .

Now we will look at smart assets and several cases of their use, including freezing assets and creating restrictions on transactions at specified addresses.

Smart assets Waves allow users to overlay scripts on assets, following the same mechanics as in the case of smart accounts. Each new transaction created using smart asset will be confirmed first by the script, and only then by the blockchain.
')
It is worth noting the following differences between smart assets and smart accounts:

  1. In the smart asset code, you cannot check the proofs (we talked about them in the first article ).
  2. In the smart account code, you can check ExchangeTransaction only if your account is a match account. Otherwise, only the order is checked. You cannot check the order directly in the smart asset code, you can check Exchange Transaction, and from it you can retrieve the order if necessary.
  3. A smart asset, unlike a smart account, does not have a state, but we still have access to the state of accounts from the script.

Smart assets greatly simplify the writing of contracts, making the implementation of many cases concise and elegant.

Asset freeze

To freeze assets to a certain height of the targetHeight block, you can simply set this value in the script of the following smart asset:

let targetHeight = 1500000 height >= targetHeight height -  ,   . 

The specific condition of the matcher

To set a specific matcher as your desired, you can set its address as the sender in the smart asset script of the following form:

 match tx { case t : ExchangeTransaction => t.sender == addressFromString("3PJaDyprvekvPXPuAtxrapacuDJopgJRaU3") case _ => true } 

“White list” of recipients

To allow the sending of tokens only to certain accounts - to create a “white list” of recipients - you can use a smart asset with the following scheme, checking the entry in the list:

 match tx { case t : TransferTransaction => let trustedRecipient1 = addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4") let trustedRecipient2 = addressFromString("3PLZcCJyYQnfWfzhKXRA4rteCQC9J1ewf5K") let trustedRecipient3 = addressFromString("3PHrS6VNPRtUD8MHkfkmELavL8JnGtSq5sx") t.recipient == trustedRecipient1 || t.recipient == trustedRecipient2 || t.recipient == trustedRecipient3 case _ => false } 

For security and demonstrable language completeness, the list does not contain an iterator implementation. Therefore, it is set as a set of specific elements.

Recipient Black List

In the same way, to ban the sending of tokens to certain accounts, you can create a “black list”. It uses exactly the same smart asset, but with checking the address for the absence of the black list:

 match tx { case t : TransferTransaction => let bannedRecipient1 = addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4") let bannedRecipient2 = addressFromString("3PLZcCJyYQnfWfzhKXRA4rteCQC9J1ewf5K") let bannedRecipient3 = addressFromString("3PHrS6VNPRtUD8MHkfkmELavL8JnGtSq5sx") t.recipient != bannedRecipient1 && t.recipient != bannedRecipient2 && t.recipient != bannedRecipient3 case _ => false } 

Sending with permission of the issuer

With the smart asset, you can also set the option to send a smart asset only with the issuer's permission (commitment / debt label ). The issuer expresses its consent by placing the transaction ID in the stack of your account:

 match tx { case t : TransferTransaction => let issuer = extract(addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4")) #,      ID   isDefined(getInteger(issuer, toBase58String(t.id))) case _ => false } 

Exchange only for certain coins

Smart Asset allows permission to exchange it only for certain coins. For example, to allow the exchange only for bitcoins, you can use the following code:

 let BTCId = base58'8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS' match tx { case t : ExchangeTransaction => t.sellOrder.assetPair.priceAsset == BTCId || t.sellOrder.assetPair.amountAsset == BTCId case _ => true } 

Trade at the price of oracle

In the script of the smart asset, you can set the permission to trade only at the price fixed in the stack of a reliable oracle. Here is an example of such a script:

 let oracle = Address(base58'3PLNmokt22NrSiNvCLvwMUP84LCMJqbXwAD') let assetId = toBase58String(base58'oWgJN6YGZFtZrV8BWQ1PGktZikgg7jzGmtm16Ktyvjd') match tx { #   case t: TransferTransaction | MassTransferTransaction => false case e: ExchangeTransaction => #,     ,        let correctPrice = e.price == extract(getInteger(oracle, assetId)) #,       WAVES let correctPriceAsset = !isDefined(e.sellOrder.assetPair.priceAsset) correctPrice && correctPriceAsset case _ => true } 

Here we are faced with an unobvious point when checking the asset ID with which to trade. The fact is that if the asset ID is not defined, then it is a question of WAVES. In the script, we make sure that trading is performed in conjunction with WAVES, in this way.

Fixed price increase

You can set a fixed price for smart asset, which will increase incrementally in a given proportion. Here is an example of an asset script, the price of which will be increased by 5% every 1000 blocks:

 let startPrice = 10 let startHeight = 1000 let interval = 1000 #        let raise = 5 match tx { case t: TransferTransaction | MassTransferTransaction => false case e: ExchangeTransaction => e.price == startPrice + ((height - startHeight) / interval) * (100 + raise) / 100 && !isDefined(e.sellOrder.assetPair.priceAsset) case _ => true } 

Interval Trading

Also, thanks to the script, the trade of smart assets can be limited to predetermined intervals. Here is an example of such a script:

 let startHeight = 10000 let interval = 44000 let limit = 1500 match tx { case t: TransferTransaction | MassTransferTransaction | ExchangeTransaction => (height - startHeight) % interval < limit case _ => true } 

In the script, we are convinced that since the start of trading, startHeight has passed no more than limit intervals. The interval length is equal to the number of blocks specified in the interval field.

Source: https://habr.com/ru/post/444686/


All Articles