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 both public and private smart contracts: applications that run exactly as programmed without any possibility of downtime, censorship, fraud or third-party interference. Public Smart contracts are open versions. However, the DVM is being designed to support Private Smart Contracts where everything is hidden, eg parties, and information involved. Smart Contracts are nothing but rules which apply on transacting parties.
Current version of DVM is an interpretor based system to avoid security vulneribilities, 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 number of comments 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
uint64
andstring
data types. - DVM interprets the smart contract and processes it line by line.
uint64
supports almost all operators, namely+
,-
,*
,/
,%
.uint64
supports the following bitwise operators:&
,|
,^
,!
,>>
,<<
.uint64
supports the following logical operators:>
,>=
,<
,<=
,==
,!=
.string
supports only the+
operator. It supports concatenation with auint64
.string
supports==
and!=
logical operators.- All DVM variables are mandatory to define and are initialized to default values, namely
0
and 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:
10100
TCP - P2P Default Port:
10101
UDP - RPC Default Port:
10102
TCP - Wallet RPC Default Port:
10103
TCP
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 Uint64
Supported 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
Function
keyword. - 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
RETURN
to return from the function or to return a value.RETURN
is mandatory. - All functions must end with
End Function
.End Function
is 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
uint64
value 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 + Y
Return value must match the type defined while declaring the function.
RETURN
can 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