Build on Valdium Testnet · v1.10 · all tests passing
Estimated read time: 12 minutes

Writing Contracts

Contract structure

A Valdium contract is a JavaScript file that evaluates to an object literal with named methods. The file must end with a parenthesized object expression:

({ init(args) { /* called once at deploy */ }, myMethod(arg1, arg2) { /* callable externally */ }, _privateHelper() { /* underscore prefix = internal only */ }, });

Available globals

Inside a contract, you have access to these injected globals:

// Read/write persistent key-value storage storage.get(key) // → string | null storage.set(key, value) // value must be a string storage.delete(key) // Transaction context msg.sender // address of the caller msg.value // VLD sent with the call (BigInt, in wei) // Chain information chain.blockNumber // current block height chain.blockTime // block timestamp (unix seconds) // Emit an event (recorded in the receipt) emit(eventName, { ...args }) // Assertion — throws and reverts on failure assert(condition, message)

Inter-contract calls

Call another contract with await E(address).method(args). Inter-contract calls are asynchronous — the current contract's execution pauses until the callee finishes. This makes reentrancy structurally impossible.

const tokenAddr = '0xABC...'; const balance = await E(tokenAddr).balanceOf(msg.sender); assert(BigInt(balance) >= 100n, 'not enough tokens');

Error handling

Use assert() to validate inputs and state. Any thrown exception reverts the transaction — storage writes are discarded, events are not emitted, gas is consumed.

assert(msg.sender === storage.get('owner'), 'not the owner'); assert(amount > 0n, 'amount must be positive');

Gas

Gas is charged per operation type:

The block gas limit is 30,000,000. Simple transfers cost 21,000 gas, allowing ~1,400 per block.

What you cannot do

Contracts run in a hardened SES sandbox. The following are not available: fetch, Date.now, Math.random, setTimeout, filesystem access, or any ambient authority. All non-determinism is stripped. What you see is what every validator sees.