Skip to content

EVM Operational Codes

Nevio Vesic edited this page Aug 12, 2023 · 8 revisions

The opcode package in Solgo is a specialized toolkit tailored for the Ethereum ecosystem. It's designed to facilitate the construction, visualization, and analysis of opcode execution trees within the Ethereum Virtual Machine (EVM). These trees represent sequences of instructions, providing a structured view of how opcodes, derived from Solidity code, are executed in sequence on the EVM.

The Ethereum Virtual Machine (EVM) is the runtime environment for executing smart contracts on the Ethereum blockchain. Smart contracts, primarily written in Solidity, are compiled into bytecode, which is a series of opcodes that the EVM can understand and execute. The opcode package in Solgo provides developers with a robust set of tools to work with these opcodes, ensuring a deeper understanding and efficient manipulation of EVM bytecode.

Decompiler Higher Overview

The decompiler.go file in the opcode package of Solgo is pivotal for understanding and working with Ethereum bytecode. It provides tools to decompile Ethereum bytecode into a set of instructions, making it easier to analyze and understand the underlying logic of Solidity smart contracts as they are executed on the Ethereum Virtual Machine (EVM).

Usage

Here's a practical example showcasing the usage of the opcode package:

package main

import (
	"context"
	"time"

	"github.com/txpull/solgo/opcode"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func main() {
	currentTick := time.Now()
	defer func() {
		zap.S().Infof("Total time took: %v", time.Since(currentTick))
	}()

	config := zap.NewDevelopmentConfig()
	config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
	logger, err := config.Build()
	if err != nil {
		panic(err)
	}

	zap.ReplaceGlobals(logger)

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	bytecode := "0x6060604052341561000f57600080fd5b5b6101518061001f6000396000f30060606040"

	decompiler, err := opcode.NewDecompiler(ctx, []byte(bytecode))
	if err != nil {
		zap.S().Errorf("Error during construction of new decompiler: %v", err)
		return
	}

	if err := decompiler.Decompile(); err != nil {
		zap.S().Errorf("Error during decompilation: %v", err)
		return
	}

	// Print the decompiled instructions
	zap.S().Infof("Decompiled Instructions: \n%s", decompiler.String())

}

Sample Decompilation Response

The following is a sample output of the decompiled instructions:

0x0000 ADDRESS // Get address of currently executing account.
0x0001 PUSH25 36303630363034303532333431353631303030663537363030 // Push 25 bytes onto the stack.
0x001b ADDRESS // Get address of currently executing account.
0x001c CODESIZE // Get size of code running in current environment.
0x001d ADDRESS // Get address of currently executing account.
0x001e PUSH7 64356235623631 // Push 7 bytes onto the stack.
0x0026 ADDRESS // Get address of currently executing account.
0x0027 BALANCE // Get balance of the given account.
0x0028 CALLDATALOAD // Get input data of current environment.
0x0029 BALANCE // Get balance of the given account.
0x002a CODESIZE // Get size of code running in current environment.
0x002b ADDRESS // Get address of currently executing account.
0x002c CALLDATASIZE // Get size of input data in current environment.
0x002d BALANCE // Get balance of the given account.
0x002e ADDRESS // Get address of currently executing account.
0x002f ADDRESS // Get address of currently executing account.
0x0030 BALANCE // Get balance of the given account.
0x0031 PUSH7 36303030333936 // Push 7 bytes onto the stack.
0x0039 ADDRESS // Get address of currently executing account.
0x003a ADDRESS // Get address of currently executing account.
0x003b ADDRESS // Get address of currently executing account.
0x003c PUSH7 33303036303630 // Push 7 bytes onto the stack.
0x0044 CALLDATASIZE // Get size of input data in current environment.
0x0045 ADDRESS // Get address of currently executing account.
0x0046 CALLVALUE // Get deposited value by the instruction/transaction responsible for this execution.
0x0047 ADDRESS // Get address of currently executing account.

Total time took to render response is 117.233µs!

Future Developments

The opcode package is continuously evolving, and here are some of the anticipated enhancements:

  • Reverser: This tool will reverse-engineer the EVM bytecode, translating it back into a more comprehensible Solidity format.
  • Symbolic Executor: A sophisticated feature enabling the simulation of opcode execution without actual execution on the EVM, proving invaluable for debugging and analysis.
Clone this wiki locally