DERO Virtual Machine (DVM)
DERO Virtual Machine represents the entire DERO Smart Contracts eco-system which runs on the DERO blockchain.
DVM is a decentralized platform that runs smart contracts: applications that run exactly as programmed without any possibility of downtime, censorship, fraud or third-party interference. DERO's unique innovation is that tokens issued by smart contracts become encrypted balances in user wallets through homomorphic encryption. While contract code and state remain public and auditable, token balances and transfer amounts are completely private. Smart Contracts are nothing but rules which apply on transacting parties.
Current version of DVM is an interpreter based system to avoid security vulnerabilities, issues and compiler backdoors. This also allows easy audits of Smart Contracts for quality, bug-testing and security assurances. DVM supports a new language DVM-BASIC.
DVM apps run on a from scratch custom built privacy supporting, encrypted blockchain, an enormously powerful shared global infrastructure that can move value around and represent the ownership of assets/property without leaking any information. No one knows who owns what and who transferred to whom.
-
This enables developers to create puzzles, games, voting, markets, store registries of debts or promises, move funds in accordance with instructions given long in the past (like a will or a futures contract) and many other ideas/things that have not been invented yet, all without a middleman or counterparty risk.
-
DVM-BASIC is a contract-oriented, high-level language for implementing smart contracts. It is influenced by GW-BASIC, Visual Basic and C and is designed to target the DERO Virtual Machine (DVM). It is very easy to program and very readable.
-
DVM runs Smart Contracts which are a collection of functions written in DVM-BASIC. These functions can be invoked over the blockchain to do something. Smart contracts can act as libraries for other Smart contracts.
-
DVM supports a number of comment formats such as ', //, /* */ as good documentation is necessary.
DVM-Basic
DVM Example Factorial program
' This is a comment // This comment is supported /* this is multi-line comment / Function Factorial(s Uint64) Uint64 // this is a commment 10 DIM result,scopy as Uint64 / this is also comment */ 15 LET scopy = s 20 LET result = 1 30 LET result = result * s 40 LET s = s - 1 50 IF s >= 2 THEN GOTO 30 70 RETURN result End Function
- DVM smart contracts are written in a DVM-BASIC custom BASIC style language with line numbers.
- DVM supports
uint64andstringdata types. - DVM interprets the smart contract and processes it line by line.
uint64supports almost all operators, namely+,-,*,/,%.uint64supports the following bitwise operators:&,|,^,!,>>,<<.uint64supports the following logical operators:>,>=,<,<=,==,!=.stringsupports only the+operator. It supports concatenation with auint64.stringsupports==and!=logical operators.- All DVM variables are mandatory to define and are initialized to default values, namely
0and an empty string ("").
Smart Contract Execution Guidelines
- Smart Contract execution must return 0 to persist any changes made during execution. No panics should occur during execution.
DERO Smart Contract Examples
- Launching your token/asset on DERO blockchain (opens in a new tab)
- Launching your exchange for interchanging tokens/assets (opens in a new tab)
- DERO Smart Contract Examples (opens in a new tab)
- More Examples (opens in a new tab)
DERO Default Ports
Mainnet:
- Mining Getwork Port:
10100TCP - P2P Default Port:
10101UDP - RPC Default Port:
10102TCP - Wallet RPC Default Port:
10103TCP
Testnet:
- P2P Default Port:
40401 - RPC Default Port:
40402 - Wallet RPC Default Port:
40403
NB: Change ports to mainnet or testnet based on your requirements.
Statements Supported by DERO Virtual Machine
- DIM
- FUNCTION
- GOTO
- IF
- LET
- RETURN
DIM
-
DIM stands for data in memory and is used to define variable names within a function.
Syntax:
10 DIM variable1 as type 20 DIM variable1, variable2 as type 30 DIM key, owner as String 40 DIM count as Uint64Supported types in DVM are Uint64 and String. All DVM variables are mandatory to be defined and are initialized to default values: 0 for Uint64 and "" for String.
FUNCTION
-
Function statement is used to define a function.
Syntax:
Function ADD(x uint64, y uint64) uint64 10 RETURN x + y End Function
Function Syntax
Function syntax can be of two types:
Function function_name(0 or more arguments)Function function_name(0 or more arguments) return type
DVM Function Rules
- All functions start with the
Functionkeyword. - Function names should be alphanumeric.
- If the first letter of the function is an uppercase alphabet, the function can be invoked by the blockchain and other smart contracts.
- If the first letter of the function is a lowercase alphabet, the function can only be invoked by other functions within the smart contract.
- Functions may or may not have a return type.
- All functions must use
RETURNto return from the function or to return a value.RETURNis mandatory. - All functions must end with
End Function.End Functionis mandatory. - A function can have an implicit parameter value of type
uint64, which contains the amount of DERO value sent with the transaction. - Any error during processing will immediately stop execution and discard all changes that occur during SC execution.
- Any entrypoint which returns a
uint64value of 0 is termed as success and will make the transaction commit all state changes.
Specific Function Commands
-
GOTO: Used to jump to any line number within the function. It cannot cross function boundaries.Syntax:
// If signer is owner then withdraw. Function Withdraw(amount Uint64) Uint64 10 IF LOAD("owner") == SIGNER() THEN GOTO 30 20 RETURN 1 30 SEND_DERO_TO_ADDRESS(SIGNER(), amount) 40 RETURN 0 End Function -
IF: Executes a statement if a specified condition is true. It has two forms.Syntax:
10 IF COUNT == 0 THEN GOTO 110 20 IF COUNT == 0 THEN GOTO 110 ELSE GOTO 200 -
LET: Used to assign a value to a variable. Value can be as complex as possible and can contain complex expressions.Syntax:
10 LET COUNT = 10 20 LET x = 2 + 3 + ADD(2, 3) -
RETURN: Used to return from a function. It has two forms.Syntax:
10 RETURN 0 20 RETURN X + YReturn value must match the type defined while declaring the function.
RETURNcan be used anywhere within a function.
DVM Inbuilt Support Functions
DVM includes support functions that provide specific functionality or expose DVM internals.
Support Functions
VERSION(v String)
- Description: Sets a version to
dvm.VERSION. Returns 1 if successful, panics otherwise. - Return Type: Uint64
- ComputeCost: 1000
- StorageCost: 0
LOAD(variable)
- Description: Loads a variable previously stored in the blockchain using STORE function. Return type depends on what is stored. It panics if the value does NOT exist.
- Return Type: Uint64/String (depending on what is stored)
- ComputeCost: 5000
- StorageCost: 0
- Syntax:
10 IF LOAD(name) != SIGNER() THEN GOTO 30
EXISTS(variable)
- Description: Returns 1 if the variable is stored in the database via STORE and 0 otherwise.
- Return Type: Uint64
- ComputeCost: 5000
- StorageCost: 0
- Syntax:
10 IF EXISTS(name) THEN GOTO 50
STORE(key variable, value variable)
- Description: Stores key and value in the database. All storage state of the smart contract is accessible only from the smart contract which created it. Returns 1.
- Return Type: Uint64
- ComputeCost: 10000
- StorageCost: 0
- Syntax:
10 STORE("owner", SIGNER()) // Store in DB ["owner"] = address
DELETE(variable)
- Description: Sets the rawkey value to
[]byte{}effectively deleting it from storage. Returns 1. - Return Type: Uint64
- ComputeCost: 3000
- StorageCost: 0
MAPEXISTS(variable)
- Description: Returns 1 if the variable has been stored in RAM (current invoke session) via MAPSTORE and 0 otherwise.
- Return Type: Uint64
- ComputeCost: 1000
- StorageCost: 0
MAPGET(variable)
- Description: Loads a variable previously stored in RAM (current invoke session) via MAPSTORE. Return type depends on what is stored. It panics if the value does NOT exist.
- Return Type: Uint64/String (depending on what is stored)
- ComputeCost: 1000
- StorageCost: 0
MAPSTORE(key variable, value variable)
- Description: Stores key and value in RAM (current invoke session). All MAPSTORE state is accessible only from the session in which it is stored. Returns 1.
- Return Type: Uint64
- ComputeCost: 1000
- StorageCost: 0
MAPDELETE(variable)
- Description: Deletes the element from the map in RAM (current invoke session). If the key does not exist, delete has no action. Returns 1.
- Return Type: Uint64
- ComputeCost: 1000
- StorageCost: 0
RANDOM(limit Uint64)
- Description: RANDOM returns a random number using a PRNG seeded on BLID, SCID, TXID. The first form gives a uint64, the second form returns a random number in the range 0 - (limit), 0 is inclusive, limit is exclusive.
- Return Type: Uint64
- ComputeCost: 2500
- StorageCost: 0
- Syntax:
10 LET winner = RANDOM() % deposit_count // Finding winner.
SCID()
- Description: Returns SMART CONTRACT ID which is currently running.
- Return Type: String
- ComputeCost: 2000
- StorageCost: 0
BLID()
- Description: Returns current BLOCK ID which contains the current execution-in-progress TXID.
- Return Type: String
- ComputeCost: 2000
- StorageCost: 0
TXID()
- Description: Returns current TXID which is execution-in-progress.
- Return Type: String
- ComputeCost: 2000
- StorageCost: 0
DERO()
- Description: Returns a string representation of zerohash which is of type crypto.Hash.
- Return Type: String
- ComputeCost: 10000
- StorageCost: 0
BLOCK_HEIGHT()
- Description: Returns current chain height of BLID().
- Return Type: Uint64
- ComputeCost: 2000
- StorageCost: 0
BLOCK_TIMESTAMP()
-
Description: Returns current timestamp of BLID().
-
Return Type: Uint64
-
ComputeCost: 2500
-
StorageCost: 0
SIGNER()
- Description: Returns the address of who signed/sent this transaction. Ringsize of tx must be 2 for this value to be known or else empty. SIGNER() returns the raw address.
- Return Type: String
- ComputeCost: 5000
- StorageCost: 0
- Syntax:
10 IF LOAD("owner") == SIGNER() THEN GOTO 30
UPDATE_SC_CODE(sc_code String)
- Description: Stores updated SC code of type string. If it is not of type string, return 0, else return 1.
- Return Type: Uint64
- ComputeCost: 5000
- StorageCost: 0
IS_ADDRESS_VALID(address String)
- Description: Returns 1 if address is valid, 0 otherwise.
- Return Type: Uint64
- ComputeCost: 50000
- StorageCost: 0
ADDRESS_RAW(address String)
- Description: Returns address in RAW form as 33 byte keys, stripping away textual/presentation form. Two addresses should always be compared in RAW form.
- Return Type: String
- ComputeCost: 60000
- StorageCost: 0
ADDRESS_STRING(p String)
- Description: Returns address in STRING form. If it can be evaluated, a string form of an address will be returned, otherwise, return an empty string.
- Return Type: String
- ComputeCost: 50000
- StorageCost: 0
SEND_DERO_TO_ADDRESS(a String, amount Uint64)
- Description: Sends amount DERO from SC DERO balance to an address which should be in raw form. Address must be in string DERO/DETO form. If the SC does not have enough balance, it will panic.
- Return Type: Uint64
- ComputeCost: 70000
- StorageCost: 0
SEND_ASSET_TO_ADDRESS(a String, amount Uint64, asset String)
- Description: Sends amount ASSET from SC ASSET balance to an address which should be in raw form. Address must be in string DERO/DETO form. If the SC does not have enough balance, it will panic.
- Return Type: Uint64
- ComputeCost: 90000
- StorageCost: 0
DEROVALUE()
- Description: Gets the amount of DERO sent within this transaction.
- Return Type: Uint64
- ComputeCost: 10000
- StorageCost: 0
ASSETVALUE(asset String)
- Description: Gets the amount of a given ASSET sent within this transaction.
- Return Type: Uint64
- ComputeCost: 10000
- StorageCost: 0
ATOI(s String)
- Description: Returns a Uint64 representation of a string. Else, panic.
- Return Type: Uint64
- ComputeCost: 5000
- StorageCost: 0
ITOA(n Uint64)
- Description: Returns string representation of a Uint64. Else, panic.
- Return Type: String
- ComputeCost: 5000
- StorageCost: 0
SHA256(s String)
- Description: Returns a string sha2-256 hash of a given string. Else, panic.
- Return Type: String
- ComputeCost: 25000
- StorageCost: 0
SHA3256(s String)
- Description: Returns a string sha3-256 hash of a given string. Else, panic.
- Return Type: String
- ComputeCost: 25000
- StorageCost: 0
KECCAK256(s String)
- Description: Returns a string sha3-keccak256 hash of a given string. Else, panic.
- Return Type: String
- ComputeCost: 25000
- StorageCost: 0
HEX(s String)
- Description: Returns a hex encoded string value of a given string. Else, panic.
- Return Type: String
- ComputeCost: 10000
- StorageCost: 0
HEXDECODE(s String)
- Description: Returns a hex decoded string value of a given hex string. Else, panic.
- Return Type: String
- ComputeCost: 10000
- StorageCost: 0
MIN(f Uint64, s Uint64)
- Description: Returns the minimum value of 2 Uint64 values. Else, panic.
- Return Type: Uint64
- ComputeCost: 5000
- StorageCost: 0
MAX(f Uint64, s Uint64)
- Description: Returns the maximum value of 2 Uint64 values. Else, panic.
- Return Type: Uint64
- ComputeCost: 5000
- StorageCost: 0
STRLEN(s String)
- Description: Returns the length of a given string in Uint64. Else, panic.
- Return Type: Uint64
- ComputeCost: 20000
- StorageCost: 0
SUBSTR(s String, offset Uint64, length Uint64)
- Description: Returns the substring of a given string with offset and length defined. Else, panic.
- Return Type: String
- ComputeCost: 20000
- StorageCost: 0
PANIC
- Description: Panics.
- Return Type: Panic
- ComputeCost: 10000
- StorageCost: 0
More about DVM-Basic here: Explaining DVM-Basic
Related Pages
Learn the Language:
- DVM-BASIC Programming Guide - Complete language reference
- Smart Contract Examples - Full code examples
Privacy Features:
- Private Smart Contracts - How contract privacy works
- Homomorphic Encryption - Encrypted state storage
Build & Deploy:
- Token Contract Tutorial - Step-by-step guide
- Wallet RPC API - Deploy via RPC
- Daemon RPC API - Query contract state
Technical Details:
- Golang Performance - Why DVM is fast
- DERO Tokens - Understanding asset transfers