Dero Virtual Machine
DVM-Basic

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 and string 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 a uint64.
  • 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

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:

  1. Function function_name(0 or more arguments)
  2. 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