A drop-in replacement for `dapp` and `seth` in Rust

Related tags

dapptools-rs
Overview

dapptools.rs

Rust port of DappTools

Github Actions

dapp example Usage

Run Solidity tests

Any contract that contains a function starting with test is being tested. The glob passed to --contracts must be wrapped with quotes so that it gets passed to the internal command without being expanded by your shell.

$ cargo r --bin dapp test --contracts './**/*.sol'
    Finished dev [unoptimized + debuginfo] target(s) in 0.21s
     Running `target/debug/dapp test --contracts './**/*.sol'`
Running 1 tests for Foo
[PASS] testX (gas: 267)

Running 1 tests for GmTest
[PASS] testGm (gas: 25786)

Running 1 tests for FooBar
[PASS] testX (gas: 267)

Running 3 tests for GreeterTest
[PASS] testIsolation (gas: 3702)
[PASS] testFailGreeting (gas: 26299)
[PASS] testGreeting (gas: 26223)

You can optionally specify a regular expresion, to only run matching functions:

$ cargo r --bin dapp test --contracts './**/*.sol' -m testG
    Finished dev [unoptimized + debuginfo] target(s) in 0.26s
     Running `target/debug/dapp test --contracts './**/*.sol' -m testG`
Running 1 tests for GreeterTest
[PASS] testGreeting (gas: 26223)

Running 1 tests for GmTest
[PASS] testGm (gas: 25786)

Test output as JSON

In order to compose with other commands, you may print the results as JSON via the --json flag

$ ./target/release/dapp test -c "./**/*.sol" --json
{"GreeterTest":{"testIsolation":{"success":true,"gas_used":3702},"testFailGreeting":{"success":true,"gas_used":26299},"testGreeting":{"success":true,"gas_used":26223}},"FooBar":{"testX":{"success":true,"gas_used":267}},"Foo":{"testX":{"success":true,"gas_used":267}},"GmTest":{"testGm":{"success":true,"gas_used":25786}}}

Build the contracts

You can build the contracts by running, which will by default output the compilation artifacts of all contracts under src/ at out/dapp.sol.json:

$ ./target/release/dapp build

You can specify an alternative path for your contracts and libraries with --remappings, --lib-path and --contracts. We default to importing libraries from ./lib, but you still need to manually set your remappings.

In the example below, we see that this also works for importing libraries from different paths (e.g. having a DappTools-style import under lib/ and an NPM-style import under node_modules)

Notably, we need 1 remapping and 1 lib path for each import. Given that this can be tedious, you can do set remappings via the env var DAPP_REMAPPINGS, by setting your remapping 1 in each line

$ dapp build --out out.json \
    --remappings ds-test/=lib/ds-test/src/ \
    --lib-paths ./lib/
    --remappings @openzeppelin/=node_modules/@openzeppelin/ \
    --lib-path ./node_modules/@openzeppelin
$ echo $DAPP_REMAPPINGS
@openzeppelin/=lib/openzeppelin-contracts/
ds-test/=lib/ds-test/src/
$ dapp build --out out.json \
    --lib-paths ./lib/ \
    --lib-paths ./node_modules/@openzeppelin

Development

Rust Toolchain

We use the stable Rust toolchain. Install by running: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Building & testing

cargo check
cargo test
cargo doc --open
cargo build [--release]

Tip: If you encounter the following error when building the project, please update your Rust toolchain with rustup update.

error[E0658]: use of unstable library feature 'map_into_keys_values'

CLI Help

The CLI options can be seen below. You can fully customize the initial blockchain context. As an example, if you pass the flag --block-number, then the EVM's NUMBER opcode will always return the supplied value. This can be useful for testing.

Build

$ cargo r --bin dapp build --help
   Compiling dapptools v0.1.0
    Finished dev [unoptimized + debuginfo] target(s) in 3.45s
     Running `target/debug/dapp build --help`
dapp-build 0.1.0
build your smart contracts

USAGE:
    dapp build [FLAGS] [OPTIONS] [--] [remappings-env]

FLAGS:
    -h, --help          Prints help information
    -n, --no-compile    skip re-compilation
    -V, --version       Prints version information

OPTIONS:
    -c, --contracts <contracts>         glob path to your smart contracts [default: ./src/**/*.sol]
        --evm-version <evm-version>     choose the evm version [default: berlin]
        --lib-path <lib-path>           the path where your libraries are installed
    -o, --out <out-path>                path to where the contract artifacts are stored [default: ./out/dapp.sol.json]
    -r, --remappings <remappings>...    the remappings

ARGS:
    <remappings-env>     [env: DAPP_REMAPPINGS=]

Test

$ cargo r --bin dapp test --help
    Finished dev [unoptimized + debuginfo] target(s) in 0.31s
     Running `target/debug/dapp test --help`
dapp-test 0.1.0
build your smart contracts

USAGE:
    dapp test [FLAGS] [OPTIONS] [--] [remappings-env]

FLAGS:
    -h, --help          Prints help information
    -j, --json          print the test results in json format
    -n, --no-compile    skip re-compilation
    -V, --version       Prints version information

OPTIONS:
        --block-coinbase <block-coinbase>
            the block.coinbase value during EVM execution [default: 0x0000000000000000000000000000000000000000]

        --block-difficulty <block-difficulty>    the block.difficulty value during EVM execution [default: 0]
        --block-gas-limit <block-gas-limit>      the block.gaslimit value during EVM execution
        --block-number <block-number>            the block.number value during EVM execution [default: 0]
        --block-timestamp <block-timestamp>      the block.timestamp value during EVM execution [default: 0]
        --chain-id <chain-id>                    the chainid opcode value [default: 1]
    -c, --contracts <contracts>                  glob path to your smart contracts [default: ./src/**/*.sol]
        --evm-version <evm-version>              choose the evm version [default: berlin]
        --gas-limit <gas-limit>                  the block gas limit [default: 25000000]
        --gas-price <gas-price>                  the tx.gasprice value during EVM execution [default: 0]
        --lib-path <lib-path>                    the path where your libraries are installed
    -o, --out <out-path>
            path to where the contract artifacts are stored [default: ./out/dapp.sol.json]

    -m, --match <pattern>                        only run test methods matching regex [default: .*]
    -r, --remappings <remappings>...             the remappings
        --tx-origin <tx-origin>
            the tx.origin value during EVM execution [default: 0x0000000000000000000000000000000000000000]


ARGS:
    <remappings-env>     [env: DAPP_REMAPPINGS=]

Features

  • seth
    • --from-ascii
    • --to-hex
    • --to-checksum-address
    • --to-bytes32
    • block
    • call (partial)
    • send (partial)
    • balance
    • ens
  • dapp
    • test
      • simple unit tests
        • Gas costs
        • DappTools style test output
        • JSON test output
        • matching on regex
        • DSTest-style assertions support
      • fuzzing
      • symbolic execution
      • coverage
      • HEVM-style Solidity cheatcodes
      • structured tracing with abi decoding
      • per-line gas profiling
      • forking mode
      • automatic solc selection
    • build
      • can read DappTools-style .sol.json artifacts
      • manual remappings
      • automatic remappings
      • multiple compiler versions
      • incremental compilation
      • can read Hardhat-style artifacts
      • can read Truffle-style artifacts
    • debug
    • CLI Tracing with RUST_LOG=dapp=trace

Tested Against

This repository has been tested against the following DappTools repos: *

