A Primer on Seth, Solidity's Swiss Army Knife
Tags: ethereum, blockchain, solidity, web3
Published: 2019-06-16 18:40:07

---
title: A Primer on Seth, Solidity's Swiss Army Knife
published: true
description: Tired of writing `new Web3` in a JS script just to check a balance? Annoyed about the friction of converting things to BigNumber, loading `Contract.json`, dealing with promises just to do something simple? Well let me introduce you to `seth`. Using `seth`, you can easily interact with smart contracts with the speed and dexterity of the command line. It's part of a suite of tools developed by the MakerDAO team, of DAI acclaim. In this post, you're going to go from 0 to hero.
tags: ethereum,blockchain,solidity,web3
---

Tired of writing `new Web3` in a JS script just to check a balance? Annoyed about the friction of converting things to BigNumber, loading `Contract.json`, dealing with promises just to do something simple? Well let me introduce you to `seth`. Using `seth`, you can easily interact with smart contracts with the speed and dexterity of the command line. It's part of a suite of tools developed by the MakerDAO team, of DAI acclaim. In this post, you're going to go from 0 to hero.

## Introduction to seth
The [Seth reference guide](https://github.com/dapphub/dapptools/tree/master/src/seth) on Github is great, but it misses some lessons that won't be obvious if you're not a power user of the CLI. I'm going to explain some really simple techniques from the perspective of these use cases:

 - deploying a Truffle contract
 - saving a contract's deployment address
 - calling methods and passing arguments
 - transacting from different accounts
 - converting units (numbers, eth)

### Installing seth
`seth` is part of the `dapptools` suite, which is a super-minimal package of software (like 5kB). Taken from their [Github instructions](https://github.com/dapphub/dapptools):

```bash
curl https://dapp.tools/install | sh
```

### Deploying a Truffle contract
Seth is based on the unix philosophy, which puts files at its core. You've probably gotten used to some monolithic framework like Truffle, which puts you in the backseat while it takes care of business. Running `truffle compile`, it will generate contract artifacts in the form of `build/contracts/ContractName.json`. And running `truffle migrate`, it will automatically take the bytecode of these contracts and deploy them.

It might seem scary, but the details aren't actually that complex to do ourselves! 

![](https://thepracticaldev.s3.amazonaws.com/i/784r3viwrckuhwkblkoz.png)
![](https://thepracticaldev.s3.amazonaws.com/i/4x41j7q1s4tpby6tbqcx.png)

But wait, what's the difference between `bytecode` and `deployedBytecode`? Well, when you deploy a contract in Ethereum, you're doing two things:

 1) you're creating a contract, which stores its runtime code on the chain
 2) you're calling the constructor

Simply put - the `deployedBytecode` is just the runtime, whereas the `bytecode` includes the code of the constructor. 

Let's see how easy it is to deploy a contract using seth. To begin with, we're going to install `jq`, a CLI tool which can parse JSON. You can find [installation instructions here](https://stedolan.github.io/jq/download/).

```bash
# Get the bytecode from the Truffle artifact
export CODE=$(cat build/contracts/ERC20.json | jq -r .bytecode)
```

#### Setting up seth's environment
Run the below to setup the environment variables seth needs to know:

```bash
# Connect to the local node
export ETH_RPC_URL=http://127.0.0.1:8545

# Disable below if not on Truffle
export ETH_GAS=4712388

# Use the unlocked RPC accounts
export ETH_RPC_ACCOUNTS=yes

# Get the 1st account and use it
export ETH_FROM=$(seth accounts | head -n1 | awk '{ print $1 }')
```

#### Deploying the contract
```bash
# We can write it simply
seth send --create $CODE

# Passing variables to the constructor
# In this example, the constructor is ERC20Detailed
# constructor(string name, string symbol, uint decimals)
seth send --create $CODE TokenName TOK 18
```

Running the above, you will get an output like so:

```
seth-send: Published transaction with 3227 bytes of calldata.
seth-send: 0xb330d69093fd6b19d5afecffebf6734f77ef8d7cf47dabb87ad840a7d4b8e57f
seth-send: Waiting for transaction receipt....
seth-send: Transaction included in block 36.
0x243e72b69141f6af525a9a5fd939668ee9f2b354
```

The last line is the contract address.

### Saving a contract's deployment address
I'm not that skilled in Bash - but I do know one thing: I'm not reinventing the wheel when I want to save the deployment address. Using Sourcegraph (which is grep+git on steroids), I just [searched for `seth send` across all of dapphub's repos](https://sourcegraph.com/search?q=repo:%5Egithub%5C.com/dapphub+seth+send+) and was able to grab the line below. 

```bash
ERC20_ADDR=$(seth send --create $CODE --status 2>/dev/null)

# or even terser
ERC20_ADDR=$(seth send --create $(cat build/contracts/ERC20.json | jq -r .bytecode) --status 2>/dev/null)
```

`2>/dev/null` basically redirects STDERR (see [Standard streams](https://en.wikipedia.org/wiki/Standard_streams)) to null. All of the misc logging by seth is ignored and we are left with the contract address. 

**If the deployment fails**, there's no `.catch` or burdensome Promises to deal with. The `$ERC20_ADDR` variable will be empty. If we are automating this in a script, it's wise to make sure it exits early in case of failure. Check this out:

```bash
#!/bin/bash
set -ex

# Connect to the local node
export ETH_RPC_URL=http://127.0.0.1:8545

# Disable below if not on Truffle
export ETH_GAS=4712388

# Use the unlocked RPC accounts
export ETH_RPC_ACCOUNTS=yes

# Get the 1st account and use it
export ETH_FROM=$(seth accounts | head -n1 | awk '{ print $1 }')

ERC20_ADDR=$(seth send --create $(cat build/contracts/ERC20.json | jq -r .bytecode) --status 2>/dev/null)

echo -n $ERC20_ADDR > ERC20.deployment
```

Boom! We've just saved the address to a file that we can load later!


### Calling methods and passing arguments
This is probably the best part of Seth. Calling methods on contracts couldn't be easier with this tool, because **you don't have to load the JSON ABI"** to interact with contracts. 

For example, say we're testing this token contract and we want to mint ourselves some tokens. This is how simple it is:

```bash
# Get the contracts address
export ERC20_ADDR=$(cat ERC20.deployment)

seth send $ERC20_ADDR "mint(uint256)" 1
```

Likewise, if a method has a return value, you just have to show seth how to decode it. What we're passing is the method signature, but in a much simpler form than the full method - `method(<types>)(<return-types>)`.


```bash
# Get the balance of our address
seth send $ERC20_ADDR "balanceOf(address)(uint)" $ETH_FROM
```


### Transacting from different accounts
Oftentimes, we're using `msg.sender` in our contract logic. When it comes time to testing, then we probably want to use different accounts for interacting. Seth makes this super easy using the `ETH_FROM` variable.

We've already been using a global `ETH_FROM` to begin with, but it's pretty simple to use per-call too.

```bash
export BUYER=$(seth accounts | sed -n 2p | awk '{ print $1 }')

seth send --from $BUYER --value 402343423423423 $EXCHANGE "ethToTokenSwapInput(uint256,uint256)" 3 1000000000000
```

The above example calls `ethToTokenSwapInput` on a Uniswap exchange, from a specific account I've allocated called the $BUYER. It also makes use of `--value` to send some ether with the transaction.

### Converting units (numbers, eth)
This brings me to my last important teaching on Seth - converting units. In Ethereum, we deal with `uint256` as our default, and ether and other tokens are *usually* designed to be shown with 18 decimal places. Seth makes it easy to convert between these different formats.

```bash
seth --to-dec 0000000000000cb803 eth
# 833539

seth --from-wei <decimal-amount>
# 0.123

seth --to-wei <decimal-value>
# 123

seth --to-ascii 67646179206d617465
# ... ;)
```


## Conclusion
I think `seth` is a fantastic investment as a developer in Ethereum's ecocsystem. Given the inherent complexity in a whole new platform of tooling, `seth` is a pragmatic approach to inspecting, experimenting, and iterating on blockchain software.

☕️ If you liked this guide, consider following [me on Twitter](https://twitter.com/liamzebedee]). 

😎 I enjoy learning and teaching, and do it regularly. Here's some links you might find interesting too:

 - my [awesome-solidity-patterns](https://github.com/liamzebedee/awesome-solidity-patterns) repo
 - [How to link libraries into Solidity contracts generated by sol-compiler](https://dev.to/liamzebedee/how-to-link-libraries-into-solidity-contracts-generated-by-sol-compiler-34b3)
 - my blog, [Regular Fascination](https://liamz.co/blog/), with a bit more in-depth content
 - [@liamzebedee](https://twitter.com/liamzebedee) for interesting links/discussions in tech