Agora analizaremos os activos intelixentes e varios casos do seu uso, incluíndo a conxelación de activos e a creación de restricións nas transaccións en enderezos especificados.
Waves Smart Assets permite aos usuarios superpoñer scripts en activos, seguindo a mesma mecánica que as Smart Accounts. Cada nova transacción creada mediante un activo intelixente será confirmada primeiro polo script e só despois pola cadea de bloques.
Paga a pena sinalar as seguintes diferenzas entre os activos intelixentes e as contas intelixentes:
No código dun activo intelixente, é imposible comprobar as probas (falamos delas no primeiro artigo).
No código de conta intelixente, só pode comprobar ExchangeTransaction se a súa conta é unha conta de coincidencia. En caso contrario, só se verifica a orde. No código de activo intelixente, non pode comprobar a orde directamente; pode comprobar a Transacción de Exchange e, se é necesario, extraer unha orde dela.
Un activo intelixente, a diferenza dunha conta intelixente, non ten un estado, pero aínda temos acceso aos estados da conta desde o script.
Os activos intelixentes simplifican moito a redacción de contratos, facendo que a implementación de moitos casos sexa concisa e elegante.
Conxelación de activos
Para conxelar os activos a unha determinada altura de bloque Altura obxectivo, pode simplemente establecer este valor no script do seguinte activo intelixente:
let targetHeight = 1500000
height >= targetHeight
height - функция языка, возращающая текущую высоту.
Condición específica do emparejador
Para establecer unha coincidencia específica como a desexada, pode definir o seu enderezo como remitente nun script de activos intelixentes que teña o seguinte aspecto:
match tx {
case t : ExchangeTransaction =>
t.sender == addressFromString("3PJaDyprvekvPXPuAtxrapacuDJopgJRaU3")
case _ => true
}
"Lista branca" de destinatarios
Para permitir que os tokens se envíen só a determinadas contas, para crear unha "lista branca" de destinatarios, pode utilizar un activo intelixente co seguinte esquema que verifica a súa inclusión na lista:
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
}
Por razóns de seguridade e a integridade demostrable da linguaxe, a lista non contén unha implementación de iterador. Polo tanto defínese como un conxunto de elementos concretos.
"Lista negra" de destinatarios
Do mesmo xeito, para prohibir o envío de tokens a determinadas contas, pode crear unha "lista negra". Neste caso, úsase exactamente o mesmo activo intelixente, pero co enderezo marcado para garantir que non estea na lista negra:
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
}
Envío con permiso do emisor
Usando un activo intelixente, tamén pode configurar a opción de enviar un activo intelixente só co permiso do emisor (etiqueta de compromiso/débeda). O emisor expresa o seu consentimento colocando o ID da transacción no estado da súa conta:
match tx {
case t : TransferTransaction =>
let issuer = extract(addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4"))
#убеждаемся, что в стейте эмитента содержится ID текущей транзакции
isDefined(getInteger(issuer, toBase58String(t.id)))
case _ => false
}
Cambia só por determinadas moedas
Un activo intelixente permite o permiso para cambialo só por determinadas moedas. Por exemplo, para permitir só o intercambio de Bitcoins, podes usar o seguinte código:
let BTCId = base58'8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS'
match tx {
case t : ExchangeTransaction =>
t.sellOrder.assetPair.priceAsset == BTCId ||
t.sellOrder.assetPair.amountAsset == BTCId
case _ => true
}
Comercio por prezo do oráculo
No script de activos intelixentes, pode establecer o permiso para negociar só ao prezo fixado no estado dun oráculo fiable. Aquí tes un exemplo dese guión:
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
}
Aquí estamos ante un punto non obvio ao comprobar a identificación do activo co que se realiza a negociación. A cuestión é que se o ID do activo non está definido, estamos a falar de WAVES. No guión, asegurámonos de que a negociación se realice en conxunto con WAVES, exactamente deste xeito.
Aumento do prezo fixo
Podes establecer un prezo fixo para un activo intelixente, que aumentará paso a paso nunha proporción determinada. Aquí tes un exemplo dun script de activos cuxo prezo aumentará un 5 % cada 1000 bloques:
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
}
Intervalo de negociación
Ademais, grazas ao script, a negociación dun activo intelixente pode limitarse a intervalos predeterminados. Aquí tes un exemplo dese guión:
let startHeight = 10000
let interval = 44000
let limit = 1500
match tx {
case t: TransferTransaction | MassTransferTransaction | ExchangeTransaction =>
(height - startHeight) % interval < limit
case _ => true
}
No guión asegurámonos de que desde o inicio da negociación Altura inicial non máis que limitar intervalos. A lonxitude do intervalo é igual ao número de bloques especificado no campo intervalo.