
XBTGPUARC Miner Version 2000 :-) 535 Zeilen Wahnsinn.^^
stratum_client.cpp:
#include
#include
#include
#include
#include
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
bool connect_to_pool(const std::string& host, int port, const std::string& wallet, const std::string& worker) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
std::cerr << "❌ Socket-Fehler\n";
return false;
}
struct hostent* server = gethostbyname(host.c_str());
if (!server) {
std::cerr << "❌ Host nicht gefunden: " << host << "\n";
return false;
}
sockaddr_in serv_addr {};
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
std::memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
std::cout << "📞 Verbinde zu " << host << ":" << port << "...\n";
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
std::cerr << "❌ Verbindung fehlgeschlagen\n";
return false;
}
// Subscribe senden
std::string subscribe = "{\"id\":1,\"method\":\"mining.subscribe\",\"params\":[]}\n";
send(sock, subscribe.c_str(), subscribe.size(), 0);
// Authorize senden
std::ostringstream auth;
auth << "{\"id\":2,\"method\":\"mining.authorize\",\"params\":[\""
<< wallet << "." << worker << "\",\"\"]}\n";
std::string auth_str = auth.str();
send(sock, auth_str.c_str(), auth_str.size(), 0);
// Mitlesen
char buffer[4096];
while (true) {
int n = read(sock, buffer, sizeof(buffer) - 1);
if (n <= 0) break;
buffer[n] = '\0';
std::cout << "📨 Pool: " << buffer << std::endl;
}
close(sock);
return true;
}
stratum_notify_listener.cpp:
#include "notify_parser.hpp"
#include
#include <boost/asio.hpp>
#include
using boost::asio::ip::tcp;
int main() {
const std::string pool_host = "solo-btg.2miners.com";
const std::string pool_port = "4040";
const std::string wallet = "Gb4V4a9Jk3p8aH6jkW3Aq3sq8rQCuJQ6S8";
const std::string worker = "XBTGPUARC";
const std::string password = "x";
const std::string full_user = wallet + "." + worker;
try {
boost::asio::io_context io_context;
tcp::resolver resolver(io_context);
auto endpoints = resolver.resolve(pool_host, pool_port);
tcp::socket socket(io_context);
boost::asio::connect(socket, endpoints);
std::cout << "📡 Verbunden mit " << pool_host << ":" << pool_port << "\n";
// mining.subscribe senden
std::string subscribe = "{\"id\": 1, \"method\": \"mining.subscribe\", \"params\": []}\n";
std::string authorize = "{\"id\": 2, \"method\": \"mining.authorize\", \"params\": [\"" +
full_user + "\", \"" + password + "\"]}\n";
// Empfangsschleife
std::string buffer;
for (;;) {
char reply[4096];
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(reply), error);
buffer.append(reply, len);
// Zeilenweise verarbeiten
size_t pos = 0;
while ((pos = buffer.find('\n')) != std::string::npos) {
std::string line = buffer.substr(0, pos);
buffer.erase(0, pos + 1);
auto job = parse_notify(line);
if (job) {
std::cout << "🎯 Job ID: " << job->job_id << std::endl;
std::cout << "🧱 PrevHash: " << job->prevhash << std::endl;
}
std::cout << "🌐 Nachricht:\n" << line << "\n";
}
if (error == boost::asio::error::eof) break;
else if (error) throw boost::system::system_error(error);
}
return 0;
}
miner_loop.cpp:
// miner_loop.cpp
#include "miner_loop.hpp"
#include <CL/cl.h>
#include
#include
#include
#include
#include
static cl_context context = nullptr;
static cl_command_queue queue = nullptr;
static cl_kernel kernel = nullptr;
static cl_program program = nullptr;
static cl_device_id device = nullptr;
// Kernel-Name
static const char* KERNEL_NAME = "zhash_144_5";
// Initialisiert OpenCL & lädt Kernel
void init_opencl() {
if (context) return; // Schon initialisiert
cl_int err;
cl_platform_id platform;
clGetPlatformIDs(1, &platform, nullptr);
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, nullptr);
context = clCreateContext(nullptr, 1, &device, nullptr, nullptr, &err);
queue = clCreateCommandQueueWithProperties(context, device, 0, &err);
std::ifstream file("kernels/zhash.cl");
std::string source((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
const char* src = source.c_str();
size_t size = source.size();
program = clCreateProgramWithSource(context, 1, &src, &size, &err);
clBuildProgram(program, 1, &device, nullptr, nullptr, nullptr);
kernel = clCreateKernel(program, KERNEL_NAME, &err);
}
// Miner-Loop: führt Kernel aus & prüft Hash < Target
void miner_loop(const MiningJob& job,
const std::function<void(uint32_t nonce, const std::array<uint8_t, 32>& hash)>& on_valid_share) {
init_opencl();
std::mt19937 rng(std::random_device{}());
std::uniform_int_distribution<uint32_t> dist;
std::vector<uint8_t> target = bits_to_target(std::stoul(job.bits, nullptr, 16));
const int batch_size = 4096;
std::vector<cl_uchar> input_buffer(512 * batch_size);
std::vector<cl_uchar> output_buffer(32 * batch_size);
cl_int err;
cl_mem cl_input = clCreateBuffer(context, CL_MEM_READ_ONLY, input_buffer.size(), nullptr, &err);
cl_mem cl_output = clCreateBuffer(context, CL_MEM_WRITE_ONLY, output_buffer.size(), nullptr, &err);
clSetKernelArg(kernel, 0, sizeof(int), &batch_size);
clSetKernelArg(kernel, 1, sizeof(cl_mem), &cl_input);
clSetKernelArg(kernel, 2, sizeof(cl_mem), &cl_output);
while (true) {
uint32_t start_nonce = dist(rng);
for (int i = 0; i < batch_size; ++i) {
uint32_t nonce = start_nonce + i;
cl_uchar* in = &input_buffer[i * 512];
in[0] = nonce & 0xFF;
in[1] = (nonce >> 8) & 0xFF;
in[2] = (nonce >> 16) & 0xFF;
in[3] = (nonce >> 24) & 0xFF;
// Rest des Buffers bleibt Dummy (kann durch coinbase ersetzt werden)
}
clEnqueueWriteBuffer(queue, cl_input, CL_TRUE, 0, input_buffer.size(), input_buffer.data(), 0, nullptr, nullptr);
size_t global_work_size = batch_size;
clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &global_work_size, nullptr, 0, nullptr, nullptr);
clFinish(queue);
clEnqueueReadBuffer(queue, cl_output, CL_TRUE, 0, output_buffer.size(), output_buffer.data(), 0, nullptr, nullptr);
for (int i = 0; i < batch_size; ++i) {
std::array<uint8_t, 32> hash;
std::memcpy(hash.data(), &output_buffer[i * 32], 32);
if (is_valid_hash(hash, target)) {
uint32_t nonce = start_nonce + i;
on_valid_share(nonce, hash);
}
}
}
// Optional: Freigeben (falls du willst)
// clReleaseMemObject(cl_input);
// clReleaseMemObject(cl_output);
// clReleaseKernel(kernel);
// clReleaseProgram(program);
// clReleaseCommandQueue(queue);
// clReleaseContext(context);
}
miner_loop.hpp:
// miner_loop.hpp
#pragma once
#include "mining_job.hpp"
#include
#include
#include
void miner_loop(const MiningJob& job,
const std::function<void(uint32_t nonce, const std::array<uint8_t, 32>& hash)>& on_valid_share);
run.sh:
#!/bin/bash
export GPU_MAX_HEAP_SIZE=100
export GPU_MAX_USE_SYNC_OBJECTS=1
export GPU_SINGLE_ALLOC_PERCENT=100
export GPU_MAX_ALLOC_PERCENT=100
export GPU_MAX_SINGLE_ALLOC_PERCENT=100
export GPU_ENABLE_LARGE_ALLOCATION=100
export GPU_MAX_WORKGROUP_SIZE=1024
./xbtgpuarc
--platform 0
--device 0
--algo zhash_144_5
--pool solo-btg.2miners.com
--port 4040
--wallet Gb4V4a9Jk3p8aH6jkW3Aq3sq8rQCuJQ6S8
--worker A730m
--password x
--intensity 4096
Makefile
CXX = g++
CXXFLAGS = -std=c++17 -Wall -O2
LDFLAGS = -lOpenCL -lboost_json -lpthread
SRC = main.cpp miner_loop.cpp
OUT = xbtgpuarc
all:
$(CXX) $(CXXFLAGS) $(SRC) -o $(OUT) $(LDFLAGS)
clean:
rm -f $(OUT)
notify_parser.hpp:
#pragma once
#include "mining_job.hpp"
#include <boost/json.hpp>
#include
#include
#include
#include
inline std::string to_hex(uint32_t val) {
std::ostringstream ss;
ss << std::hex << std::setw(8) << std::setfill('0') << val;
return ss.str();
}
inline std::optional parse_notify(const std::string& json_string) {
using namespace boost::json;
try {
value parsed = parse(json_string);
if (!parsed.is_object()) return std::nullopt;
auto& obj = parsed.as_object();
if (!obj.contains("method") || obj["method"].as_string() != "mining.notify") return std::nullopt;
auto& params = obj["params"].as_array();
if (params.size() < 9) return std::nullopt;
MiningJob job;
job.job_id = params[0].as_string().c_str();
job.prevhash = params[1].as_string().c_str();
job.coinbase1 = params[2].as_string().c_str();
job.coinbase2 = params[3].as_string().c_str();
for (const auto& entry : params[4].as_array())
job.merkle_branch.emplace_back(entry.as_string().c_str());
job.version = to_hex(static_cast<uint32_t>(params[5].as_int64()));
job.bits = to_hex(static_cast<uint32_t>(params[6].as_int64()));
job.ntime = to_hex(static_cast<uint32_t>(params[7].as_int64()));
job.clean_jobs = params[8].as_bool();
return job;
} catch (const std::exception& e) {
std::cerr << "❌ JSON-Fehler: " << e.what() << "\n";
return std::nullopt;
}
}
mining_job.hpp:
#pragma once
#include
#include
#include
#include
// Struktur für einen Mining-Job (aus mining.notify)
struct MiningJob {
std::string job_id;
std::string prevhash;
std::string coinbase1;
std::string coinbase2;
std::vector<std::string> merkle_branch;
std::string version;
std::string bits;
std::string ntime;
bool clean_jobs;
};
// Wandelt "bits" (compact target) in echtes 256-bit Target (32 Byte)
inline std::vector<uint8_t> bits_to_target(uint32_t bits) {
int exponent = bits >> 24;
uint32_t mantissa = bits & 0x007fffff;
std::vector<uint8_t> target(32, 0);
int shift = exponent - 3;
if (shift >= 0 && shift <= 29) {
target[shift] = (mantissa >> 16) & 0xff;
target[shift + 1] = (mantissa >> 8) & 0xff;
target[shift + 2] = mantissa & 0xff;
}
return target;
}
// Vergleicht Hash < Target
inline bool is_valid_hash(const std::array<uint8_t, 32>& hash, const std::vector<uint8_t>& target) {
for (size_t i = 0; i < 32; ++i) {
if (hash[i] < target[i]) return true;
if (hash[i] > target[i]) return false;
}
return false; // Gleichstand ist kein gültiger Share
}
main.cpp:
#include <boost/asio.hpp>
#include <CL/cl.h>
#include
#include
#include
#include
#include
#include
#include
#include "notify_parser.hpp"
#include "mining_job.hpp"
#include "miner_loop.hpp"
void connect_to_pool(const std::string& host, int port,
const std::string& wallet,
const std::string& worker,
const std::string& password,
int platform_index,
int device_index,
int intensity) {
using boost::asio::ip::tcp;
try {
boost::asio::io_context io_context;
tcp::resolver resolver(io_context);
auto endpoints = resolver.resolve(host, std::to_string(port));
tcp::socket socket(io_context);
boost::asio::connect(socket, endpoints);
std::cout << "📡 Verbunden mit " << host << ":" << port << "\n";
std::string subscribe = R"({"id":1,"method":"mining.subscribe","params":[]})" "\n";
std::string full_user = wallet + "." + worker;
std::string authorize = R"({"id":2,"method":"mining.authorize","params":[")" + full_user + R"(",")" + password + R"("]})" "\n";
boost::asio::write(socket, boost::asio::buffer(subscribe));
boost::asio::write(socket, boost::asio::buffer(authorize));
std::string buffer;
for (;;) {
char reply[4096];
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(reply), error);
buffer.append(reply, len);
size_t pos = 0;
while ((pos = buffer.find('\n')) != std::string::npos) {
std::string line = buffer.substr(0, pos);
buffer.erase(0, pos + 1);
auto job = parse_notify(line);
if (job) {
std::cout << "🎯 Neuer Job: " << job->job_id << "\n";
miner_loop(*job, [](uint32_t nonce, const std::array<uint8_t, 32>& hash) {
std::cout << "✅ Share gefunden! Nonce = " << nonce << "\n";
// TODO: submit_share(job, nonce, hash);
});
}
std::cout << "🌐 Nachricht:\n" << line << "\n";
}
if (error == boost::asio::error::eof) break;
else if (error) throw boost::system::system_error(error);
}
} catch (const std::exception& e) {
std::cerr << "❌ Fehler: " << e.what() << "\n";
}
}
int main(int argc, char** argv) {
int platform_index = 0;
int device_index = 0;
int intensity = 4;
std::string algo = "zhash_144_5";
std::string wallet = "default_wallet";
std::string worker = "default_worker";
std::string password = "x";
std::string pool_host = "solo-btg.2miners.com";
int pool_port = 4040;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg == "--platform" && i + 1 < argc) platform_index = std::atoi(argv[++i]);
else if (arg == "--device" && i + 1 < argc) device_index = std::atoi(argv[++i]);
else if (arg == "--intensity" && i + 1 < argc) intensity = std::atoi(argv[++i]);
else if (arg == "--algo" && i + 1 < argc) algo = argv[++i];
else if (arg == "--wallet" && i + 1 < argc) wallet = argv[++i];
else if (arg == "--worker" && i + 1 < argc) worker = argv[++i];
else if (arg == "--password" && i + 1 < argc) password = argv[++i];
else if (arg == "--pool" && i + 1 < argc) pool_host = argv[++i];
else if (arg == "--port" && i + 1 < argc) pool_port = std::atoi(argv[++i]);
}
std::cout << "🚀 Starte XBTGPUARC mit Algo: " << algo << "\n";
std::cout << "🎛️ Platform: " << platform_index << " | Device: " << device_index << " | Intensity: " << intensity << "\n";
std::cout << "👤 Worker: " << wallet << "." << worker << "\n";
connect_to_pool(pool_host, pool_port, wallet, worker, password, platform_index, device_index, intensity);
return 0;
}
kernels:
__constant uint IV[8] = {
0x6a09e667, 0xbb67ae85, 0x0a6ef372, 0x0a54ff5a,
0x510e527f, 0xb056688c, 0x1f83d9ab, 0x5be0cd19
};
inline uint rotl32(uint x, uint n) {
return (x << n) | (x >> (32 - n));
}
inline void G(uint *a, uint *b, uint *c, uint *d, uint m) {
*a = *a + *b + m;
*d ^= *a;
d = rotl32(d, 16);
*c = *c + *d;
*b ^= *c;
*b = rotl32(*b, 12);
*a = *a + *b + m;
*d ^= *a;
*d = rotl32(*d, 8);
*c = *c + *d;
*b ^= *c;
*b = rotl32(*b, 7);
}
__kernel void zhash_kernel(__global const uchar *input, __global uchar *output) {
int gid = get_global_id(0);
// Beispielhafte Initialwerte (einfach IV kopiert, z.B. Blake-Vorbild)
uint a = IV[0];
uint b = IV[1];
uint c = IV[2];
uint d = IV[3];
// Beispielhafte Nachrichtendaten (real aus input)
uint m = ((uint*)input)[gid];
// Mehrere Runden simuliert (feste Zahl z.B. 4)
for (int i = 0; i < 4; ++i) {
G(&a, &b, &c, &d, m ^ i);
}
// Output berechnen (einfache Reduktion, sonst wird’s zu groß)
uint result = a ^ b ^ c ^ d;
// 4 Byte rausschreiben
output[gid * 4 + 0] = (uchar)((result >> 0) & 0xFF);
output[gid * 4 + 1] = (uchar)((result >> 8) & 0xFF);
output[gid * 4 + 2] = (uchar)((result >> 16) & 0xFF);
output[gid * 4 + 3] = (uchar)((result >> 24) & 0xFF);
}
logs
Leave XBTGPUARC Miner Version 2000 :-) 535 Zeilen Wahnsinn.^^ to:
Read more #deutsch posts
Best Posts From ALUCIAN™
We have not curated any of alucian's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From ALUCIAN™
- Die Frage ob ich einem §99 Personenkreis zugeordnet werde oder sowas wird gestellt per Terminierung ich angezeigt wegen Falscher Tasachenbehauptung. Langweilig werds ned, sag ma bei uns. :-)
- Kaum, macht man einfach auch mal Nix, kriegt man schon wieder eine Rechnung. Kriminalisierungsbeitrag.
- Juhuu, Frau Weiß bei der Sozialen Wohnhilfe aus der Froebelstraße in Berlin ist Super. Sie macht das sehr Flott, ohne großes hin oder her. Hier ein Neuer Traeger.
- Ich habe gestern den Laptop und die Claw dann noch "verheiratet" sozusagen. Die kennen sich jetzt. Was ein Staatsakt das war!
- Lageso Antwortet das jetzt meine Krebserkrankung noch nicht festgestellt werden konnte... Ja ne, die CD auf der man das sieht als Arzt oder so... hatten die schon in der Hand...
- Mein Laptop laed die Claw, ohne PD. Ich denke das eine Mindestwattzahl geladen wird an so einem Thunderbold Stecker. Auch ohne PD.
- Ich habe ueber die Jahre sowohl Windows als auch Linux Mining Programme gesammelt und sortiert.
- Der Rieck... ueber Bitcoin. Alle ignorieren sie die Grundlangen... One Vote One CPU!!! DAS war Grundlage!!! Nicht meine Worte!!! Sathosis Gelaber nicht meines, ich unterschreibe es NICHT, aber im Kern SCHON!!! (GPU ZAEHLEN JETZT AUCH!)
- Ein bisschen Rausgeputzt hab ich jetzt alles und geflickt fertig auch die Uhr.^^
- Das Bild ist auch Scharf finde ich, kommt in die Erinnerungskiste.^^ Das war so der drei Dutzendstes Versuch drei GPUs in einen Midi Tower zu quetschen.^^