logo
back
back
Back

Using dApps, Smart account and smart asset, you can implement various blockchain-empowered applications: gaming and gambling, DeFi, digital identity, supply chains, and many others

Create dAppdAppdApp

dApp is Waves account assigned with dApp script created for using Smart-contracts in WAVES. dApp script is a Ride script that contains callable functions that can be called externally by the Waves transactions

More info
gradient
img
img

Create Your First DApp In One Step In WAVES IDE

Say "Hello World" in WAVES Network

arrow
plus

Create your first Dapp

Step 1

Directives

Each Ride script should start with directives. These directives tell the compiler that:

< The script uses Standard library version 5 >
< Type of the script is dApp >
< The script will be assigned to an account >
ride
Copy
1
2
3
{-# STDLIB_VERSION 6 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}

Callable functions

Callable function can be called externally by the invoke script transaction

Callable function result is a set of script actions that are performed on the blockchain

ride
Copy
1
2
3
4
5
6
@Callable(i)
func helloWorld(name: String) = {
    [
        StringEntry("answer", "Hello World! Hello, " + name)
    ]
}

Add script into your project

It s much easier than you imagine. Say "Hello World" in WAVES Network Insert this script into your project

New project IDE
ride
Copy
1
2
3
4
5
6
7
8
9
{-# STDLIB_VERSION 6 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
@Callable(i)
func helloWorld(name: String) = {
    [
        StringEntry("answer", "Hello World! Hello, " + name)
    ]
}
arrow
plus

Deploy

Step 2

deploy
deploy
deploy

Deploy your script into Waves Network

deploy
deploy
deploy

During deployment you'll need to create your account if you still haven't it

arrow
plus

Run test

Step 3

// Run test with help of Surfboard

ride
Copy
1
2
3
4
5
6
const WAVES = 10 ** 8;
const FEE = 0.001 * WAVES;
const ADD_FEE = 0.004 * WAVES;

describe('HelloWorld dApp test suite', async function () {
    this.timeout(100000);

// In the before section, we perform all the actions that we need to test the dApp and certain number of accounts with the specified balance is generated

ride
Copy
1
2
3
4
before(async function () {
    await setupAccounts({
        dApp: 10 * WAVES,
    });

//Deployment is carried out by the transaction of installing the script on the account

ride
Copy
1
2
3
4
5
const dAppScript = compile(file('dApp.ride'));
    const ssDAppTx = setScript({ script: dAppScript }, accounts.dApp);
    await broadcast(ssDAppTx);
    await waitForTx(ssDAppTx.id);
});

//Each section of it() serves to test some functionality

ride
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
it('Should say hello', async function () {
    const name = "Alex";

    const iInitTx = invokeScript({
        fee: FEE + ADD_FEE,
        dApp: address(accounts.dApp),
        call: {
            function: "helloWorld",
            args: [
                { type: 'string', value: name },
            ]
        },
    }, accounts.dApp);
    await broadcast(iInitTx);
    await waitForTx(iInitTx.id);

//Call of the script function is carried out by the invokeScript transaction

ride
Copy
1
2
3
4
const result = await accountDataByKey("answer", address(accounts.dApp))
        expect(result.value).to.be.equal("Hello World! Hello, " + name);
    });
})

//In the end, we read the account data by key and check the correctness of the saved data

ride
Copy
1
2
3
4
const result = await accountDataByKey("answer", address(accounts.dApp))
        expect(result.value).to.be.equal("Hello World! Hello, " + name);
    });
})

Also you can run test by using InvokeScript transaction

//An example of a function call from dApp

java
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import com.wavesplatform.crypto.Crypto;
import com.wavesplatform.transactions.InvokeScriptTransaction;
import com.wavesplatform.transactions.SetScriptTransaction;
import com.wavesplatform.transactions.TransferTransaction;
import com.wavesplatform.transactions.account.PrivateKey;
import com.wavesplatform.transactions.common.Amount;
import com.wavesplatform.transactions.common.Base64String;
import com.wavesplatform.transactions.data.DataEntry;
import com.wavesplatform.transactions.invocation.Function;
import com.wavesplatform.transactions.invocation.StringArg;
import com.wavesplatform.wavesj.Node;
import com.wavesplatform.wavesj.Profile;
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 DappTest {

    static PrivateKey dApp;

    static Node node;

    static Base64String dAppScript;

    // 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");

    // In "Before section", we perform all the actions that we need to test the dApp
    @BeforeClass
    public static void before() throws NodeException, IOException {
        node = new Node(Profile.LOCAL);

        // Certain number of accounts with the specified balance is generated
        dApp = PrivateKey.fromSeed(Crypto.getRandomSeedBytes());
        TransferTransaction transfer = TransferTransaction.builder(
            dApp.address(), Amount.of(1_00_000_000)
        ).getSignedWith(faucet);
        node.broadcast(transfer);
        node.waitForTransaction(transfer.id());

        // Deployment is carried out by the transaction of installing the script on the account
        String source = Files.readString(new File("src/test/resources/dApp.ride"));
        dAppScript = node.compileScript(source).script();
        SetScriptTransaction ssTx = SetScriptTransaction.builder(dAppScript).getSignedWith(dApp);
        node.broadcast(ssTx);
        node.waitForTransaction(ssTx.id());
    }

    @Test
    public void should_say_hello() throws NodeException, IOException {
        String name = "Alex";

        // Call of the script function is carried out by the invokeScript transaction
        InvokeScriptTransaction iInitTx = InvokeScriptTransaction.builder(
            dApp.address(),
            Function.as("helloWorld", StringArg.as(name))
        ).getSignedWith(dApp);
        node.broadcast(iInitTx);
        node.waitForTransaction(iInitTx.id());

        // At the end, some checks are usually made.
        // In this case, we read the account data by key and check the correctness of the saved data
        DataEntry result = node.getData(dApp.address(), "answer");
        Assert.assertEquals(result.valueAsObject(), "Hello World! Hello, " + name);
    }
}

Congragulations!

You've been created your first dApp successfully. It has been published on the Waves.

Still have questions?

Lets

Keep in touchKeep in touchKeep in touch

Learn about new infrastructure products, libraries, and new solutions for easy blockchain work