Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ignore all files by default.
**

# Include only the main script.
!safe_hashes.sh
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore the `data` directory by default.
data/
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# For reproducible builds, consider pinning to a specific digest instead of `latest`.
# See https://github.com/foundry-rs/foundry/pkgs/container/foundry.
FROM ghcr.io/foundry-rs/foundry:latest

# Switch to the root user to install the necessary packages.
USER root

# Install `curl` and `jq` using the package manager.
RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl \
jq \
&& rm -rf /var/lib/apt/lists/*

# Copy the script into the image.
COPY ./safe_hashes.sh /app/safe_hashes.sh
RUN chmod +x /app/safe_hashes.sh

# Switch back to the default, non-root Foundry user for security.
USER foundry
66 changes: 65 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ This Bash [script](./safe_hashes.sh) calculates the Safe transaction hashes by r
- [Usage](#usage)
- [macOS Users: Upgrading Bash](#macos-users-upgrading-bash)
- [Optional: Set the New Bash as Your Default Shell](#optional-set-the-new-bash-as-your-default-shell)
- [Docker Usage](#docker-usage)
- [Building the Docker Image](#building-the-docker-image)
- [Basic Usage](#basic-usage)
- [Using Message Files](#using-message-files)
- [With Environment Variables](#with-environment-variables)
- [Safe Transaction Hashes](#safe-transaction-hashes)
- [Interactive Mode](#interactive-mode)
- [Transaction Simulation](#transaction-simulation)
Expand Down Expand Up @@ -81,7 +86,7 @@ This Bash [script](./safe_hashes.sh) calculates the Safe transaction hashes by r
> Ensure that [`cast`](https://github.com/foundry-rs/foundry/tree/master/crates/cast) and [`chisel`](https://github.com/foundry-rs/foundry/tree/master/crates/chisel) are installed locally. For installation instructions, refer to this [guide](https://getfoundry.sh/introduction/installation/). This [script](./safe_hashes.sh) is designed to work with the latest _stable_ versions of [`cast`](https://github.com/foundry-rs/foundry/tree/master/crates/cast) and [`chisel`](https://github.com/foundry-rs/foundry/tree/master/crates/chisel), starting from version [`1.3.5`](https://github.com/foundry-rs/foundry/releases/tag/v1.3.5).

> [!TIP]
> For macOS users, please refer to the [macOS Users: Upgrading Bash](#macos-users-upgrading-bash) section.
> For macOS users, please refer to the [macOS Users: Upgrading Bash](#macos-users-upgrading-bash) section. Alternatively, you can use the Docker container, which comes pre-installed with all required dependencies. For details, see the [Docker Usage](#docker-usage) section below.

```console
./safe_hashes.sh [--help] [--version] [--list-networks] --network <network> --address <address>
Expand Down Expand Up @@ -199,6 +204,65 @@ chsh -s BASH_PATH

Make sure to replace `BASH_PATH` with the actual path you retrieved in step 1.

### Docker Usage

Using [Docker](https://www.docker.com), you can run the [script](./safe_hashes.sh) in a containerised environment with all dependencies pre-installed. This is useful if you do not wish to install the required tools locally, or if you are on a system where installation is difficult.

#### Building the Docker Image

Build the [Docker](https://www.docker.com) image using [Docker Compose](https://docs.docker.com/compose/):

```console
docker-compose build
```

#### Basic Usage

To run the [script](./safe_hashes.sh) using [Docker Compose](https://docs.docker.com/compose/), use the [`compose.yaml`](./compose.yaml) file provided in the repository. The container is named `safe-tx-hashes-util`.

Example displaying help:

```console
docker-compose run --rm safe-tx-hashes-util --help
```

Example calculating the Safe transaction hashes:

```console
docker-compose run --rm safe-tx-hashes-util --network arbitrum --address 0x111CEEee040739fD91D29C34C33E6B3E112F2177 --nonce 234
```

#### Using Message Files

When calculating off-chain message hashes, you need to provide a local directory containing your message file. The included [`compose.yaml`](./compose.yaml) configuration mounts the `./data` directory by default.

```console
# First, create a `data` directory and add your message file.
~$ mkdir -p data
~$ echo "Your message content here" > data/message.txt

# Run the container with the mounted directory.
~$ docker-compose run --rm safe-tx-hashes-util \
--network sepolia \
--address 0x657ff0D4eC65D82b2bC1247b0a558bcd2f80A0f1 \
--message /data/message.txt
```

#### With Environment Variables

You can pass environment variables directly via [Docker Compose](https://docs.docker.com/compose/):

```console
# Disable all formatting.
docker-compose run --rm -e NO_COLOR=true safe-tx-hashes-util \
--network arbitrum \
--address 0x111CEEee040739fD91D29C34C33E6B3E112F2177 \
--nonce 234
```

> [!IMPORTANT]
> Running in a [Docker](https://www.docker.com) container offers isolation, but it is important to always follow the [Security Best Practices](#security-best-practices-for-using-this-script).

## Safe Transaction Hashes

To calculate the Safe transaction hashes for a specific transaction, you need to specify the `network`, `address`, and `nonce` parameters. An example:
Expand Down
46 changes: 46 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
services:
safe-tx-hashes-util:
build:
context: .
dockerfile: Dockerfile

container_name: safe-tx-hashes-util

security_opt:
- no-new-privileges:true # Prevent privilege escalation.
- apparmor=docker-default # Set the `AppArmor` profile for Ubuntu/Debian/openSUSE (restrict file/network access).
- label=type:container_t # Set the `SELinux` profile for RHEL/CentOS/Fedora (provide mandatory access control).

cap_drop:
- ALL # Drop all root Linux kernel capabilities.

read_only: true # Make the container's root filesystem read-only.

working_dir: /app

volumes:
# Mount the script from the host for live editing without rebuilding the image.
- type: bind
source: ./safe_hashes.sh
target: /app/safe_hashes.sh
read_only: true
# Mount the host `./data` directory as read-only for off-chain message files.
- type: bind
source: ./data
target: /data
read_only: true
bind:
create_host_path: true

tmpfs:
- /tmp:noexec,nosuid,nodev,size=50m # Store temporary files in memory only (limited to 50MB, not executable).
- /home/foundry/.foundry:noexec,nosuid,nodev,size=50m # Keep Foundry's cache and settings in memory (limited to 50MB, cannot run programs from here).
- /home/foundry/.svm:exec,nosuid,nodev,size=50m # Keep Solidity Version Manager (`svm`) files in memory (limited to 50MB, programs can run from here).

environment:
- DEBUG=false # See https://github.com/pcaversaccio/safe-tx-hashes-util/tree/main#usage.
- NO_COLOR=false # See https://github.com/pcaversaccio/safe-tx-hashes-util/tree/main#usage.
- FOUNDRY_DISABLE_NIGHTLY_WARNING=false

# Override the image's default command to run the script.
entrypoint: ["/bin/bash", "/app/safe_hashes.sh"]