How to build, deploy and test the Waves RIDE dApp

Hello! In this article, I will show you how to write and run a regular dApp on a Waves node. Consider the necessary tools, methods and development example.

How to build, deploy and test the Waves RIDE dApp

The scheme for developing dApps and ordinary applications is almost the same:

  • We write the code
  • Writing automated testing
  • Run the application
  • We are testing

Tools

1. docker to run the node and Waves Explorer

If you don't want to run a node, you can skip this step. After all, there is a test and experimental network. But without deploying your own node, the testing process can be delayed.

  • You will constantly need new accounts with test tokens. The testnet faucet transfers 10 WAVES every 10 minutes.
  • The average block time in the test network is 1 minute, in the node - 15 seconds. This is especially noticeable when a transaction requires multiple confirmations.
  • Aggressive caching is possible in public test nodes.
  • They may also be temporarily unavailable due to maintenance.

Further, I will assume that you are working with your node.

2. Surfboard Command Line Tool

  • Download and install Node.js using ppa, homebrew or exe here: https://nodejs.org/en/download/.
  • Install Surfboard, a tool that will allow you to run tests on an existing node.

npm install -g @waves/surfboard

3. Visual Studio Code Plugin

This step is optional if you are not an IDE fan and prefer text editors. All the necessary tools are command line utilities. If you are using vim, check out the plugin vim-ride.

Download and install Visual Studio Code: https://code.visualstudio.com/

Open VS Code and install the waves-ride plugin:

How to build, deploy and test the Waves RIDE dApp

Waves Keeper Browser Extension: https://wavesplatform.com/products-keeper

Done!

Launch the node and Waves Explorer

1. Run the node:

docker run -d -p 6869:6869 wavesplatform/waves-private-node

Make sure the node is started via the REST API in http://localhost:6869:

How to build, deploy and test the Waves RIDE dApp
Swagger REST API for Node

2. Launch an instance of Waves Explorer:

docker run -d -e API_NODE_URL=http://localhost:6869 -e NODE_LIST=http://localhost:6869 -p 3000:8080 wavesplatform/explorer

Open a browser and go to http://localhost:3000. See how quickly an empty local node chain is built.

How to build, deploy and test the Waves RIDE dApp
Waves Explorer displays local node instance

RIDE structure and Surfboard tool

Create an empty directory and run the command in it

surfboard init

The command initializes the directory with the project structure, hello world applications and tests. If you open this folder with VS Code, you will see:

How to build, deploy and test the Waves RIDE dApp
Surfboard.config.json

  • Under the ./ride/ folder, you will find a single wallet.ride file - the directory where the dApp code is located. We will briefly analyze dApp in the next block.
  • Under the ./test/ folder you will find the *.js file. This is where tests are stored.
  • ./surfboard.config.json - configuration file for running tests.

Envs is an important section. Each environment is configured like this:

  • The REST API endpoint of the node that will be used to launch the dApp and the CHAIN_ID of the network.
  • Passphrase for the token account that will be the source of your test tokens.

As you can see, surfboard.config.json supports multiple environments by default. By default, the local environment is set (the defaultEnv key is a variable parameter).

Wallet-demo application

This section is not a reference to the RIDE language. Rather, a look at the application that we are deploying and testing in order to better understand what is happening in the blockchain.

Consider a simple Wallet-demo application. Everyone can send tokens to the dApp address. You can withdraw only your own WAVES. Two @Callable functions are available via InvokeScriptTransaction:

  • deposit(), which requires an attached payment in WAVES
  • withdraw(amount: Int), which returns tokens

Throughout the dApp life cycle, the structure (address → amount) will be maintained:

Action
result state

initial
empty

Alice deposits 5 WAVES
alice-address → 500000000

Bob deposits 2 WAVES

alice-address → 500000000
bob-address → 200000000

Bob withdraws 7 WAVES
DENIED!

Alice withdraws 4 WAVES
alice-address → 100000000
bob-address → 200000000

Here is the code to fully understand the situation:

# In this example multiple accounts can deposit their funds and safely take them back. No one can interfere with this.
# An inner state is maintained as mapping `address=>waves`.
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
@Callable(i)
func deposit() = {
 let pmt = extract(i.payment)
 if (isDefined(pmt.assetId))
    then throw("works with waves only")
    else {
     let currentKey = toBase58String(i.caller.bytes)
     let currentAmount = match getInteger(this, currentKey) {
       case a:Int => a
       case _ => 0
     }
     let newAmount = currentAmount + pmt.amount
     WriteSet([DataEntry(currentKey, newAmount)]) 
   }
 }
