Skip to content

Commit

Permalink
feat: Add support for proxy-based contract deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
MrSpike63 committed Feb 7, 2024
1 parent 6548651 commit e13ef6e
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 22 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ Vanity Eth Address is a tool to generate Ethereum addresses that match certain c
```
./vanity-eth-addresss [PARAMETERS]
Scoring methods
(-lz) --leading-zeros Count zero bytes at the start of the address
(-z) --zeros Count zero bytes anywhere in the address
(-lz) --leading-zeros Count zero bytes at the start of the address
(-z) --zeros Count zero bytes anywhere in the address
Modes (normal addresses by default)
(-c) --contract Search for addresses and score the contract address generated using nonce=0
(-c2) --contract2 Search for contract addresses using the CREATE2 opcode
(-c) --contract Search for addresses and score the contract address generated using nonce=0
(-c2) --contract2 Search for contract addresses using the CREATE2 opcode
(-c3) --contract3 Search for contract addresses using a CREATE3 proxy deployer
Other:
(-d) --device <device_number> Use device <device_number> (Add one for each device for multi-gpu)
(-b) --bytecode <filename> File containing contract bytecode (only needed when using --contract2)
(-a) --address <address> Sender contract address (only needed when using --contract2)
(-w) --work-scale <num> Defaults to 15. Scales the work done in each kernel. If your GPU finishes kernels within a few seconds, you may benefit from increasing this number.
(-d) --device <device_number> Use device <device_number> (Add one for each device for multi-gpu)
(-b) --bytecode <filename> File containing contract bytecode (only needed when using --contract2 or --contract3)
(-a) --address <address> Sender contract address (only needed when using --contract2 or --contract3)
(-ad) --deployer-address <address> Deployer contract address (only needed when using --contract3)
(-w) --work-scale <num> Defaults to 15. Scales the work done in each kernel. If your GPU finishes kernels within a few seconds, you may benefit from increasing this number.
Examples:
./vanity-eth-address --zeros --device 0 --device 2 --work-scale 17
Expand Down
45 changes: 45 additions & 0 deletions src/contract_address3.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
Copyright (C) 2023 MrSpike63
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once
#include "curve_math.h"
#include "keccak.h"
#include "math.h"


__global__ void __launch_bounds__(BLOCK_SIZE, 2) gpu_contract3_address_work(int score_method, Address origin, Address deployer, _uint256 base_key, _uint256 proxy_bytecode) {
uint64_t thread_id = (uint64_t)threadIdx.x + (uint64_t)blockIdx.x * (uint64_t)BLOCK_SIZE;
uint64_t key_offset = (uint64_t)THREAD_WORK * thread_id;

_uint256 key = base_key;
asm(
"add.cc.u32 %0, %0, %8; \n\t"
"addc.cc.u32 %1, %1, %9; \n\t"
"addc.cc.u32 %2, %2, 0x0; \n\t"
"addc.cc.u32 %3, %3, 0x0; \n\t"
"addc.cc.u32 %4, %4, 0x0; \n\t"
"addc.cc.u32 %5, %5, 0x0; \n\t"
"addc.cc.u32 %6, %6, 0x0; \n\t"
"addc.u32 %7, %7, 0x0; \n\t"
: "+r"(key.h), "+r"(key.g), "+r"(key.f), "+r"(key.e), "+r"(key.d), "+r"(key.c), "+r"(key.b), "+r"(key.a) : "r"((uint32_t)(key_offset & 0xFFFFFFFF)), "r"((uint32_t)(key_offset >> 32))
);
for (int i = 0; i < THREAD_WORK; i++) {
_uint256 salt = calculate_create3_salt(origin, key);
Address proxy = calculate_contract_address2(deployer, salt, proxy_bytecode);
handle_output2(score_method, calculate_contract_address(proxy, 1), key_offset + i);
key.h += 1;
}
}
30 changes: 28 additions & 2 deletions src/cpu_keccak.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,15 @@ Address cpu_calculate_address(_uint256 x, _uint256 y) {
}


Address cpu_calculate_contract_address(Address a) {
Address cpu_calculate_contract_address(Address a, uint8_t nonce = 0x80) {
uint64_t block[25];
for (int i = 0; i < 25; i++) {
block[i] = 0;
}

block[0] = cpu_swap_endianness((0xD694ULL << 48) | ((uint64_t)a.a << 16) | (a.b >> 16));
block[5] = cpu_swap_endianness(((uint64_t)a.b << 48) | ((uint64_t)a.c << 16) | (a.d >> 16));
block[10] = cpu_swap_endianness(((uint64_t)a.d << 48) | ((uint64_t)a.e << 16) | (0x80ULL << 8) | 1);
block[10] = cpu_swap_endianness(((uint64_t)a.d << 48) | ((uint64_t)a.e << 16) | ((uint64_t)nonce << 8) | 1);

block[8] = 0x8000000000000000;

Expand Down Expand Up @@ -254,4 +254,30 @@ Address cpu_calculate_contract_address2(Address a, _uint256 salt, _uint256 bytec
uint64_t d = cpu_swap_endianness(block[15]);

return {(uint32_t)(b & 0xFFFFFFFF), (uint32_t)(c >> 32), (uint32_t)(c & 0xFFFFFFFF), (uint32_t)(d >> 32), (uint32_t)(d & 0xFFFFFFFF)};
}

_uint256 cpu_calculate_create3_salt(Address origin, _uint256 salt) {
uint64_t block[25];
for (int i = 0; i < 25; i++) {
block[i] = 0;
}

block[0] = cpu_swap_endianness(((uint64_t)origin.a << 32) | (uint64_t)origin.b);
block[5] = cpu_swap_endianness(((uint64_t)origin.c << 32) | (uint64_t)origin.d);
block[10] = cpu_swap_endianness(((uint64_t)origin.e << 32) | (uint64_t)salt.a);
block[15] = cpu_swap_endianness(((uint64_t)salt.b << 32) | (uint64_t)salt.c);
block[20] = cpu_swap_endianness(((uint64_t)salt.d << 32) | (uint64_t)salt.e);
block[1] = cpu_swap_endianness(((uint64_t)salt.f << 32) | (uint64_t)salt.g);
block[6] = cpu_swap_endianness(((uint64_t)salt.h << 32) | (1ULL << 24));

block[8] = 0x8000000000000000;

cpu_block_permute(block);

uint64_t a = cpu_swap_endianness(block[0]);
uint64_t b = cpu_swap_endianness(block[5]);
uint64_t c = cpu_swap_endianness(block[10]);
uint64_t d = cpu_swap_endianness(block[15]);

return {(uint32_t)(a >> 32), (uint32_t)(a & 0xFFFFFFFF), (uint32_t)(b >> 32), (uint32_t)(b & 0xFFFFFFFF), (uint32_t)(c >> 32), (uint32_t)(c & 0xFFFFFFFF), (uint32_t)(d >> 32), (uint32_t)(d & 0xFFFFFFFF)};
}
30 changes: 28 additions & 2 deletions src/keccak.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,15 @@ __device__ Address calculate_address(_uint256 x, _uint256 y) {
}


__device__ Address calculate_contract_address(Address a) {
__device__ Address calculate_contract_address(Address a, uint8_t nonce = 0x80) {
uint64_t block[25];
for (int i = 0; i < 25; i++) {
block[i] = 0;
}

block[0] = swap_endianness((0xD694ULL << 48) | ((uint64_t)a.a << 16) | (a.b >> 16));
block[5] = swap_endianness(((uint64_t)a.b << 48) | ((uint64_t)a.c << 16) | (a.d >> 16));
block[10] = swap_endianness(((uint64_t)a.d << 48) | ((uint64_t)a.e << 16) | (0x80ULL << 8) | 1);
block[10] = swap_endianness(((uint64_t)a.d << 48) | ((uint64_t)a.e << 16) | ((uint64_t)nonce << 8) | 1);

block[8] = 0x8000000000000000;

Expand Down Expand Up @@ -201,4 +201,30 @@ __device__ Address calculate_contract_address2(Address a, _uint256 salt, _uint25
uint64_t d = swap_endianness(block[15]);

return {(uint32_t)(b & 0xFFFFFFFF), (uint32_t)(c >> 32), (uint32_t)(c & 0xFFFFFFFF), (uint32_t)(d >> 32), (uint32_t)(d & 0xFFFFFFFF)};
}

__device__ _uint256 calculate_create3_salt(Address origin, _uint256 salt) {
uint64_t block[25];
for (int i = 0; i < 25; i++) {
block[i] = 0;
}

block[0] = swap_endianness(((uint64_t)origin.a << 32) | (uint64_t)origin.b);
block[5] = swap_endianness(((uint64_t)origin.c << 32) | (uint64_t)origin.d);
block[10] = swap_endianness(((uint64_t)origin.e << 32) | (uint64_t)salt.a);
block[15] = swap_endianness(((uint64_t)salt.b << 32) | (uint64_t)salt.c);
block[20] = swap_endianness(((uint64_t)salt.d << 32) | (uint64_t)salt.e);
block[1] = swap_endianness(((uint64_t)salt.f << 32) | (uint64_t)salt.g);
block[6] = swap_endianness(((uint64_t)salt.h << 32) | (1ULL << 24));

block[8] = 0x8000000000000000;

block_permute(block);

uint64_t a = swap_endianness(block[0]);
uint64_t b = swap_endianness(block[5]);
uint64_t c = swap_endianness(block[10]);
uint64_t d = swap_endianness(block[15]);

return {(uint32_t)(a >> 32), (uint32_t)(a & 0xFFFFFFFF), (uint32_t)(b >> 32), (uint32_t)(b & 0xFFFFFFFF), (uint32_t)(c >> 32), (uint32_t)(c & 0xFFFFFFFF), (uint32_t)(d >> 32), (uint32_t)(d & 0xFFFFFFFF)};
}
Loading

0 comments on commit e13ef6e

Please sign in to comment.