Skip to content

Commit

Permalink
docs: update interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
leovct committed Jul 17, 2024
1 parent 796754f commit d4ee0b5
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 14 deletions.
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,74 @@ The aim is to keep it simple, quick to implement and interesting to learn more a

Inspired by [gevm](https://github.com/Jesserc/gevm) by [Jesserc](https://twitter.com/jesserc_).

## EVM

```go
type IEVM interface {
//// Stack operations
// Push an item to the stack.
Push(*uint256.Int) error

// Pop an item from the stack.
Pop() (*uint256.Int, error)

//// Math operations
// Add the top two elements of the stack and push the result, x + y, back to the stack.
Add() error

// Multiply the top two elements of the stack and push the result, x * y, back to the stack.
Mul() error

// Subtract the top two elements of the stack and push the result, x - y, back to the stack.
Sub() error

// Perform the integer divison operation on the top two elements of the stack and push the result, x // y, back to the stack.
Div() error

// Perform the signed integer division operation (trunced) on the top two elements of the stack and push the result, x // y, back to the stack.
SDiv() error

// Perform the modulo remained operation on the top two elements of the stack and push the result, x % y, back to the stack.
Mod() error

// Perform the signed modulo remained operation on the top two elements of the stack and push the result, x % y, back to the stack.
SMod() error

// Perform the modulo addition operation on the top two elements of the stack and push the result, (x + y) % m, back to the stack.
// The third top element of the stack is the integer denominator m.
AddMod() error

// Perform the modulo multiplication operation on the top two elements of the stack and push the result, (x * y) % m, back to the stack.
// The third top element of the stack is the integer denominator N.
MulMod() error

// Perform the exponential operation on the top two elements of the stack and push the result, x ** y, back to the stack.
Exp() error

// Extend the length of two’s complement signed integer.
// The first top element of the stack, b, represents the size in byte - 1 of the integer to sign extend.
// The second top element of the stack, x, represents the integer value to sign extend.
SignExtend() error
}

// EVM represents an Ethereum Virtual Machine.
type EVM struct {
stack IStack
memory IMemory
storage IStorage
}
```

## Stack

```go
type IStack interface {
// Push adds a new element to the top of the stack.
// It returns an error if the stack is full.
Push(*uint256.Int) error

// Pop removes and returns the top element from the stack.
// If the stack is empty, it returns a zero-value 32-byte array and an error.
Pop() (*uint256.Int, error)
}

Expand All @@ -24,7 +87,14 @@ type Stack struct {

```go
type IMemory interface {
// Store writes a byte slice to memory at the specified offset.
// If the offset plus the length of the value exceeds the current memory size,
// the memory is automatically expanded to accommodate the new data.
Store(value []byte, offset int)

// Access retrieves a slice of memory starting at the given offset with the specified size.
// It handles cases where the requested region may extend beyond the current memory size.
// Returns a byte slice of length 'size', zero-padded if necessary.
Access(offset, size int) []byte
}

Expand All @@ -38,7 +108,12 @@ type Memory struct {

```go
type IStorage interface {
// Store writes a 32-byte word to storage at the specified key.
// If the key already exists, its value will be overwritten.
Store(key int, value [32]byte)

// Load retrieves a 32-byte word from storage using the specified key.
// If the key does not exist in the storage, it returns an empty 32-byte word.
Load(key int) [32]byte
}

Expand Down
13 changes: 7 additions & 6 deletions memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ package main

// IMemory defines the methods that a memory implementation should have.
type IMemory interface {
// Store writes a byte slice to memory at the specified offset.
// If the offset plus the length of the value exceeds the current memory size,
// the memory is automatically expanded to accommodate the new data.
Store(value []byte, offset int)

// Access retrieves a slice of memory starting at the given offset with the specified size.
// It handles cases where the requested region may extend beyond the current memory size.
// Returns a byte slice of length 'size', zero-padded if necessary.
Access(offset, size int) []byte
}

Expand All @@ -16,9 +23,6 @@ func NewMemory() IMemory {
return &Memory{data: make([]byte, 0)}
}

// Store writes a byte slice to memory at the specified offset.
// If the offset plus the length of the value exceeds the current memory size,
// the memory is automatically expanded to accommodate the new data.
func (m *Memory) Store(value []byte, offset int) {
// Expand the memory if needed.
requiredSize := offset + len(value)
Expand All @@ -30,9 +34,6 @@ func (m *Memory) Store(value []byte, offset int) {
copy(m.data[offset:], value)
}

// Access retrieves a slice of memory starting at the given offset with the specified size.
// It handles cases where the requested region may extend beyond the current memory size.
// Returns a byte slice of length 'size', zero-padded if necessary.
func (m *Memory) Access(offset, size int) []byte {
// Return a zero-filled slice if memory is empty or offset is out of bounds.
if len(m.data) == 0 || offset >= len(m.data) {
Expand Down
9 changes: 5 additions & 4 deletions stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ var (

// IStack defines the methods that a stack implementation should have.
type IStack interface {
// Push adds a new element to the top of the stack.
// It returns an error if the stack is full.
Push(*uint256.Int) error

// Pop removes and returns the top element from the stack.
// If the stack is empty, it returns a zero-value 32-byte array and an error.
Pop() (*uint256.Int, error)
}

Expand All @@ -32,8 +37,6 @@ func NewStack() IStack {
return &Stack{data: make([]uint256.Int, 0)}
}

// Push adds a new element to the top of the stack.
// It returns an error if the stack is full.
func (s *Stack) Push(value *uint256.Int) error {
if len(s.data) >= MAX_STACK_SIZE {
return ErrStackOverflow
Expand All @@ -42,8 +45,6 @@ func (s *Stack) Push(value *uint256.Int) error {
return nil
}

// Pop removes and returns the top element from the stack.
// If the stack is empty, it returns a zero-value 32-byte array and an error.
func (s *Stack) Pop() (*uint256.Int, error) {
if len(s.data) == 0 {
return nil, ErrStackUnderflow
Expand Down
9 changes: 5 additions & 4 deletions storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ package main

// IStorage defines the methods that a storage implementation should have.
type IStorage interface {
// Store writes a 32-byte word to storage at the specified key.
// If the key already exists, its value will be overwritten.
Store(key int, value [32]byte)

// Load retrieves a 32-byte word from storage using the specified key.
// If the key does not exist in the storage, it returns an empty 32-byte word.
Load(key int) [32]byte
}

Expand All @@ -16,14 +21,10 @@ func NewStorage() IStorage {
return &Storage{data: make(map[int][32]byte)}
}

// Store writes a 32-byte word to storage at the specified key.
// If the key already exists, its value will be overwritten.
func (s *Storage) Store(key int, value [32]byte) {
s.data[key] = value
}

// Load retrieves a 32-byte word from storage using the specified key.
// If the key does not exist in the storage, it returns an empty 32-byte word.
func (s *Storage) Load(key int) [32]byte {
return s.data[key]
}

0 comments on commit d4ee0b5

Please sign in to comment.