melodeon 0.5.16

High-level language that targets the Themelio blockchains' MelVM covenants
Documentation
type Hash = %[32]

struct CoinID {
	txhash: Hash,
	index: Nat
}

struct CoinData {
	covhash: Hash,
	value: Nat,
	denom: %[],
	additional_data: %[],
}

struct Transaction {
	kind: Nat,
	inputs: [CoinID;],
	outputs: [CoinData;],
	fee: Nat,
	scripts: [%[];],
	data: %[],
	sigs: [%[];]
}

# Wrappers for the environment

def env_spender_tx() = unsafe extern "SPENDER-TX" :! Transaction

def env_spender_tx_hash() = unsafe unsafe extern "SPENDER-TX-HASH" :! Hash
def env_parent_tx_hash() = unsafe extern "PARENT-TX-HASH" :! Hash
def env_parent_index() = unsafe extern "PARENT-INDEX" :! Nat
def env_self_hash() = unsafe extern "SELF-HASH" :! Hash
def env_parent_value() = unsafe extern "PARENT-VALUE" :! Nat
def env_parent_denom() = unsafe extern "PARENT-DENOM" :! %[]
def env_parent_data() = unsafe extern "PARENT-DATA" :! %[]
def env_parent_height() = unsafe extern "PARENT-HEIGHT" :! Nat
def env_spender_index() = unsafe extern "SPENDER-INDEX" :! Nat


# Vector tools
def vlen(vec: [Any ;]) : Nat =
	unsafe
		extern call "v-len" (vec)
	:! Nat

def blen(bytes: %[]) : Nat =
	unsafe 
		extern call "b-len" (bytes)
	:! Nat

def range<$n>(x: {$n..$n}) =
    unsafe let accum = [] :! [Nat; $n] in
    let ctr = 0 :: Nat in
    loop $n do
        accum <- (accum ++ [ctr]) :! [Nat; $n]; 
        ctr <- ctr + 1
    return accum

def zip<$n, T, U>(x: [T; $n], y: [U; $n]) =
    for i in range($n)
    fold accum = [] :: [[T, U]; 0] with
        accum ++ [[unsafe_vref(x, i), unsafe_vref(y, i)]]

def enumerate<$n, T>(x: [T; $n]) = zip(range($n), x)

def unsafe_vref<T>(x: [T;], i: Nat) = unsafe (x :! [T; 1])[i :! {0}]

def vref<T>(x: [T;], n: Nat): T | False =
    if n < vlen(x) then
        unsafe_vref(x, n)
    else
        0

# stopgaps

def unsafe_bslice(b: %[], i: Nat, j: Nat) = unsafe extern call "b-slice" (b, i, j) :! %[]

# Conversions

def b2n(b: %[32]) = unsafe extern call "bytes->u256" (b) :! Nat
def n2b(b: Nat) = unsafe extern call "u256->bytes" (b) :! %[32]

# signatures
def ed25519_verify<$n>(msg: %[$n], public_key: %[], signature: %[]) =
    unsafe extern call "sigeok" ($n, msg, public_key, signature) :! Bool

# useful helper
def ed25519_signed_by(public_key: %[32], idx: Nat) =
	let sig = vref(env_spender_tx().sigs, idx) in
	sig && ed25519_verify(env_spender_tx_hash(), public_key, sig)

# Blake3 hash function
def blake3<$n>(msg: %[$n]) =
	unsafe extern call "hash" ($n, msg) :! %[32]

# def print<T>(x: T): T =
#     unsafe extern call "print" (x) :! T

# Definitions for bools etc
type False = {0}
type True = {1}
type Bool = True | False