Dero Virtual Machine
DVM-BASIC

DVM-BASIC Programming Guide

DVM-BASIC is DERO's smart contract programming language - a blockchain-optimized BASIC variant that's easy to learn yet powerful enough for complex dApps with privacy features.

Source: dvm/ - Virtual Machine implementation

Language Features

  • Line-numbered syntax (like GW-BASIC)
  • Strong typing: Uint64 and String
  • Built-in blockchain functions
  • Privacy-preserving operations
  • Deterministic execution

Quick Start

Function Initialize() Uint64
  10 STORE("owner", SIGNER())
  20 STORE("counter", 0)
  30 RETURN 0
End Function

Function Increment() Uint64
  10 DIM current as Uint64
  20 LET current = LOAD("counter")
  30 STORE("counter", current + 1)
  40 RETURN 0
End Function

Authorization patterns

SIGNER() returns the wallet address that sent the current transaction — Captain's words: "may not be the owner of the SC." It coincides with the owner during Initialize (canonical pattern below) but on every other call you must check explicitly. If your contract has no stored-owner gate, anyone can call UpdateCode and overwrite your logic — the DVM does not gate UpdateCode at the protocol level.

The canonical pattern: store the owner during Initialize, then gate every privileged function with IF LOAD("owner") == SIGNER() THEN ....

Function Initialize() Uint64
  10 STORE("owner", SIGNER())
  20 RETURN 0
End Function

Function UpdateOwner(new_owner String) Uint64
  10 IF LOAD("owner") == SIGNER() THEN GOTO 30
  20 RETURN 1
  30 STORE("owner", ADDRESS_RAW(new_owner))
  40 RETURN 0
End Function

Without line 10, anyone can call UpdateOwner and seize the contract.

Data Types & Variables

TypeRangeDefaultUsage
Uint640 to 18,446,744,073,709,551,6150Numbers, balances, counts
StringVariable (size limits apply)""Text, addresses, keys

Declare variables:

10 DIM counter as Uint64
20 DIM name, symbol as String

Operators

TypeOperators
Arithmetic+ - * / %
Bitwise& | ^ ! >> <<
Comparison> >= < <= == !=
String+ (concat), ==, !=

Control Flow

IF-THEN-ELSE:

10 IF value > 100 THEN GOTO 30 ELSE GOTO 50

Loops with GOTO:

10 LET counter = 0
20 LET counter = counter + 1
30 IF counter < 10 THEN GOTO 20

Comments

' Single-line comment
// Alternative single-line
/* Multi-line
   comment */

Functions

Syntax:

Function Name(param1 Type, param2 Type) ReturnType
  10 RETURN value
End Function

Visibility:

  • Uppercase first letter → Public (callable externally)
  • Lowercase first letter → Private (internal only)

Return values:

  • 0 = success
  • Non-zero = error code

Blockchain Functions

State Management

FunctionPurpose
STORE(key, value)Save to blockchain state
LOAD(key)Read from blockchain state
EXISTS(key)Check if key exists

Identity & Transaction

FunctionPurpose
SIGNER()Get transaction sender address
TXID()Get current transaction ID
ADDRESS_RAW(string)Convert address string to raw format
IS_ADDRESS_VALID(string)Validate address format

Asset Operations

FunctionPurpose
SEND_DERO_TO_ADDRESS(addr, amount)Transfer DERO
SEND_ASSET_TO_ADDRESS(addr, amount, scid)Transfer asset/token
DEROVALUE()Get DERO sent in transaction
ASSETVALUE(scid)Get asset sent in transaction

Blockchain Info

FunctionPurpose
BLOCK_HEIGHT()Current block height
BLOCK_TIMESTAMP()Current block timestamp
SCID()This contract's ID

Cryptographic

FunctionPurpose
SHA256(data)Compute SHA256 hash
KECCAK256(data)Compute Keccak256 hash

Best Practices

  1. Security - Always validate inputs and permissions
  2. Gas efficiency - Minimize STORE/LOAD operations
  3. Line spacing - Use increments of 10 for future insertions
  4. Error codes - Return meaningful error codes
  5. Testing - Use Simulator before deployment

Example: Token Contract

Function Initialize() Uint64
  10 STORE("owner", SIGNER())
  20 STORE("supply", 1000000)
  30 STORE("balance:" + SIGNER(), 1000000)
  40 RETURN 0
End Function

Function Transfer(to String, amount Uint64) Uint64
  10 DIM sender as String
  20 DIM sender_bal, recipient_bal as Uint64
  
  30 LET sender = SIGNER()
  40 IF IS_ADDRESS_VALID(to) != 1 THEN GOTO 200
  50 IF amount <= 0 THEN GOTO 200
  
  60 LET sender_bal = LOAD("balance:" + sender)
  70 IF sender_bal < amount THEN GOTO 200
  
  80 IF EXISTS("balance:" + ADDRESS_RAW(to)) THEN GOTO 100
  90 STORE("balance:" + ADDRESS_RAW(to), 0)
  
  100 LET recipient_bal = LOAD("balance:" + ADDRESS_RAW(to))
  110 STORE("balance:" + sender, sender_bal - amount)
  120 STORE("balance:" + ADDRESS_RAW(to), recipient_bal + amount)
  130 RETURN 0
  
  200 RETURN 1 ' Error
End Function

Function BalanceOf(address String) Uint64
  10 IF EXISTS("balance:" + ADDRESS_RAW(address)) THEN GOTO 30
  20 RETURN 0
  30 RETURN LOAD("balance:" + ADDRESS_RAW(address))
End Function

Learn More

Tip: The DVM-BASIC language evolves with DERO. Check official docs for updates!


Related Pages

Smart Contract Examples:

Understanding the DVM:

Deploy & Test: