• Stars
    star
    125
  • Rank 286,335 (Top 6 %)
  • Language Dafny
  • License
    Apache License 2.0
  • Created almost 3 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An EVM interpreter in Dafny

License made-for-VSCode

Common Tests Passing Checks

Table of Contents

  1. Table of Contents
  2. Overview
    1. Dafny
    2. Semantics Example
  3. Getting Started
  4. Verifying Bytecode
  5. Building the Code
    1. Java target
      1. Test Generation
    2. Go target
  6. Contributing
  7. Resources

Overview

In this project we develop the Dafny-EVM, a functional specification of the Ethereum Virtual Machine in Dafny.

This type of specification has several advantages:

  • it is programming-language agnostic and easily readable: it does not require any prior knowledge of a specific programming language, but rather defines the semantics of the EVM as functions and compositions thereof. Read more
  • it is executable: we can run EVM bytecode, and in effect we have an interpreter of EVM bytecode. Read more
  • it is verified. We guarantee that our EVM interpreter is free of runtime errors (e.g. division by zero, arithmetic under/overflow). Read more
  • it provides a usable API for formal verification of EVM bytecode. Read more

Developing this specification in Dafny allows us to apply formal reasoning to Smart Contracts at the EVM Bytecode level. For example, one can prove that certain key properties are maintained by the contract. We choose Dafny over other verification systems (e.g. Coq or Isabelle/HOL) because it is relatively accessible to someone without significant prior experience.

Our functional specification is executable, meaning that we can run bytecode using it and compare their output with existing clients (e.g. Geth). In particular, we are interested in comparing against the Ethereum Common Reference Tests and have made some progress towards this.

Dafny

Dafny supports automated software verification by leveraging the power of state-of-the-art automated theorem provers (e.g. with SMT solvers like Z3). This means Dafny can prove a program is correct with respect to its specification. To do this, Dafny requires the developer to provide annotations in the form of preconditions and postconditions where appropriate, and/or loop invariants as necessary.

Semantics Example

Our semantics is written as a state transformer of type State -> State.

As a simple example, consider the following specification given for the semantics of the ADD bytecode:

/**
 * Unsigned integer addition with modulo arithmetic.
 * @param   st  A state.
 * @returns     The state after executing an `ADD` or an `Error` state.
 */
function method Add(st: State): (st': State)
    requires st.IsExecuting() 
    ensures st'.OK? || st' == INVALID(STACK_UNDERFLOW)
    ensures st'.OK? <==> st.Operands() >= 2
    ensures st'.OK? ==> st'.Operands() == st.Operands() - 1
{
    if st.Operands() >= 2
    then
        var lhs := st.Peek(0) as int;
        var rhs := st.Peek(1) as int;
        var res := (lhs + rhs) % TWO_256;
        st.Pop().Pop().Push(res as u256).Next()
    else
        State.INVALID(STACK_UNDERFLOW)
}

This tells us that ADD requires two operands on the stack to be performed, otherwise, the exceptional state INVALID(STACK_UNDERFLOW) state is reached.
When more than two operands are on the stack, addition employs modulo arithmetic (hence, overflows wrap around) and the final result (of the addition modulo) is pushed onto the stack after the operands are popped, and then the program counter is advanced by 1.

The postcondition ensures st'.OK? <==> st.Operands() >= 2 specifies a strong guarantee on the code in the body of function: for any input state st, Add returns an OK state (non-failure) if and only if the stack in the input state st has at least two elements (Operands()). Note that this postcondition is checked by the Dafny verification engine at compile-time not at runtime.

Getting Started

To use our code base you may follow these steps:

Verifying Bytecode

Our EVM is written in Dafny. As a result we can instrument bytecode with some reasoning features. Some examples are given in the verification examples document.

Building the Code

Dafny has to be translated to a target language to be run and to access functionality not included natively in Dafny. We have currently 2 target languages: Go and Java.

Java target

The Java target uses the gradle build system. To build the code, you need the following components:

With these installed, you can build the code using the following command:

> gradle build

This will verify the codebase using Dafny along with some examples, generate a Java implementation of the EVM, and run two test suites against it in Java.

Test Generation

As the main purpose of our EVM is to reason about bytecode, we may want to have some guarantees that the proofs we develop are also valid on other EVM implementations: if the same code is run on another implementation then the guarantees (e.g. no stack under/overflow) that we obtain using our automated reasoning and our EVM are still valid. This requires to prove that the other implementation produces exactly the same computations as our EVM on all inputs and for all programs. It is not practical to formally prove this kind of equivalence.

However we can compare the results of the execution of some bytecode on different implementations. If for a large number of tests two implementations give the same results (sequences of states), we have some confidence that the two implementations are equivalent. If our EVM yields the same results as, say the Geth's evm tools, then we can be confident that our proofs on the bytecode should be valid on the Geth EVM too.

The test cases used for the Dafny EVM are stored in the tests/ directory. These are generated from the Ethereum Consensus Tests using Geth's evm tool. Each test is a json file similar in structure to that used by the Ethereum Consensus Tests, except that they include full trace data (i.e. the state of the EVM after every execution step).

To regenerate the trace tests, you need to ensure the fixtures submodule is updated appropriately. If you originally employed git clone --recursive when cloning the repository, then you don't need to do anything. Otherwise, you can do this:

git submodule update --init

Using gradle one can now regenerate all the trace tests as follows:

> gradle testgen

This can take several minutes to complete, and requires that Geth's evm tool is installed and visible on PATH (we currently recommend version 1.10.25 or later). Furthermore, the test generation process is governed by the files tests/includes.txt and tests/excludes.txt. The former determines which of the reference tests should be included, whilst the latter identifies specific cases to exclude. Finally, the trace generation process is managed by the EvmTools framework.

Go target

The Go target uses GNU Make for its build system (preferably v4 or later). In macOS, it can be installed with brew install make, which installs it as gmake.

The code is currently being developed with Dafny 3.10, Go 1.19; all available in brew.

The GNUMakefile contains multiple targets to ease development:

  • dafny runs verification, translation and tests on the Dafny code.
    • Each stage can be run independently with dafny_verify, dafny_translate, dafny_test
    • You can add _clean to those to remove their products and witnesses.
    • Or you can add _force instead to rerun them even if there were no changes.
  • clean cleans all build products and verification and test witnesses.
  • run builds and runs the Dafny Main entry point. You can provide arguments adding RUN_ARGS="--gas 100".
    • This is for convenience; a standard executable is nonetheless generated at build/dafnyexec.

For example, you can run the Dafny main like this:

> gmake run RUN_ARGS="--gas 100"

Contributing

See the CONTRIBUTORS file for more information on contributing to this repository. By default contributors accept the terms of the license. We also endeavour to follow the conventions of the Dafny style guide.

Resources

The architecture of our Dafny-EVM: ARCHITECTURE.md

Some useful links:

More Repositories

1

smart-contract-best-practices

A guide to smart contract security best practices
HTML
7,473
star
2

ethereum-developer-tools-list

A guide to available tools and platforms for developing on Ethereum.
5,321
star
3

quorum

A permissioned implementation of Ethereum supporting data privacy
Go
4,581
star
4

mythril

Security analysis tool for EVM bytecode. Supports smart contracts built for Ethereum, Hedera, Quorum, Vechain, Rootstock, Tron and other EVM-compatible blockchains.
Python
3,817
star
5

Tokens

Ethereum Token Contracts
JavaScript
2,059
star
6

eth-lightwallet

Lightweight JS Wallet for Node and the browser
JavaScript
1,466
star
7

gnark

gnark is a fast zk-SNARK library that offers a high-level API to design circuits. The library is open source and developed under the Apache 2.0 license
Go
1,383
star
8

surya

A set of utilities for exploring Solidity contracts
JavaScript
1,076
star
9

ethql

A GraphQL interface to Ethereum 🔥
TypeScript
623
star
10

abi-decoder

Nodejs and Javascript library for decoding data params and events from ethereum transactions
JavaScript
605
star
11

vscode-solidity-auditor

Solidity language support and visual security auditor for Visual Studio Code
JavaScript
568
star
12

teku

Java Implementation of the Ethereum 2.0 Beacon Chain
Java
557
star
13

cakeshop

An integrated development environment and SDK for Ethereum-like ledgers
JavaScript
507
star
14

gnark-crypto

gnark-crypto provides elliptic curve and pairing-based cryptography on BN, BLS12, BLS24 and BW6 curves. It also provides various algorithms (algebra, crypto) of particular interest to zero knowledge proof systems.
Go
487
star
15

Token-Factory

Basic Token Factory dapp.
JavaScript
479
star
16

constellation

Peer-to-peer encrypted message exchange
Haskell
379
star
17

UniversalToken

Implementation of Universal Token for Assets and Payments
JavaScript
346
star
18

doc.linea

Linea documentation
JavaScript
338
star
19

quorum-examples

Examples for Quorum
Shell
317
star
20

scribble

Scribble instrumentation tool
TypeScript
315
star
21

anonymous-zether

A private payment system for Ethereum-based blockchains, with no trusted setup.
Solidity
295
star
22

defi-score

DeFi Score: An open framework for evaluating DeFi protocols
Python
280
star
23

EthOn

EthOn - The Ethereum Ontology
HTML
245
star
24

solidity-metrics

Solidity Code Metrics
JavaScript
235
star
25

Mahuta

IPFS Storage service with search capability
Java
230
star
26

tessera

Tessera - Enterprise Implementation of Quorum's transaction manager
Java
169
star
27

PLCRVoting

Partial Lock Commit Reveal Voting System that utilizes ERC20 Tokens
JavaScript
169
star
28

ethjsonrpc

Python JSON-RPC client for the Ethereum blockchain
Python
156
star
29

linea-attestation-registry

Verax is a shared registry for storing attestations of public interest on EVM chains, designed to enhance data discoverability and consumption for dApps across the network.
TypeScript
129
star
30

zero-knowledge-proofs

Zero Knowledge Proofs and how they can be implemented in Quorum
C++
128
star
31

python-solidity-parser

An experimental Solidity parser for Python built on top of a robust ANTLR4 grammar 📚
Python
125
star
32

truffle-security

MythX smart contract security verification plugin for Truffle Framework
JavaScript
124
star
33

solc-typed-ast

A TypeScript package providing a normalized typed Solidity AST along with the utilities necessary to generate the AST (from Solc) and traverse/manipulate it.
TypeScript
123
star
34

web3signer

Web3Signer is an open-source signing service capable of signing on multiple platforms (Ethereum1 and 2, Filecoin) using private keys stored in an external vault, or encrypted on a disk.
Java
122
star
35

daedaluzz

Benchmark Generator for Smart-Contract Fuzzers
Solidity
120
star
36

btcrelay-fetchd

Just the fetchd script of btcrelay
Python
116
star
37

ethsigner

DEPRECATED. A transaction signing application to be used with a web3 provider.
Java
112
star
38

ethereum-dissectors

🔍Wireshark dissectors for Ethereum devp2p protocols
C
109
star
39

quorum-dev-quickstart

The Quorum Developer Quickstart utility can be used to rapidly generate local Quorum blockchain networks for development and demo purposes using Besu, GoQuorum, and Codefi Orchestrate.
Solidity
108
star
40

truffle-webpack-demo

A demo Webpack + React App using truffle-solidity-loader
JavaScript
95
star
41

orion

Orion is a PegaSys component for doing private transactions
Java
92
star
42

blockchainSecurityDB

JavaScript
90
star
43

quorum-kubernetes

Helm charts for Hyperledger Besu and GoQuorum
Mustache
85
star
44

quorum-docs

Documentation assets for Quorum
84
star
45

mythx-cli

A command line interface for the MythX smart contract security analysis API
Python
83
star
46

gpact

General Purpose Atomic Crosschain Transaction Protocol
Java
81
star
47

bytecode-verifier

Compile Solidity source code and verify its bytecode matches the blockchain
JavaScript
80
star
48

goff

goff (go finite field) is a unix-like tool that generates fast field arithmetic in Go.
Go
76
star
49

starknet-snap

The MetaMask Snap for Starknet
TypeScript
74
star
50

linea-contracts

Linea smart-contracts
Solidity
73
star
51

eth2.0-dafny

Eth2.0 spec in Dafny
Dafny
72
star
52

zsl-q

ZSL on Quorum
C++
71
star
53

security-workshop-for-devs

Secure smart contract development workshop hosted by ConsenSys Diligence and MythX.
70
star
54

Legions

Ethereum/EVM Node Security Toolkit
Python
69
star
55

support-metamask-io

Public-facing repository of content live on support.metamask.io. Open for contributions and suggestions.
MDX
66
star
56

quorum-docker-Nnodes

Run a bunch of Quorum nodes, each in a separate Docker container.
Shell
65
star
57

Project-Alchemy

Ethereum-Zcash Integration effort
63
star
58

handel

Multi-Signature Aggregation in a Large Byzantine Committees
Go
53
star
59

qubernetes

Quorum on Kubernetes.
Go
52
star
60

Uniswap-audit-report-2018-12

51
star
61

quorum-tools

Tools for running Quorum clusters and integration tests
Haskell
51
star
62

doc.teku

ConsenSys Ethereum 2.0 client
CSS
47
star
63

vscode-solidity-metrics

Generate Solidity Source Code Metrics, Complexity and Risk profile reports for your project.
JavaScript
46
star
64

private-networks-deployment-scripts

This repository contains out-of-the-box deployment scripts for private PoA networks
Shell
45
star
65

awesome-quorum

A curated list of awesome softwares, libraries, tools, articles, educational resources, discussion channels and more to build on ConsenSys Quorum.
45
star
66

wittgenstein

Simulator for some PoS or consensus algorithms. Includes dfinity, casper IMD and others
Java
45
star
67

linea-tutorials

An EVM-equivalent zk-rollup for scaling Ethereum dapps
Shell
43
star
68

vscode-ethover

Ethereum Account Address Hover Info and Actions
JavaScript
42
star
69

permissioning-smart-contracts

Smart contracts for the Besu permissioning system
TypeScript
41
star
70

besu-sample-networks

Hyperledger Besu Ethereum client quick-start makes you able to simply test all Besu features.
40
star
71

linea-token-list

Linea Token List
TypeScript
39
star
72

0x-review

Security review of 0x smart contracts
HTML
39
star
73

quorum-key-manager

A universal Key & Account Management solution for blockchain applications.
Go
39
star
74

mythx-playground

Exercises to go along with smart contract security workshops by MythX and ConsenSys Diligence
Solidity
39
star
75

kubernetes-action

GitHub Action to run kubectl
Dockerfile
38
star
76

evm-analyzer-benchmark-suite

A benchmark suite for evaluating the precision of EVM code analysis tools.
HTML
38
star
77

quorum-cloud

Deploy Quorum network in a cloud provider of choice
HCL
36
star
78

quorum.js

Quorum.js is an extension to web3.js providing support for JP Morgan's Quorum API
JavaScript
36
star
79

web3js-eea

EEA JavaScript libraries.
JavaScript
35
star
80

truffle-solidity-loader

A Webpack loader that will parse and provision Solidity files to Javascript using Truffle for compilation
JavaScript
35
star
81

secureum-diligence-bootcamp

Solidity
35
star
82

rimble-app-demo

React Ethereum dApp demonstrating onboarding and transaction UX
JavaScript
35
star
83

linea-monorepo

The principal Linea repository. This mainly includes the smart contracts covering Linea's core functions, the prover in charge of generating ZK proofs, the coordinator responsible for multiple orchestrations, and the postman to execute bridge messages.
Go
35
star
84

linea-tracer

Part of the Linea stack responsible for extracting data from the execution of an EVM client in order to construct large matrices called execution traces.
Java
34
star
85

infura-sdk

Infura NFT SDK
TypeScript
34
star
86

web3studio-soy

Static Websites on the Distributed Web
JavaScript
33
star
87

pythx

A Python library for the MythX smart contract security analysis platform
Python
33
star
88

quorum-aws

Tools for deploying Quorum clusters to AWS
HCL
33
star
89

react-metamask

JavaScript
32
star
90

diligence-fuzzing

Python
32
star
91

boilerplate-react

React app boilerplate by ConsenSys France
JavaScript
29
star
92

hellhound

HellHound is a decentralized blind computation platform.
Go
29
star
93

aragraph

Visualize your Aragon DAO Templates
JavaScript
29
star
94

quorum-wizard

Quorum Wizard is a command line tool that allow users to set up a development Quorum network on their local machine in less than 2 minutes.
JavaScript
28
star
95

doc.goquorum

Documentation site for GoQuorum, the ConsenSys Enterprise Ethereum client
CSS
27
star
96

quorum-explorer

A light-weight front-end explorer for Besu and GoQuorum to visualise private networks and deploy smart contracts
TypeScript
27
star
97

mythxjs

TypeScript
26
star
98

hackathon-2021-dapp-workshop

JavaScript
25
star
99

0x_audit_report_2018-07-23

0x Protocol v2 Audit
HTML
24
star
100

web3js-quorum

JavaScript
24
star