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.
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 👀
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.
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
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.
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
Or completing one of the ethernaut challenges!
Imagine what it could do with more tools.
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.
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?
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:
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.
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.
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
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.
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
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
I’ll provide documentation on how to design UI extensions in a later article.
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.