@Callable(i)
func withdraw(amount: Int) = {
 let currentKey = toBase58String(i.caller.bytes)
 let currentAmount = match getInteger(this, currentKey) {
   case a:Int => a
   case _ => 0
 }
 let newAmount = currentAmount - amount
 if (amount < 0)
   then throw("Can't withdraw negative amount")
   else if (newAmount < 0)
     then throw("Not enough balance")
     else ScriptResult(
       WriteSet([DataEntry(currentKey, newAmount)]),
       TransferSet([ScriptTransfer(i.caller, amount, unit)])
      )
 }
@Verifier(tx)
func verify() = false

Sample code can also be found at GitHub.

The VSCode plugin supports continuous compilation while editing a file. Therefore, you can always watch for errors in the PROBLEMS tab.

How to build, deploy and test the Waves RIDE dApp
If you want to use a different text editor when compiling the file, use

surfboard compile ride/wallet.ride

This will output a base64 string of compiled RIDE code.

Test script for 'wallet.ride'

Let's look at test file. Powered by JavaScript's Mocha framework. There is a "Before" function and three tests:

  • "Before" funds multiple accounts through MassTransferTransaction, compiles the script, and deploys it to the blockchain.
  • "Can deposit" sends an InvokeScriptTransaction to the network, activating the deposit() function for each of the two accounts.
  • "Can't withdraw more than was deposited" tests that no one can steal someone else's tokens.
  • "Can deposit" checks that withdrawals are processed correctly.

Running Tests from Surfboard and Analyzing Results in Waves Explorer

To run the test run

surfboard test

If you have multiple scripts (for example, you need a separate deployment script), you can run

surfboard test my-scenario.js

Surfboard will collect the test files in the ./test/ folder and run the script in the node that is configured in surfboard.config.json. After a few seconds, you will observe something like this:

wallet test suite
Generating accounts with nonce: ce8d86ee
Account generated: foofoofoofoofoofoofoofoofoofoofoo#ce8d86ee - 3M763WgwDhmry95XzafZedf7WoBf5ixMwhX
Account generated: barbarbarbarbarbarbarbarbarbar#ce8d86ee - 3MAi9KhwnaAk5HSHmYPjLRdpCAnsSFpoY2v
Account generated: wallet#ce8d86ee - 3M5r6XYMZPUsRhxbwYf1ypaTB6MNs2Yo1Gb
Accounts successfully funded
Script has been set
   √ Can deposit (4385ms)
   √ Cannot withdraw more than was deposited
   √ Can withdraw (108ms)
3 passing (15s)

Hooray! Tests passed. Now let's take a look at what happens when using the Waves Explorer: look at the blocks or insert one of the above addresses into the search (for example, the corresponding wallet#. There you can find transaction history, dApp state, decompiled binary.

How to build, deploy and test the Waves RIDE dApp
wave explorer. An application that has just been deployed.

A few Surfboard tips:

1. To test in the testnet environment, use:

surfboard test --env=testnet

Get test tokens

2. If you want to see JSON versions of transactions and how they are processed by the node, run the test with -v (meaning 'verbose'):

surfboard test -v

Using apps with Waves Keeper

1. Set up Waves Keeper for work: http://localhost:6869

How to build, deploy and test the Waves RIDE dApp
Setting up Waves Keeper to work with a local node

2. Import your network token passphrase? For simplicity, use the initial seed of your node: waves private node seed with waves tokens. Address: 3M4qwDomRabJKLZxuXhwfqLApQkU592nWxF.

3. You can run a single page serverless application yourself using npm. Or go to an existing one: chrome-ext.wvservices.com/dapp-wallet.html

4. Enter the wallet address from the test run (underlined above) in the dApp address text field

5. Enter a small amount in the "Deposit" field and press the button:

How to build, deploy and test the Waves RIDE dApp
Waves Keeper requests permission to sign an InvokeScriptTransaction with a payment of 10 WAVES.

6. Confirm the transaction:

How to build, deploy and test the Waves RIDE dApp
The transaction is created and broadcast to the network. Now you can see her ID

7. Watch the transaction with Waves Explorer. Enter ID in the search field

How to build, deploy and test the Waves RIDE dApp

Conclusions and additional information

We looked at the tools for developing, testing, deploying and using simple dApps on the Waves Platform:

  • RIDE Language
  • VS Code Editor
  • Waves Explorer
  • surfboard
  • Wave Keeper

Links for those who want to continue learning RIDE:

More examples
Online IDE with examples
Wave Documentation
Telegram developers chat
Waves and RIDE on stackoverflow
NEW! Online courses on creating dApps on the Waves Platform

Keep diving into RIDE and build your first dApp!

TL; DR: bit.ly/2YCFnwY

Source: habr.com

Add a comment