Issues
  • feat: seth --to-hex

    feat: seth --to-hex

    null

    opened by OdysLam 1
  • feat: `seth send`

    feat: `seth send`

    null

    opened by gakonst 0
  • feat: add test runner

    feat: add test runner

    • can call the vm directly w/ solidity(can deploy & interact)
    • can follow the dapptools pattern for writing solidity only tests
    opened by gakonst 0
  • feat: parallelism with rayon

    feat: parallelism with rayon

    null

    opened by gakonst 0
  • feat: support multiple compiler versions

    feat: support multiple compiler versions

    • if a version is not detected locally and is in your contracts, it automatically gets downloaded for you
    • it groups contracts by compiler and proceeds to execute them all together
    opened by gakonst 0
  • refactor: monorepo

    refactor: monorepo

    As title - splits into monorepo to better parallelize compilation time / isolate & organize code etc.

    opened by gakonst 0
  • Inform users to update in case of error [E0658]

    Inform users to update in case of error [E0658]

    If users try to build/check the project with an older version of rust, it will fail due to this error: error[E0658]: use of unstable library feature 'map_into_keys_values'.

    It is fixed with rustup update

    opened by OdysLam 0
  • feat: ens & balance

    feat: ens & balance

    Adds support for

    • seth resolve-name
    • seth lookup-address
    • seth balance

    Makes seth call, seth balance and seth send accept ENS names (they auto-resolve them internally).

    Finally, makes the singleton commands work with stdin so that they compose, e.g. you can do `seth

    opened by gakonst 0
  • test: share compilation step to avoid race condition

    test: share compilation step to avoid race condition

    There seems to be a race condition the first time the compilers are installed which makes later running the compilation step fail with:

    Installing 0.7.6
    Done!
    thread 'tests::failing_solidity_unit_test' panicked at '`"/home/runner/.svm/0.7.6/solc-0.7.6"` not found', /home/runner/.cargo/git/checkouts/ethers-rs-c3a7c0a0ae0fe6be/64294d1/ethers-core/src/utils/solc.rs:240:33
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

    This is fixed by running the compilation step once and then re-using the value across tests.

    I wonder why this is happening. Possibly due to some overwrite inside install when called multiple times in parallel?

    opened by gakonst 0
  • refactoring: first pass

    refactoring: first pass

    • move solidity builder to its own file
    • add some basic tracing
    • always default to --allow-paths .
    opened by gakonst 0
Owner
Georgios Konstantopoulos
blockchain scalability, information security and mechanism design. That Layer 2 guy. Aspiring Rustacean.
Georgios Konstantopoulos
fastmod is a fast partial replacement for the codemod tool

fastmod is a fast partial replacement for codemod. Like codemod, it is a tool to assist you with large-scale codebase refactors, and it supports most of codemod's options.

Facebook Incubator 1.2k Sep 9, 2021
A cat(1) clone with syntax highlighting and Git integration.

A cat(1) clone with syntax highlighting and Git integration. Key Features • How To Use • Installation • Customization • Project goals, alternatives [中

David Peter 29.4k Sep 15, 2021
A curated list of replacements for existing software written in Rust

Awesome Alternatives in Rust A curated list of replacements for existing software written in Rust. If you want to contribute, please read CONTRIBUTING

Takayuki Maeda 1.9k Sep 9, 2021
A readline replacement written in Rust

A readline replacement written in Rust Basic example // Create a default reedline object to handle user input use reedline::{DefaultPrompt, Reedline,

JT 89 Sep 5, 2021
exa is a modern replacement for ls.

exa exa is a modern replacement for ls. README Sections: Options — Installation — Development exa is a modern replacement for the venerable file-listi

Benjamin Sago 14.6k Sep 14, 2021
A thread-safe signal/slot library based on boost::signals2

About signals2 is a thread-safe signal/slot library based on the boost::signals2 C++ library. Signals are objects that contain a list of callback func

Christian Daley 11 Aug 25, 2021
procs is a replacement for ps written in Rust.

procs is a replacement for ps written in Rust. Documentation quick links Features Platform Installation Usage Configuration Features Output by t

null 2.2k Sep 12, 2021
Intuitive find & replace CLI (sed alternative)

sd - s[earch] & d[isplace] sd is an intuitive find & replace CLI. The Pitch Why use it over any existing tools? Painless regular expressions sd uses r

Gregory 2.5k Sep 12, 2021
zoxide is a blazing fast replacement for your cd command

zoxide A smarter cd command for your terminal zoxide is a blazing fast replacement for your cd command, inspired by z and z.lua. It keeps track of the

Ajeet D'Souza 3.7k Sep 18, 2021
This is choose, a human-friendly and fast alternative to cut and (sometimes) awk

Choose This is choose, a human-friendly and fast alternative to cut and (sometimes) awk Features terse field selection syntax similar to Python's list

Ryan Geary 874 Sep 15, 2021
ddi is a wrapper for dd. It takes all the same arguments, and all it really does is call dd in the background

ddi A safer dd Introduction If you ever used dd, the GNU coreutil that lets you copy data from one file to another, then you may have encountered a ty

Tomás Ralph 75 Jun 20, 2021
LSD (LSDeluxe) - The next gen ls command

LSD (LSDeluxe) Table of Contents Description Screenshot Installation Configuration External Configurations Required Optional F.A.Q. Contributors Credi

Pierre Peltier 6.3k Sep 18, 2021
Curated list of awesome projects and resources related to Rust and computer security

Awesome Rust Security Curated list of awesome projects and resources related to Rust and computer security Table of Contents Tools Web and Cloud Secur

Alan 12 Sep 6, 2021
fd is a program to find entries in your filesystem. It is a simple, fast and user-friendly alternative to find

fd is a program to find entries in your filesystem. It is a simple, fast and user-friendly alternative to find. While it does not aim to support all of find's powerful functionality, it provides sensible (opinionated) defaults for a majority of use cases.

David Peter 18.8k Sep 4, 2021
Execution of and interaction with external processes and pipelines

subprocess The subprocess library provides facilities for execution of and interaction with external processes and pipelines, inspired by Python's sub

Hrvoje Nikšić 298 Sep 12, 2021
miniserve - a CLI tool to serve files and dirs over HTTP

?? For when you really just want to serve some files over HTTP right now!

Sven-Hendrik Haase 2.6k Sep 15, 2021
Tool to draw low-resolution graphs in terminal

lowcharts Tool to draw low-resolution graphs in terminal. lowcharts is meant to be used in those scenarios where we have numerical data in text files

juanleon lahoz 24 Sep 4, 2021
Zellij is a workspace aimed at developers, ops-oriented people and anyone who loves the terminal

Zellij is a workspace aimed at developers, ops-oriented people and anyone who loves the terminal. At its core, it is a terminal multiplexer (similar to tmux and screen), but this is merely its infrastructure layer.

null 3.8k Sep 15, 2021
Run your Rust CLI programs as state machines with persistence and recovery abilities

step-machine Run your CLI programs as state machines with persistence and recovery abilities. When such a program breaks you'll have opportunity to ch

Imbolc 19 Aug 26, 2021