The functionality of a WAVES account only allows you to verify that the transaction released from it was actually sent from this account
Smart-asset without burning
Each Ride script should start with directives These directives tell the compiler that:
{-# STDLIB_VERSION 6 #-}
{-# CONTENT_TYPE EXPRESSION #-}
{-# SCRIPT_TYPE ASSET #-}
After the directives, you can define auxiliary variables and functions. The expression checks transactions involving the asset for compliance with the specified conditions. If the conditions are not met, the transaction is denied
match tx {
case t : SetAssetScriptTransaction | BurnTransaction => throw("You can`t set new script or burn token")
case _ => true
}
It's much easier than you imagine. Say "Hello World" in WAVES Network Insert this script into your project
{-# STDLIB_VERSION 6 #-}
{-# CONTENT_TYPE EXPRESSION #-}
{-# SCRIPT_TYPE ASSET #-}
match tx {
case t : SetAssetScriptTransaction | BurnTransaction => throw("You can`t set new script or burn token")
case _ => true
}
Deploy your script into Waves Network
During deployment you'll need to create your account if you still haven't it
// Run test with help of Surfboard
// In the before section, we perform all the actions that we need to test the Smart account and certain number of accounts with the specified balance is generated
describe('Smart-asset test suite', async function () {
const wvs = 10 ** 8;
let curtAssetId;
this.timeout(100000);
before(async function () {
await setupAccounts({
curt: 10 * wvs
});
});
//Deployment is carried out by the transaction of installing the script on the account
accontScript = compile(file('account-script.ride'));
const ssTx = setScript({ script: accontScript }, accounts.user);
await broadcast(ssTx);
await waitForTx(ssTx.id);
const ssTx2 = setScript({ script: accontScript }, accounts.secondUser);
await broadcast(ssTx2);
await waitForTx(ssTx2.id);
console.log('Script has been set')
});
//Each section of it() serves to test some functionality
// Transfer WAVES
it('Should transfer less than 1500', async function () {
const transferTx = transfer({ amount: 1000, recipient: address(accounts.secondUser), fee: 1000000 }, accounts.user);
// Get account effective balance
const userBalanceBefore = await balance(address(accounts.user));
const secondUserBalanceBefore = await balance(address(accounts.secondUser));
await broadcast(transferTx);
await waitForTx(transferTx.id);
const userBalanceAfter = await balance(address(accounts.user));
const secondUserBalanceAfter = await balance(address(accounts.secondUser));
expect(userBalanceBefore).to.be.gt(userBalanceAfter);
expect(secondUserBalanceBefore).to.be.lt(secondUserBalanceAfter);
})
// Trying to make a transfer with an amount that exceeds the limit
it('Should not transfer more than 1000', async function () {
const transferTx = transfer({ amount: 2000, recipient: address(accounts.secondUser), fee: 1000000 }, accounts.user);
expect(broadcast(transferTx)).to.be.rejectedWith("");
})
it('Should not set script again', async function () {
const ssTx = setScript({ script: accontScript, fee: 1500000 }, accounts.user);
expect(broadcast(ssTx)).to.be.rejectedWith("");
})
// Make records to the state as a data transaction to check the standard behavior of the account for other types of transactions
it('Should store data', async function () {
const records = [
{ key: 'integerVal', value: 1 },
{ key: 'booleanVal', value: true },
{ key: 'stringVal', value: 'Lorem ipsum dolor sit amet' }
]
const dataTx = data({ data: records, fee: 1000000 }, accounts.user);
await broadcast(dataTx);
await waitForTx(dataTx.id);
const store = await accountData(address(accounts.user));
expect(store["integerVal"].value).to.be.equal(1);
expect(store["booleanVal"].value).to.be.equal(true);
expect(store["stringVal"].value).to.be.equal('Lorem ipsum dolor sit amet');
})
})
//An example of a function call from dApp
import com.wavesplatform.crypto.Crypto;
import com.wavesplatform.transactions.BurnTransaction;
import com.wavesplatform.transactions.IssueTransaction;
import com.wavesplatform.transactions.SetAssetScriptTransaction;
import com.wavesplatform.transactions.TransferTransaction;
import com.wavesplatform.transactions.account.PrivateKey;
import com.wavesplatform.transactions.common.Amount;
import com.wavesplatform.transactions.common.AssetId;
import com.wavesplatform.transactions.common.Base64String;
import com.wavesplatform.wavesj.Node;
import com.wavesplatform.wavesj.Profile;
import com.wavesplatform.wavesj.ScriptInfo;
import com.wavesplatform.wavesj.exceptions.NodeException;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.web3j.utils.Files;
import java.io.File;
import java.io.IOException;
public class AssetScriptTest {
static Node node;
static PrivateKey curt;
// additional info can be found - https://hub.docker.com/r/wavesplatform/waves-private-node
static PrivateKey faucet = PrivateKey.fromSeed("waves private node seed with waves tokens");
static int errorCode = 306;
// In the before section, we perform all the actions that we need to test scripts
@BeforeClass
public static void before() throws NodeException, IOException {
node = new Node(Profile.LOCAL);
// A certain number of accounts with the specified balance is generated
curt = PrivateKey.fromSeed(Crypto.getRandomSeedBytes());
TransferTransaction transfer1 = TransferTransaction.builder(
curt.address(), Amount.of(10_00_000_000)
).getSignedWith(faucet);
node.broadcast(transfer1);
node.waitForTransaction(transfer1.id());
}
@Test
public void test() throws NodeException, IOException {
//Should issue smart-asset with quantity 100_000_000'
// Specify the parameters of the smart asset (at this stage, a stub is installed as a script,
// which is equal "true")
IssueTransaction issueTx = IssueTransaction.builder(
"mySmartToken",
100_000_000,
8
)
.isReissuable(true)
.description("some desc")
.script(new Base64String("AQa3b8tH"))
.getSignedWith(curt);
AssetId curtAssetId = node.broadcast(issueTx).assetId();
node.waitForTransaction(issueTx.id());
// Check the balance of the token on the account - all the tokens of the issuing account
long total = node.getAssetBalance(curt.address(), curtAssetId);
Assert.assertEquals(issueTx.quantity(), total);
// Should set real script and try to change script
// Compiling the Smart Asset Script
String source = Files.readString(new File("src/test/resources/smart-asset-script.ride"));
ScriptInfo assetScript = node.compileScript(source);
// Install the script on the smart asset (already allowed to do this)
SetAssetScriptTransaction sasTx = SetAssetScriptTransaction.builder(
curtAssetId, assetScript.script()
).getSignedWith(curt);
node.broadcast(sasTx);
node.waitForTransaction(sasTx.id());
// Try to change the smart asset script again, get an errornode.waitForTransaction(sasTx.id());
SetAssetScriptTransaction sasTx2 = SetAssetScriptTransaction.builder(
curtAssetId, assetScript.script()
).getSignedWith(curt);
try {
node.broadcast(sasTx2);
} catch (NodeException nodeException) {
Assert.assertEquals(errorCode, nodeException.getErrorCode());
}
//Should try burn some curtAsset
// Trying to burn a certain number of tokens - get an error, because the script forbids from such actions with the asset
BurnTransaction bTx = BurnTransaction.builder(Amount.of(100, curtAssetId))
.extraFee(400000)
.getSignedWith(curt);
try {
node.broadcast(bTx);
} catch (NodeException nodeException) {
Assert.assertEquals(errorCode, nodeException.getErrorCode());
}
}
}
You've been created your first dApp successfully. It has been published on the Waves.