Skip to content

Commit 2cb9b0f

Browse files
committed
initial commit
0 parents  commit 2cb9b0f

19 files changed

+4254
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/target
2+
**/*.rs.bk
3+
.DS_Store
4+
efficient_addresses.txt
5+
.env
6+
*/node_modules/

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Uniswap V4 Vanity Miner
2+
3+
This repo contains three components to mine for the Uniswap V4 address:
4+
- Modified version of [create2crunch](https://github.com/0age/create2crunch)
5+
- Server instance to aggregate logs and forward salts to tg channel
6+
- Script to bid on vastai instances
7+
8+
...
9+
10+
# Running
11+
12+
### Start The Log Aggregator Server
13+
14+
1. Setup a new tg bot + channel ([how to get the channel id](https://stackoverflow.com/questions/33858927/how-to-obtain-the-chat-id-of-a-private-telegram-channel))
15+
16+
2. Host server using railway
17+
```bash
18+
cd log-aggregator
19+
railway init
20+
railway up
21+
```
22+
> You will need to supply the env vars `BOT_TOKEN` and `CHANNEL_ID` on your railway dashboard
23+
24+
25+
### Creating template on vastai
26+
27+
Head to [cloud.vast.ai/templates/edit](https://cloud.vast.ai/templates/edit). You can pull the docker-image [`mousless/fourfourfourfour`](https://hub.docker.com/repository/docker/mousless/fourfourfourfour/general) if you want to skip building your own.
28+
29+
Fill in the `on-startup Script` section with the following
30+
```bash
31+
for i in $(seq 0 $(($(clinfo | awk '/Platform Name/ {pname=$3} /Number of devices/ {if (pname ~ /NVIDIA/) {print $4}}') - 1))); do
32+
nohup /home/target/release/fourfourfourfour \
33+
0x48E516B34A1274f49457b9C6182097796D0498Cb \
34+
0x0000000000000000000000000000000000000000 \
35+
0x94d114296a5af85c1fd2dc039cdaa32f1ed4b0fe0868f02d888bfc91feb645d9 \
36+
$i \
37+
$YOUR_RAILWAY_ENDPOINT_URL_HERE \
38+
> "log_$i.txt" 2>&1 &
39+
done
40+
```
41+
> Note that this is setting msg.sender as the zero address meaning anyone can submit your salt.
42+
43+
### Building Docker Image (Optional)
44+
45+
There is probably a much better way to mod create2crunch for this challenge. I just one shotted a prompt, it looked good, but it likely isn't the optimal solution.
46+
47+
```bash
48+
cd create2crunch
49+
docker build -t fourfourfourfour .
50+
docker tag fourfourfourfour ${YOUR_DOCKERHUB_USERNAME}/fourfourfourfour:latest
51+
docker push ${YOUR_DOCKERHUB_USERNAME}/fourfourfourfour:latest
52+
```
53+
54+
### Setting up vastai bidder
55+
56+
vastai offers interruptable boxes where users can place bids on GPUs at a much lower price compared to straight out renting. This is a simple script to periodically place bids on RTX 4090s (up to $0.2/h)
57+
58+
Running bidder:
59+
```bash
60+
cd bidder
61+
railway init
62+
railway up
63+
```
64+
> You will need to supply the env vars `VAST_API_KEY` and `VAST_TEMPLATE_HASH` on your railway dashboard.

bidder/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
VAST_API_KEY=
2+
VAST_TEMPLATE_HASH=

bidder/main.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import os
2+
import json
3+
import time
4+
from dotenv import load_dotenv
5+
from vastai import VastAI
6+
7+
def check_and_create_instances():
8+
# Load environment variables from .env file
9+
load_dotenv()
10+
11+
# Get API key from environment variables
12+
api_key = os.getenv('VAST_API_KEY')
13+
template_hash = os.getenv('TEMPLATE_HASH')
14+
vast_sdk = VastAI(api_key=api_key)
15+
16+
# Check available machines
17+
machines_raw = vast_sdk.search_offers(
18+
order='flops_per_dphtotal',
19+
type="interruptible",
20+
query="gpu_name=RTX_4090",
21+
raw=True
22+
)
23+
machines = json.loads(machines_raw)
24+
time.sleep(0.5) # 500ms delay after API request
25+
26+
# Print information for each machine
27+
for machine in machines:
28+
cost_per_gpu = machine['dph_total'] / machine['num_gpus']
29+
if cost_per_gpu <= 0.2: # Set ceiling to $0.2/h
30+
print(f"Machine ID: {machine['id']}")
31+
print(f"Number of GPUs: {machine['num_gpus']}")
32+
print(f"Total Cost per hour: ${machine['dph_total']:.2f}")
33+
print(f"Cost per GPU per hour: ${cost_per_gpu:.2f}")
34+
print("-" * 40)
35+
bid_price = machine['dph_total'] * 1.15 # place a lowball stink bid that is 15% above min
36+
print(f"Setting initial bid at ${bid_price:.3f} (10% of ${machine['dph_total']:.2f})")
37+
x = vast_sdk.create_instance(
38+
ID=machine['id'],
39+
template_hash=template_hash,
40+
price=bid_price
41+
)
42+
print(x)
43+
time.sleep(0.5) # 500ms delay after API request
44+
45+
# Check instances
46+
instances_raw = vast_sdk.show_instances(raw=True)
47+
instances = json.loads(instances_raw)
48+
time.sleep(0.5) # 500ms delay after API request
49+
active_gpus = 0
50+
51+
for instance in instances:
52+
if instance['actual_status'] == "running":
53+
active_gpus += instance['num_gpus']
54+
if instance['is_bid'] == True and instance['intended_status'] == "stopped":
55+
cost_per_gpu = machine['dph_total'] / machine['num_gpus']
56+
if cost_per_gpu <= 0.2: # Set ceiling to $0.2/h
57+
bid_price = instance['min_bid'] * 1.15
58+
x = vast_sdk.change_bid(id=instance['id'], price=bid_price)
59+
print(f"Changed bid for instance {instance['id']} - {instance['num_gpus']} GPUs at ${bid_price:.3f} total (${(bid_price/instance['num_gpus']):.3f}/GPU)")
60+
print(f"Original price was ${instance['min_bid']:.2f}")
61+
print(x)
62+
time.sleep(0.5) # 500ms delay after API request
63+
64+
print(f"Active GPUs: {active_gpus}")
65+
print(f"Check completed at: {time.strftime('%Y-%m-%d %H:%M:%S')}")
66+
print("-" * 40)
67+
68+
def main():
69+
print("Starting VastAI GPU monitoring script...")
70+
print("Checking every 15 seconds...")
71+
print("-" * 40)
72+
73+
while True:
74+
try:
75+
check_and_create_instances()
76+
time.sleep(15) # Wait for 15 seconds before next check
77+
except Exception as e:
78+
print(f"Error occurred: {e}")
79+
print("Waiting 15 seconds before retry...")
80+
time.sleep(15)
81+
82+
if __name__ == "__main__":
83+
main()

bidder/requirements.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
certifi==2024.8.30
2+
charset-normalizer==3.4.0
3+
idna==3.10
4+
python-dotenv==1.0.1
5+
requests==2.32.3
6+
urllib3==2.2.3
7+
vastai==0.2.6

0 commit comments

Comments
 (0)