Hello! In the article I will show how to write and run the usual dApp on the Waves node. Consider the necessary tools, methods and design example.
The design of dApps and common applications is almost the same:
')
- Write the code
- We write automated testing
- Run the application
- We are testing
Instruments
1.
docker
to launch nodes and Waves Explorer
If you do not want to run the node, you can skip this step. After all, there is a test and experimental network. But without deploying your node, the testing process can be delayed.
- You will constantly need new accounts with test tokens. The test network crane translates into 10 WAVES every 10 minutes.
- The average time of the blocks in the test network is 1 minute, and 15 seconds in the node. This is especially noticeable when a transaction requires several confirmations.
- In publicly accessible test nodes, aggressive caching is possible.
- They may also be temporarily unavailable due to maintenance.
Next, 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 allows you to run tests on an existing node.
npm install -g @waves/surfboard
3. Visual Studio Code Plugin
The step is optional if you are not an IDE fan and prefer text editors. All the necessary tools are command line utilities. If you use vim, pay attention to the
vim-ride plugin.
Download and install Visual Studio Code:
https://code.visualstudio.com/
Open VS Code and install the waves-ride plugin:
Browser extension Waves Keeper:
https://wavesplatform.com/products-keeper
Done!
Launch node and Waves Explorer
1. Run the node:
docker run -d -p 6869:6869 wavesplatform/waves-private-node
Ensure that the node runs through the REST API at
http: // localhost: 6869 :
Swagger REST API for node
2. Start the Waves Explorer instance:
docker run -d -e API_NODE_URL=http:
Open a browser and go to
http: // localhost: 3000 . See how quickly an empty local node chain is built.
Waves Explorer displays an instance of a local node.
RIDE structure and Surfboard tool
Create an empty directory and execute the command
surfboard init
The command initializes the directory with the project structure, applications like “hello world” and tests. If you open this folder with VS Code, you will see:
Surfboard.config.json
- Under the folder ./ride/ you will find a single file wallet.ride - the directory where the dApp code is located. We will briefly analyze the dApp in the next block.
- Under the folder ./test/ find the file * .js. Here are the tests.
- ./surfboard.config.json - configuration file for running tests.
Envs is an important section. Each environment is configured as follows:
- The endpoint of the REST API node that will be used to run the dApp and CHAIN_ID network.
- The secret phrase for the account with tokens that will be the sources 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, look at the application, which we deploy and test to better understand what is happening in the blockchain.
Consider a simple Wallet-demo application. Anyone can send tokens dApp address. You can display only your WAVES. Two @Callable functions are available via InvokeScriptTransaction:
deposit()
, which requires an attached payment in WAVESwithdraw(amount: Int)
that returns tokens
Throughout the dApp life cycle, the structure (address → amount) will be maintained:
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 on
GitHub .
The VSCode plugin supports continuous compilation when editing a file. Therefore, you can always follow the errors in the PROBLEMS tab.
If you want to use another text editor when compiling a file, use
surfboard compile ride/wallet.ride
This will output a base64 series of compiled RIDE code.
Test script for 'wallet.ride'
Let's look at the
test file . Powered by JavaScript's Mocha framework. There is a “Before” function and three tests:
- “Before” finances several accounts through MassTransferTransaction, compiles the script and deploys it in the blockchain.
- “Can deposit” sends 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" verifies that the withdrawals are processed correctly.
Running tests with Surfboard and analyzing results in the Waves Explorer
To run the test run
surfboard test
If you have several 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, which is configured in surfboard.config.json. After a few seconds, you'll see 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: browse the blocks or insert one of the above addresses into the search (for example, the corresponding
wallet#
. There you can find transaction history, dApp status, decompiled binary file.
Waves Explorer. The application that has just been deployed.
Some tips on surfing:
1. To test in the testnet environment, use:
surfboard test --env=testnet
Get test tokens
2. If you want to see the JSON versions of transactions and how they are processed by the node, run the test with -v (means 'verbose'):
surfboard test -v
Using applications with Waves Keeper
1. Configure Waves Keeper to work:
http: // localhost: 6869
Configuring Waves Keeper to work with a local node
2. Import a secret phrase with tokens for the network? For simplicity, use the initial seed of your node:
waves private node seed with waves tokens
. Address:
3M4qwDomRabJKLZxuXhwfqLApQkU592nWxF
.
3. You can launch a single-page serverless application by yourself using npm. Or go to the 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 box
5. Enter a small amount in the “Deposit” field and click the button:
Waves Keeper is requesting permission to sign an InvokeScriptTransaction with a payment of 10 WAVES.
6. Confirm the transaction:
The transaction is created and transmitted to the network. Now you can see her ID
7. Watch the transaction using the Waves Explorer. Enter ID in the search field
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
- Waves keeper
Links for those who want to continue exploring RIDE:
More examples
Online IDE with examples
Waves Documentation
Developer Chat in Telegram
Waves and RIDE on stackoverflow
NEW! Online dApps courses on the Waves Platform
Keep going into the RIDE theme and create your first dApp!
TL; DR:
bit.ly/2YCFnwY