Skip to content

Instantly share code, notes, and snippets.

@YHTerrance
Last active June 1, 2022 13:48
Show Gist options
  • Save YHTerrance/33a39187ddc3613e4f0181a59bfed893 to your computer and use it in GitHub Desktop.
Save YHTerrance/33a39187ddc3613e4f0181a59bfed893 to your computer and use it in GitHub Desktop.
2022 DeFi - Zokrates Calculator
// -- Parameters --
const u32 MAX_OPS = 16
const u32 MAX_STACK_ = 8
// workaround for not having short-circuit in the branch
const u32 STACK_OFFSET = 8
const u32 MAX_STACK = MAX_STACK_ + STACK_OFFSET
const u32 MAX_OPS_ = MAX_OPS + 1
// --- OPs ---
const field OP_PUSH = 42 // push next value into the stack
const field OP_NOP = 97 // noop
const field OP_ADD = 147 // add top two values in the stack and push back the result
const field OP_SUB = 148 // substract top value from the second value and push back the result
const field OP_MUL = 149 // multiply top two values in the stack and push back the result
// --- instructions ---
def opAddStack(field[MAX_STACK] stack, u32 idx) -> field[MAX_STACK]:
// TODO: Implementation
def opAddIdx(u32 idx) -> u32:
// TODO: Implementation
// TODO: Add more instructions
def exec(field op, field[MAX_STACK] stack, u32 idx) -> (field[MAX_STACK], u32):
stack = op == OP_ADD ? opAddStack(stack, idx) : stack
idx = op == OP_ADD ? opAddIdx(idx) : idx
// TODO: Add more instructions
return stack, idx
def opPushStack(field[MAX_STACK] stack, u32 stackIdx, field[MAX_OPS_] data, u32 dataIdx) -> field[MAX_STACK]:
stack[stackIdx] = data[dataIdx+1]
return stack
def opPushIdx(u32 stackIdx) -> u32:
return stackIdx+1
def execWithData(field op, field[MAX_STACK] stack, u32 stackIdx, field[MAX_OPS_] data, u32 dataIdx) -> (field[MAX_STACK], u32, u32):
stack = op == OP_PUSH ? opPushStack(stack, stackIdx, data, dataIdx) : stack
stackIdx = op == OP_PUSH ? opPushIdx(stackIdx) : stackIdx
u32 advance = 0
advance = op == OP_PUSH ? 1 : advance
return stack, stackIdx, advance
// A simple calculator with private initial stack values
// return value: top stack value
def main(private field[MAX_STACK_] initialStack, private u32 initialStackIdx, field[MAX_OPS] ops) -> field:
field[STACK_OFFSET] padding = [0; STACK_OFFSET]
field[MAX_STACK] stack = [...padding, ...initialStack]
u32 stackIdx = initialStackIdx + STACK_OFFSET
field[MAX_OPS_] ops_ = [...ops, 0]
for u32 i in 0..MAX_OPS do
field op = ops[i]
stack, stackIdx = exec(op, stack, stackIdx)
u32 dataAdvance = 0
stack, stackIdx, dataAdvance = execWithData(op, stack, stackIdx, ops_, i)
i = i + dataAdvance
endfor
return stack[stackIdx-1]
import "./calculator-p.zok" as vm
from "./calculator-p.zok" import OP_ADD, OP_SUB, OP_MUL, OP_PUSH, OP_NOP
def main(field address) -> field:
field result = vm([address, 0, 0, 0, 0, 0, 0, 0], 1, [
OP_PUSH, 3,
OP_ADD,
OP_PUSH, 5,
OP_MUL,
OP_PUSH, 6,
OP_SUB,
OP_PUSH, 4,
OP_MUL,
OP_NOP, OP_NOP, OP_NOP, OP_NOP
])
assert(result == ((address + 3) * 5 - 6) * 4)
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment