solgo

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 17, 2023 License: Apache-2.0 Imports: 15 Imported by: 0

README

Build Status Security Status Coverage Status Go Report Card License PkgGoDev OpenSSF Best Practices

Solidity Parser in Go

SolGo contains a Solidity parser written in Go, using Antlr and AntlrGo for grammar parsing. The aim of this project is to provide a tool to parse Solidity source code into a structured format, enabling further analysis.

The parser is generated from a Solidity grammar file using Antlr, producing a lexer, parser, and listener using AntlrGo. This allows for the syntactic analysis of Solidity code, transforming it into a parse tree that can be traversed and manipulated.

This project is ideal for developers working with Solidity smart contracts who wish to leverage the power and efficiency of Go for their analysis tools.

Disclaimer

Please be aware that this project is still under active development. While it is approaching a state suitable for production use, there may still be undiscovered issues or limitations. Over the next few weeks, extensive testing will be conducted on 1-2 million contracts to evaluate its performance and stability. Additional tests and comprehensive documentation will also be added during this phase.

Once we are confident that the project is fully ready for production, this disclaimer will be removed. Until then, please use the software with caution and report any potential issues or feedback to help us improve its quality.

Documentation

The SolGo basic documentation is hosted on GitHub, ensuring it's always up-to-date with the latest changes and features. You can access the full documentation here.

Getting Started

Detailed examples of how to install and use this package can be found in the Usage section.

Solidity Language Grammar

Latest Solidity language grammar higher overview and detailed description can be found here.

ANTLR Grammar

We are using grammar files that are maintained by the Solidity team. Link to the grammar files can be found here.

ANTLR Go

We are using the ANTLR4 Go runtime library to generate the parser. Repository can be found here.

Crytic Slither

We are using Slither to detect vulnerabilities in smart contracts. Repository can be found here.

Makes no sense to rewrite all of that hard work just to be written in Go. Therefore, a bit of python will not hurt. In the future we may change direction.

Features

  • Protocol Buffers: SolGo uses Protocol Buffers to provide a structured format for the data, enabling more effective analysis and a way to build a common interface for other tools. Supported languages: Go and Javascript. In the future, will be adding Rust and Python.
  • Abstract Syntax Tree (AST) Generation: SolGo includes an builder that constructs an Abstract Syntax Tree for Solidity code.
  • Intermediate Representation (IR) Generation: SolGo can generate an Intermediate Representation (IR) from the AST. The IR provides a language-agnostic representation of the contract, capturing key elements such as functions, state variables, events, and more. This enables more advanced analysis and manipulation of the contract.
  • Application Binary Interface (ABI) Generation: SolGo includes an builder that can parse contract definitions to generate ABI for group of contracts or each contract individually.
  • Opcode Decompilation and Execution Trees: The opcode package facilitates the decompilation of bytecode into opcodes, and offers tools for constructing and visualizing opcode execution trees. This provides a comprehensive view of opcode sequences in smart contracts, aiding in deeper analysis and understanding.
  • Syntax Error Handling: SolGo includes listener which collects syntax errors encountered during parsing, providing detailed error information including line, column, message, severity, and context.
  • Automatic Source Detection: SolGo automatically loads and integrates Solidity contracts from well-known libraries such as OpenZeppelin.
  • Ethereum Improvement Proposals (EIP) Registry: A package designed to provide a structured representation of Ethereum Improvement Proposals (EIPs) and Ethereum Request for Comments (ERCs). It simplifies the interaction with various contract standards by including functions, events, and a registry mechanism crafted for efficient management.
  • Security Audits: SolGo now includes an Audit package that is specifically designed to detect security vulnerabilities in Solidity smart contracts. This package uses Slither advanced algorithms and patterns to scan and identify potential threats and weaknesses in the codebase, ensuring that contracts are secure and robust against malicious attacks.

Contributing

Contributions to SolGo are always welcome! Please visit Contributing for more information on how to get started.

License

SolGo is licensed under the Apache 2.0. See LICENSE for the full license text.

Acknowledgements

We would like to express our gratitude to the Solidity team for maintaining the Solidity grammar files, and to the Antlr and AntlrGo team for providing the powerful Antlr tool that makes this project possible. Not to forget the Crytic and Slither contributors for their hard work on the Slither tool as without it we would have hard time detecting vulnerabilities in smart contracts.

Documentation

Overview

Package solgo provides a suite of tools for parsing, analyzing, and interacting with Solidity contracts. It includes a contextual parser that maintains a stack of contexts as it parses a contract, allowing it to keep track of the current context (e.g., within a contract definition, function definition, etc.). It also includes a contract listener that extracts information about contracts as they are parsed, including the contract name, implemented interfaces, imported contracts, pragmas, and comments. Additionally, it includes a syntax error listener that listens for syntax errors in contracts and categorizes them by severity. The package also provides functionality for generating and working with Ethereum contract ABIs (Application Binary Interfaces). This includes parsing contract definitions to extract ABI information, normalizing type names, and handling complex types like mappings. These tools can be used together to provide a comprehensive interface for working with Solidity contracts, making it easier to understand their structure, identify potential issues, and interact with them on the Ethereum network.

Index

Constants

This section is empty.

Variables

View Source
var ErrPathFound = errors.New("path found")

Functions

This section is empty.

Types

type ListenerName

type ListenerName string

ListenerName represents the name of a listener.

const (
	ListenerAbi          ListenerName = "abi"
	ListenerContractInfo ListenerName = "contract_info"
	ListenerAst          ListenerName = "ast"
	ListenerSyntaxErrors ListenerName = "syntax_errors"
)

Predefined listener names.

func (ListenerName) String added in v0.1.4

func (l ListenerName) String() string

type Node added in v0.2.1

type Node struct {
	Name         string
	Dependencies []string
}

Node represents a unit of source code in Solidity with its dependencies.

type Parser added in v0.1.6

type Parser struct {
	// contains filtered or unexported fields
}

Parser is a struct that encapsulates the functionality for parsing and analyzing Solidity contracts.

func NewParser added in v0.1.6

func NewParser(ctx context.Context, input io.Reader) (*Parser, error)

New creates a new instance of SolGo. It takes a context and an io.Reader from which the Solidity contract is read. It initializes an input stream, lexer, token stream, and parser, and sets up error listeners.

func NewParserFromSources added in v0.1.6

func NewParserFromSources(ctx context.Context, sources *Sources) (*Parser, error)

NewParserFromSources creates a new instance of parser from a reader. It takes a context and an io.Reader from which the Solidity contract is read. It initializes an input stream, lexer, token stream, and parser, and sets up error listeners.

func (*Parser) GetAllListeners added in v0.1.6

func (s *Parser) GetAllListeners() map[ListenerName]antlr.ParseTreeListener

func (*Parser) GetContextualParser added in v0.1.6

func (s *Parser) GetContextualParser() *syntaxerrors.ContextualParser

GetContextualParser returns the ContextualParser which wraps the Solidity parser.

func (*Parser) GetInput added in v0.1.6

func (s *Parser) GetInput() io.Reader

GetInput returns the raw input reader from which the Solidity contract is read.

func (*Parser) GetInputStream added in v0.1.6

func (s *Parser) GetInputStream() *antlr.InputStream

GetInputStream returns the ANTLR input stream which is used by the lexer.

func (*Parser) GetLexer added in v0.1.6

func (s *Parser) GetLexer() *parser.SolidityLexer

GetLexer returns the Solidity lexer which tokenizes the input stream.

func (*Parser) GetListener added in v0.1.6

func (s *Parser) GetListener(name ListenerName) (antlr.ParseTreeListener, error)

func (*Parser) GetParser added in v0.1.6

func (s *Parser) GetParser() *parser.SolidityParser

GetParser returns the Solidity parser which parses the token stream.

func (*Parser) GetSources added in v0.1.6

func (s *Parser) GetSources() *Sources

GetSources returns the sources of the Solidity contract.

func (*Parser) GetTokenStream added in v0.1.6

func (s *Parser) GetTokenStream() *antlr.CommonTokenStream

GetTokenStream returns the stream of tokens produced by the lexer.

func (*Parser) GetTree added in v0.1.6

func (s *Parser) GetTree() antlr.ParseTree

GetTree returns the root of the parse tree that results from parsing the Solidity contract.

func (*Parser) IsListenerRegistered added in v0.1.6

func (s *Parser) IsListenerRegistered(name ListenerName) bool

func (*Parser) Parse added in v0.1.6

func (s *Parser) Parse() []syntaxerrors.SyntaxError

Parse initiates the parsing process. It walks the parse tree with all registered listeners and returns any syntax errors that were encountered during parsing.

func (*Parser) RegisterListener added in v0.1.6

func (s *Parser) RegisterListener(name ListenerName, listener antlr.ParseTreeListener) error

type SourceUnit added in v0.1.6

type SourceUnit struct {
	Name    string `yaml:"name" json:"name"`
	Path    string `yaml:"path" json:"path"`
	Content string `yaml:"content" json:"content"`
}

SourceUnit represents a unit of source code in Solidity. It includes the name, path, and content of the source code.

func (*SourceUnit) ToProto added in v0.2.0

func (s *SourceUnit) ToProto() *sources_pb.SourceUnit

ToProto converts a SourceUnit to a protocol buffer SourceUnit.

type Sources added in v0.1.6

type Sources struct {
	SourceUnits          []*SourceUnit `yaml:"source_units" json:"source_units"`
	EntrySourceUnitName  string        `yaml:"entry_source_unit" json:"base_source_unit"`
	MaskLocalSourcesPath bool          `yaml:"mask_local_sources_path" json:"mask_local_sources_path"`
	LocalSourcesPath     string        `yaml:"local_sources_path" json:"local_sources_path"`
	// contains filtered or unexported fields
}

Sources represents a collection of SourceUnit. It includes a slice of SourceUnit and the name of the entry source unit.

func NewSourcesFromMetadata added in v0.2.0

func NewSourcesFromMetadata(md *metadata.ContractMetadata) *Sources

NewSourcesFromMetadata creates a Sources from a metadata package ContractMetadata. This is a helper function that ensures easier integration when working with the metadata package.

func (*Sources) ArePrepared added in v0.2.0

func (s *Sources) ArePrepared() bool

ArePrepared returns true if the Sources has been prepared.

func (*Sources) GetCombinedSource added in v0.1.6

func (s *Sources) GetCombinedSource() string

GetCombinedSource combines the content of all SourceUnits in the Sources into a single string, separated by two newlines.

func (*Sources) GetLocalSource added in v0.1.6

func (s *Sources) GetLocalSource(partialPath string, relativeTo string) (*SourceUnit, error)

GetLocalSource attempts to find a local source file that matches the given partial path. It searches relative to the provided path and returns a SourceUnit representing the found source. If no matching source is found, it returns nil.

The function replaces any instance of "@openzeppelin" in the partial path with the actual path to the openzeppelin-contracts repository. It then walks the file tree starting from "./sources/", checking each file against the new path.

If the new path contains "../", it removes this and looks for the file in the parent directory. If a match is found, it creates a new SourceUnit with the name and path of the file, and returns it.

If no "../" is present in the new path, it simply creates a new SourceUnit with the name and path.

After a SourceUnit is created, the function checks if the file at the path exists. If it does, it reads the file content and assigns it to the SourceUnit's Content field. If the file does not exist, it returns an error.

If the walk function encounters an error other than ErrPathFound, it returns the error. If the source is still nil after the walk, it returns nil.

func (*Sources) GetSourceUnitByName added in v0.1.6

func (s *Sources) GetSourceUnitByName(name string) *SourceUnit

GetSourceUnitByName returns the SourceUnit with the given name from the Sources. If no such SourceUnit exists, it returns nil.

func (*Sources) GetSourceUnitByPath added in v0.1.6

func (s *Sources) GetSourceUnitByPath(path string) *SourceUnit

GetSourceUnitByPath returns the SourceUnit with the given path from the Sources. If no such SourceUnit exists, it returns nil.

func (*Sources) Prepare added in v0.1.6

func (s *Sources) Prepare() error

Prepare validates and prepares the Sources. It checks if each SourceUnit has either a path or content and a name. If a SourceUnit has a path but no content, it reads the content from the file at the path.

func (*Sources) SortContracts added in v0.2.1

func (s *Sources) SortContracts() error

SortContracts sorts the SourceUnits based on their dependencies.

func (*Sources) SourceUnitExists added in v0.1.6

func (s *Sources) SourceUnitExists(name string) bool

SourceUnitExists returns true if a SourceUnit with the given name exists in the Sources.

func (*Sources) SourceUnitExistsIn added in v0.1.6

func (s *Sources) SourceUnitExistsIn(name string, units []*SourceUnit) bool

SourceUnitExistsIn returns true if a SourceUnit with the given name exists in the given slice of SourceUnits.

func (*Sources) ToProto added in v0.2.0

func (s *Sources) ToProto() *sources_pb.Sources

ToProto converts a Sources to a protocol buffer Sources.

func (*Sources) TruncateDir added in v0.2.0

func (s *Sources) TruncateDir(path string) error

TruncateDir removes all files and subdirectories within the specified directory.

func (*Sources) WriteToDir added in v0.2.0

func (s *Sources) WriteToDir(path string) error

WriteToDir writes each SourceUnit's content to a file in the specified directory.

Directories

Path Synopsis
Package abi provides functionality for parsing and manipulating Solidity contract ABIs (Application Binary Interfaces).
Package abi provides functionality for parsing and manipulating Solidity contract ABIs (Application Binary Interfaces).
Package ast provides an Abstract Syntax Tree (AST) representation for Solidity contracts.
Package ast provides an Abstract Syntax Tree (AST) representation for Solidity contracts.
Package audit provides a comprehensive suite of tools for auditing smart contracts.
Package audit provides a comprehensive suite of tools for auditing smart contracts.
Package bytecode provides tools for decoding and analyzing Ethereum contract, transaction, event and log bytecode.
Package bytecode provides tools for decoding and analyzing Ethereum contract, transaction, event and log bytecode.
Package detector provides helpers for accessing solgo packages.
Package detector provides helpers for accessing solgo packages.
Package eip provides structures and functions to represent and manipulate Ethereum Improvement Proposals (EIPs) and Ethereum standards.
Package eip provides structures and functions to represent and manipulate Ethereum Improvement Proposals (EIPs) and Ethereum standards.
Package ir provides an intermediate representation of the AST.
Package ir provides an intermediate representation of the AST.
Package metadata provides functionality for interacting with IPFS/SWARM and retrieving contract metadata.
Package metadata provides functionality for interacting with IPFS/SWARM and retrieving contract metadata.
Package opcode offers tools for constructing and visualizing opcode execution trees, representing sequences of instructions.
Package opcode offers tools for constructing and visualizing opcode execution trees, representing sequences of instructions.
Package solc provides functionality related to the Solidity compiler (solc).
Package solc provides functionality related to the Solidity compiler (solc).
Package syntaxerrors provides tools for detecting and handling syntax errors in Solidity contracts.
Package syntaxerrors provides tools for detecting and handling syntax errors in Solidity contracts.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL