Announcing the ethernaut-cli

A safe haven for builders

Optimism’s Retroactive Public Goods Funding (RetroPGF) is fuel for creativity.

Yes, its idea is radical, but what it enables is even more so. We basically have a new funding primitive that lets us focus on what we truly want to build, worrying about money later—or even not ever.

This removes clutter from our work. It opens doors.

So, thank you Optimism. You are amazing <3

One hiccup with RetroPGF, from this perspective, is that you can’t just quit your job and start building on day 1. You gotta pay the bills, or at least not burn your savings. Most of us can’t go without receiving any sort of payment or funding for 6 months, or a year. You'd also be banking on the hope that, by the end of the RetroPGF round, you’ve generated enough impact to be noticed and valued.

That’s why we're morphing the EthernautDAO into a kind of “RetroPGF buffer”. This is the spirit of the DAO after all; we want to offer a safe haven for devs and builders in transition. Initially, our focus was on devs in transition from web2 to web3, but what we’re really about is empowering builders in transition from A to B. From anything to anything.

And right now, we want to focus on helping devs transition from not-doing-what-they-love to yes-doing-what-they-love!

So, the RetroPGF buffer concept is pretty straightforward. You come to the DAO, pitch your project, if it has potential to make an impact in the next RetroPGF round, we give you feedback, assist in the build, and guide you through the RetroPGF application. We do apply separately for having supported you, but your application is 100% independent from ours.

Meanwhile, we provide you with a salary to cover your living expenses while you are building, allowing you to concentrate fully on your creation. When you receive your OP from RetroPFG, it's 100% yours. We have no claim on it. And when we receive ours, we allocate a portion to an internal RetroPGF round for DAO members that contributed to the value added by the DAO. We also save a big chunk in the buffer, enabling us to continue offering this support to others.

That’s right, we don’t ask for anything in return. We simply want you to build cool shit because we believe that creations that come from this place of untangledness have the power to change the world. It’s that simple.

And who are we? We are just other devs. Other builders. The EthernautDAO is a co-op of builders.

The toy

So how can we demonstrate this beautiful idea?

We’ve built a little toy.

Something that we know has potential, but also something we don’t want to contaminate with features that are just intended for fundraising. The whole point of what we built, is to demonstrate that we profoundly believe in the principles presented above. And that you can come and do the same thing: Build what you really want to build.

And yes, we also built it for fun.

Here it is, the “ethernaut-cli”.

What is it? It’s basically a composable web3 AI agent, with a command line interface. You can call it “ChatGPT for web3”.

Its also a CLI that can be used by everyone, no matter the level of technical expertise: ultra-hackers, devs, and absolutely non-technical users, maybe even normies some day.

IMO it has so much potential that it most likely wont be a toy for long.

Check it out 👀

First glimpse of the ethernaut-cli
First glimpse of the ethernaut-cli

Would you like to try it out?

The installation is meant to be super simple, just

$ npm i -g ethernaut-cli
$ ethernaut -v
> ethernaut-cli v1.0.15

You’ll also need Anvil for the network package

curl -L https://foundry.paradigm.xyz | bash

Sweet! Now lets try out a command

$ ethernaut util token usdt

This should output a list of addresses related to the Tether USDT token.

 Found 5 matches for "usdt" in any network:                                                                     
                                                                                                                
 0. Tether (USDT) Address: 0xdAC17F958D2ee523a2206206994597C13D831ec7 in Ethereum Mainnet (Rating: 1)           
 1. Aave Interest bearing USDT (aUSDT) Address: 0xC2102b921b49ea863476fa5Cc9E5851dCE8cc699 in Ethereum Mainnet  
 (Rating: 0.8571428571428571)                                                                                   
 2. Compound USDT (cUSDT) Address: 0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9 in Ethereum Mainnet (Rating:      
 0.8571428571428571)                                                                                            
 3. Fluid USDT (FUSDT) Address: 0xADc234a4e90E2045f353F5d4fCdE66144d23b458 in Ethereum Mainnet (Rating:         
 0.8571428571428571)                                                                                            
 4. Fulcrum USDT iToken (iUSDT) (iUSDT) Address: 0x7e9997a38A439b2be7ed9c9C4628391d3e055D48 in Ethereum         
 Mainnet (Rating: 0.8571428571428571)                                                                           

Let’s break that apart

ethernaut    <- thats me! No, its the toy.
util         <- the util scope
token        <- the token task for finding token addresses
usdt         <- the keyword parameter for the token search

A scope is just a bunch of tasks with a particular theme. The util scope has common utilities. The interact scope allows you to interact with any network, etc.

Try some other commands

ethernaut util unit 42 --from ether --to wei
ethernaut challenges info 1
ethernaut util resolve vitalik.eth

Yup, it’s just a good old regular Hardhat CLI. The only difference here is that this one is meant to be installed globally, as opposed to a local project installation.

Hint: Unsure what to try out? Just type ethernaut and let the CLI guide you :) More on this UI navigation feature later.

Yeah, yeah nice, but I don’t have time to learn a new tool

You don’t have to.

The AI can actually do the work for you, teach you how to use the CLI, and you can even use it to learn web3.

Something I’ve always fringed about with CLIs, which I believe makes them unusable for non-technical users, is that the command line interface is pretty tedious. You have to understand the syntax, remember the commands, its parameters, and its peculiarities.

I do love command line interfaces, but I hate this particular UX that expects you to remember everything. I think that we can do more.

I wish a CLI could process gibberish like this right?

$ ethernaut what is the address of usdt

Well, this one can

Natural language interpretation
Natural language interpretation

Wat in the world is going on here?

First, you see a few messages that show you that what you typed has been identified as a natural language query instead of a CLI command, and is being routed to the “interpret” task within the “ai” scope.

It took a bit of hacking, but this pre-parses the instructions with Hardhat, and if that blows up, the AI kicks in.

Your query is actually given to an OpenAI ChatGPT assistant that has access to all the CLIs tasks as its tools. With that knowledge, it processes your query, and replies with a suggestion to run one of these commands.

In this case, it suggested the use of the token task, which is exactly the task we used before.

Whenever the CLI’s AI suggests actions, it presents a summary (in this case, it's just one action, but it can do several in parallel) and it will then iterate over each action to see what you’d like to do with it. When jumping into each one, it will show you the associated command and the parameters to be used.

You can then choose to execute the command, edit it, to explain the rationale of why the tool was chosen, or just to skip this particular command.

You can also run the ai interpret task with the --no-confirm flag and let the AI do its thing. Just be careful what you ask. By the time you return with your coffee, the Singularity might have occurred.

Now imagine…

This is where the fun really starts.

This CLI is so much more than a simple experiment. I took it seriously and built it as a framework, because what can give this tool its spark and complexity, is the tools we give to it. We can collaborate on this and come up with all sorts of crazy use cases.

You can easily build new tools for the AI to use, throw them in the mix, and see what happens. Who knows, maybe this is how AGI happens 😆

I did my best to ship this thing with the minimal amount of tasks for it to do interesting things, so here are ~40 tasks that are included in the Beta release.

ai: AI assistant that interprets user input and executes Hardhat tasks
  config        Configures ai scope parameters
  interpret     Interprets natural language into CLI commands
  
challenges: Tasks for playing the Open Zeppelin Ethernaut challenge
  check         Checks if the player has completed the specified level
  check-all     Checks all levels that have been completed
  info          Shows information about an open zeppelin challenges level 
  instance      Creates an instance of a level
  submit        Submits an instance created by the instance task
  
interact: Tasks for interacting with a network
  add-abi       Add an ABI to the list of known ABI paths
  balance       Queries the ETH or TOKEN balance of an address
  contract      Interacts with a contract
  find-abi      Given part of a name of an abi
  info          Retrieves information about a contract
  logs          Finds logs emitted by a contract
  send          Sends ether to an address
  token         Interacts with any ERC20 token
  
network: Tasks for interacting with different networks
  add           Adds a network to the cli
  current       Prints the active network
  edit          Edits a network
  info          Provides information about a network
  list          Prints all networks
  node          Starts a local development chain, potentially with a fork.
  remove        Removes a network from the cli
  set           Sets the active network
  
util: Simple, everyday utilities for Ethereum devs
  bytes         Converts strings to bytes32
  checksum      Computes or validates the checksum of an address
  lookup        Lookup the address of an ens name
  resolve       Resolves an ens name to an address
  string        Converts bytes32 to string
  token         Tries to find the address of a token
  unit          Converts between different units of Ether
  gas           Fetch gas info on the current network
  
wallet: Tasks for interacting from different Ethereum accounts
  add           Adds a wallet
  current       Shows which wallet is active
  info          Shows information about a wallet
  list          Lists all wallets
  remove        Removes a wallet
  set           Sets the active wallet
  sign          Signs a message with the active wallet
  watch         Adds a wallet with no private key

With just these tasks, you can do pretty wild things. Like asking questions about the allowance of an address

Asking the AI about your allowance
Asking the AI about your allowance

Or completing one of the ethernaut challenges!

Ask the AI to solve an ethernaut challenge
Ask the AI to solve an ethernaut challenge

Imagine what it could do with more tools.

Creating a task

If you’d like to add a task, you just have to create a new Hardhat task. Like this

const types = require('ethernaut-common/src/validation/types')
const output = require('ethernaut-common/src/ui/output')

require('../scopes/util')
  .task('resolve', 'Resolves an ens name to an address')
  .addPositionalParam('ens', 'The ens name to resolve', undefined, types.ens)
  .setAction(async ({ ens }, hre) => {
    try {
      const address = await hre.ethers.provider.resolveName(ens)

      if (!address) {
        throw new Error('Unable to resolve ens name')
      }

      return output.resultBox(address)
    } catch (err) {
      return output.errorBox(err)
    }
  })

There’s a bit of ethernaut-cli flavor here, but in its core, its just regular old Hardhat task.

Easy.

Pirates

Now, with your new task, how would you inform the AI of its new capabilities?

It’s simpler than you think; you just need a pretty powerful computer capable of training a modern language model, and a few thousand hours of computation… It’s preferable to live in a cold area with temperatures under -10C, or at least move there for a few months.

Haha. You don’t need to do anything.

The CLI takes the task descriptions defined in Hardhat tasks, and understands how the assistant needs to be reconfigured. It just fizzes up a new assistant and registers it with the OpenAI API. This is all done behind the scenes, so you don’t even need to worry about it.

All you have to do is document your tasks well. But we all do that already, right?

Right?

(sorry)
(sorry)

But yes, if you insist in doing some of the work yourself, you can provide additional instructions to the AI. In fact, many of the CLI's plugins do this already to give the AI a little bit more context about the tasks it defines.

The ethernaut-interact plugin tells the AI to not hallucinate with abi paths, because for some reason it really liked doing that. https://github.com/theethernaut/ethernaut-cli/blob/main/packages/ethernaut-interact/src/internal/assistants/configs/interact.json

You can tell the AI, for example, to always talk like a pirate. Which is definitely a worthy use case

// hardhat.config.js

module.exports = {
  solidity: '0.8.19',
  defaultNetwork: 'localhost',
  ethernaut: {
    ai: {
      interpreter: {
        additionalInstructions: ['Always talk like a pirate'],
      },
    },
  },
}

And then, it talks like a pirate!

$ ethernaut what is poop in bytes
> Ai response:
                                                                                                                           
"poop" in bytes is:                                                                                                        
                                                                                                                           
0x706f6f7000000000000000000000000000000000000000000000000000000000                                                         
                                                                                                                           
There ya have it, matey! Query any other phrases ye want to see in bytes, or ask me somethin' else if ye have a different  
quest!                                                                                                                     

I’ll work on additional tasks to make this fine tuning of the AI more capable.

Now, if this is blowing your mind and already have a few ideas for a bunch of tasks that accomplish some specific goal, my recommendation is that you build a Hardhat plugin.

I’ll just leave you with the docs and open the Pandora’s box:

Its all Hardhat plugins

Now, what’s really interesting about the CLI is that the CLI built 100% as Hardhat plugins, each of which works independently from the others.

Hardhat plugins that compose the ethernaut-cli
Hardhat plugins that compose the ethernaut-cli

For example, you could just use the ethernaut-ai plugin in your project and boom! It becomes sentient.

Which would make your project capable of handling this instruction

npx hardhat please compile my project and tell me a joke about byte arrays

Which is very important. Of course.

My beloved back-end UIs

Ah, how I love these things. I’m not sure why. I just do. Maybe what I am is a backend frontend developer. If I die, put this on my tombstone.

Anyways…

The CLI also comes with a pretty neat interactivity boost that allows you to navigate your tasks with enquirer prompts, and also uses the promts to collect missing arguments from your commands.

On one end of the spectrum we have ultra hackers, which like to type their commands by hitting their keyboards explosively, getting exactly what they want in like under a second.

On the other end of the spectrum, we have non technical users that can just use the AI they want.

But, is there a middle ground?

Yes. You don’t need to remember all the commands and parameters.

And its still fast

Interactive mode
Interactive mode

This is essentially the ethernaut-ui plugin, another component of the CLI.

Again, if you find this whole CLI concept an aberration in programming history, but you do appreciate this particular UI feature, you can simply use this plugin independently in your project. And that's that. You've added interactivity. Which will probably boost the productivity of your team by, I dunno, 27%?

Maybe the combined components of the CLI are a toy, but are the components by themselves a toy?

You can be the judge of that.

UI extensions

The UI plugin can do a bit more still. I've started to refer to some of the plugins that make up the CLI as "UI extensions". These are essentially plugins of plugins, designed to fine-tune the prompts of a plugin in a project that uses the ethernaut-ui plugin.

That’s a mouthful, right?

TL;DR it's just a way to refine the prompts. For instance, take the ethernaut-interact-ui extension, which offers a more engaging prompt for collecting the ABI of a contract. It utilizes the Etherscan API for auto-fetching it from the provided address.

Take a look

Custom prompt that fetches ABIs with Etherscan
Custom prompt that fetches ABIs with Etherscan

UI extensions can also implement suggestions, not just prompts. In this example, when you re-enter the same address on the same network, the plugin will recognize it and directly suggest the ABI path you used before.

Same command

Custom suggestions
Custom suggestions

I’ll provide documentation on how to design UI extensions in a later article.

Wrapping it up

So, that's our little toy!

I Hope you like it and have fun with it.

It’d be great if you could take a look at the repo https://github.com/theethernaut/ethernaut-cli, and perhaps even drop a little ⭐ in there?

Oh, and if you have an idea for a task but don’t know how to build or don’t have the time, also create an issue for a feature request and I’ll take of it.

Please keep in mind that this is a Beta release. I don’t promise that it won’t be buggy, but I do promise to work on it until its robust. So if you experience any problems, please do take the time to report an issue. It will be looked at.

But let’s circle back to our original intention.

I built this tool to have fun, and to demonstrate what we want to become in the EthernautDAO.

As I built this tool, you could build yours. With or without our help. If you want our help, come to the DAO with your ideas, and perhaps we can help you build it.

It can be a toy like this, a tool that the web3 industry is desperate for but no one has the time to build because their building their own thing, a mission request, anything that has value.

If you’re not enjoying what you’re coding right now, then maybe there’s something you’re missing; It’s supposed to be fun.

If you are then please continue what you’re doing.

Coding is beautiful. It's a very precise and practical language that allows us to build things that can totally reshape our world. It’s okay to be ambitious, and it's okay to do it from the heart, without any entanglement.

Optimism has opened a door with the RetroPGF funding primitive, and we at EthernautDAO want to push it just an inch further.

Subscribe to theethernaut.eth
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.