Pages:
Author

Topic: [Bounty - Claimed] Vanity address split-key generator software - page 2. (Read 22811 times)

legendary
Activity: 980
Merit: 1008
I can't figure out how to build oclvanityminer. Any hints?
hero member
Activity: 784
Merit: 1009
firstbits:1MinerQ
Thx. I used your test page to verify my method and it works the same. But what I found after plugging results into bitaddress.org and comparing with keyconv is that I do not add a 00h byte after the sum and before converting to WIF. This seems to cause a problem as the base 58 conversion goes awry producing a bad key.

[edit:]
Solved! The "getExportedPrivateKey" member of the ECKey class in the BitcoinJS library has a bug. It does not check and pad the byte array to 32 bytes before adding 0x80 and checksum. Incidentally bitaddress.org is using a different version of BitcoinJS that has a "getBitcoinPrivateKeyByteArray" member instead that is fixed. My version of BitcoinJS was pulled from github just a few days ago.

sr. member
Activity: 444
Merit: 313
Hmm, if you have an odd case, you can try it against my testing suite:
http://gobittest.appspot.com/

In order to prevent 0 from being the answer, you have to first subtract 1 from result before modding, then mod, and then add 1. Then your range will be from 1 to N, rather than from 0 to N-1.

The multiplication method is quite easy - instead of using the base point G (04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8), you just use the public key provided by the other person. Then you generate the address like normal (without any adding). To obtain the proper private key to be used with Bitcoin, one needs to multiply the two private keys. This method is also available in my testing suite.

As for StackExchange, you just need an OpenID and you can log in without any problem.
hero member
Activity: 784
Merit: 1009
firstbits:1MinerQ
Thanks again. I don't know how the multiplication method works. I did test a few hundred keys today using ADD + MOD (running output back thru keyconv to test the key gives the right address). All worked well except one.

I have one weird one that just won't come out right even though it does work in keyconv. Very odd. It must be some glitch or maybe I'm just not doing something quite right. I've repeated it over and over with various tweaks and conversions output to see what is wrong with this one case. I wouldn't want it to happen again sometime. The intermediate value looks similar to others but the MOD corrupts it.

Both input keys always start with 5... and often after the ADD they still do. But sometimes after the ADD I'll get some with Kw... or similar. In all cases the final key starts with 5...again but this one bad key degenerates into: ynomGnBe9P5eDVrdRY49Fs5nNRWkoAGYkPY7PqMuDdzzCzWH7. I've been looking over the keyconv code trying to find something I'm doing wrong. I did check the ADD result and it wasn't 0.

What would I do with a zero result? Just toss it out as bad key I suppose. I should probably test all output starts with 5... and remove any that don't.

I'm not a member over at stackexchange - though have often found useful help there, so probably should be. Thanks.
sr. member
Activity: 444
Merit: 313
You might find that the multiplication method is from what I know a bit faster.

I don`t mind you posting here, I just found it odd.

The number isn't really magical, it`s just a part of the curve, a constant.

By the way, you should also make sure you don`t get a 0 as the result of the adding.

If you have any more specific questions, you ought to ask them on the StackExchange:
bitcoin.stackexchange.com
hero member
Activity: 784
Merit: 1009
firstbits:1MinerQ
Thank you for that. It works! As I said I really don't understand the math. I had no idea the order was a constant. I thought it had to be calculated for each key!

I'm using the add method for creating keys as that is what vanitygen supports. I'll look into your mining pool as I get further. I didn't really think there would be money in this  and was doing it more for the fun of setting up something using Bitcoin - my first dev project in this area.

I didn't mean to offend by posting here. After being awake all night, coding and trying to figure out the right way to add keys I came across this thread and figured someone here probably has some clue how the math works. My apologies.

So it's a magic number, like 42... hmmm.
sr. member
Activity: 444
Merit: 313
And that's related to this bounty how exactly?

As for the N, as far as I remember it should be FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - it`s specified for the secp256k1 ecdsa curve:
https://en.bitcoin.it/wiki/Secp256k1

As for your backend, you can always try getting it switched to my Vanity Pool to potentially get more work.

By the way, are you using the addition or multiplication method of generating keys, or just the standard method that requires the users to trust you not to keep their private keys?
hero member
Activity: 784
Merit: 1009
firstbits:1MinerQ
I'm working on a web site for creating vanity addresses. It's very easy for users to submit a request and have it fulfilled on my mining backend. It auto-switches from mining Bitcoin to finding a vanity address and back on demand. I'm also currently adding some code to spawn Amazon EC2 instances for doing regex searches as needed.

I actually have this all working now and I'm testing the whole thing. My website generates a "login key" for a new user and uses that to send a public key to my server. ie. like blockchain.info the private key never leaves the browser. The public key becomes the unique identifier (session) for each user. I generate the partial key (using oclvanitygen) and feed it back to the client to be combined. A nice looking interface and result reporting are already done. Users can get HTML, JSON, CSV and SQL versions of output data with just a click.

But I have a big problem. Some keys are not combined correctly and give bad results. I think I know what this is - but I *really* don't understand the math and so have been stumbling along. The problem seems to be that I am just using BigNumber ADD and not doing a MOD after. The reason being that I have no idea how to get the modulus N to use for that. In the keyconv program it uses EC_GROUP_get _order from OpenSSL.

I'm using BitcoinJS and the jsbn module to do the ADD function. It works often but not always. I've been digging around trying to figure out how to do the get_order using javascript. Any ideas? Having the key re-combine in the browser opens vanity addresses up to a wider "newbie" audience, with a nicer interface, and I think it's quite worthwhile.

Thx.
sr. member
Activity: 444
Merit: 313
And the 12 Bitcoin bounty goes to samr7 and his oclvanityminer, available from here:
https://bitcointalksearch.org/topic/vanitygen-vanity-bitcoin-address-generatorminer-v022-25804

Thanks to everyone for your interest and support, especially Uncurlhalo for contributing to the bounty and samr7 for his hard work and wonderful contribution.
sr. member
Activity: 444
Merit: 313
Well, the MainNet version of the website is up in case one needs more incentive to work on claiming the bounty, or just developing a working solution for themselves to claim all the prizes;) :
https://bitcointalksearch.org/topic/my-bitcoin-master-thesis-88149
sr. member
Activity: 444
Merit: 313
I'm also hoping some people/businesses will want to order their addresses in bulk, which could make things interesting...

Interesting idea.  So, by ordering in bulk, you mean post multiple bounties with the same public key?  Then the mining client can run them all at the same time, and when deciding which bounties to go after, it should sum the cost-reward of all bounties with the same public key.

Well, it could be either doing that, or posting a few bounties for the same vanity address prefix with different public keys. I guess the first method would be more preferable for people that provide solutions for a lot of different businesses, while the latter would be better for companies that want a number of addresses to identify with their one business. One or either way, it can be interesting...
full member
Activity: 140
Merit: 430
Firstbits: 1samr7
I'm also hoping some people/businesses will want to order their addresses in bulk, which could make things interesting...

Interesting idea.  So, by ordering in bulk, you mean post multiple bounties with the same public key?  Then the mining client can run them all at the same time, and when deciding which bounties to go after, it should sum the cost-reward of all bounties with the same public key.
sr. member
Activity: 444
Merit: 313
This thing enables a whole business model, and it's good for a bunch of reasons.  There won't be room for many sites like this, because the bounty will be held in a sort of escrow, and potential customers won't want to pay the bounty twice or three times.  So they'll pick the site with the most compute power.  The way it's shaping up, they'll also have to post a reward large enough to beat out the current top bounty on reward-to-difficulty in order to get their job prioritized.

Yeah, eventually the mining tools will probably be prioritizing the addresses to mine which will regulate the reward model better than any pre-set cost per character would (as far as I remember someone mentioned that in the Vanity Pool post). I'm also hoping some people/businesses will want to order their addresses in bulk, which could make things interesting...

I might have been too nitpicky about two URLs, that works fine, and it will do the job going forward.  However, how would you change it in a backward-compatible way to support something like a case-insensitivity flag?

If I had to design it from scratch though, maybe the bitcoin JSON-RPC model would be a good choice.

Well, I'll probably want to do as much as I can with the current system, and if I won't be able to handle something important, I'll probably start making versions of the protocol.

While JSON-RPC model would probably be more than enough, I think keeping it the simplest for now would suffice. But hey, that's what the testing phase is for;).

Yep that was me.  The payment did go through, and it shows up on block explorer.  My testnet client unfortunately didn't see it because the transaction is on testnet2 and my client is on testnet3.

The pool keeps 20%, or 1 tBTC?

Currently the pool keeps 20%, might implement some cap or change the value if needed be. It all depends on how people will be using the Pool and what the costs of operation will be. The Pool and Bitcoind are running currently on two clouds, so the costs can change a lot with popularity of the service.
full member
Activity: 140
Merit: 430
Firstbits: 1samr7
Thank you, but it's not really that complicated.

This thing enables a whole business model, and it's good for a bunch of reasons.  There won't be room for many sites like this, because the bounty will be held in a sort of escrow, and potential customers won't want to pay the bounty twice or three times.  So they'll pick the site with the most compute power.  The way it's shaping up, they'll also have to post a reward large enough to beat out the current top bounty on reward-to-difficulty in order to get their job prioritized.

Quote
I guess you are right about the two strings, kind of silly of me to split them up. I'll probably just add the additional functionality to the /getWork address and delete the reference to the other one in the protocol specification, while still supporting it for awhile.

As for "knowing all of this", you give me a bit too much credit - I'm not really that proficient of a web programmer. I do a lot of projects because I know nothing about the field - my bachelor's thesis was about AI and used OpenGL, didn't know much about either before I started, and my master's thesis was about Bitcoin, Google App Engine and Go, also haven't used any before I started. When it comes to web stuff, I'm still learning a lot.

So, could you elaborate a bit more?

I might have been too nitpicky about two URLs, that works fine, and it will do the job going forward.  However, how would you change it in a backward-compatible way to support something like a case-insensitivity flag?

If I had to design it from scratch though, maybe the bitcoin JSON-RPC model would be a good choice.

Quote
From what I can see, the bounty was claimed by someone with the public key of
C2042FBA7ABE6DF861F7EF45E297EB684BE107D8CC4752F7740E7141FCD22470
Which uses the additive split-key mining. I programmed the Pool to not do anything with the bounty if some data is incorrect - be it an invalid key or Bitcoin address. This way the coins don't get lost or stolen by someone providing a valid solution without the proper means to pay. I figured this would be the fairest - I could implement a Pool that would register a solution without a valid payout address, but it is a bit wrong in my opinion.

If all the data is correct, the Pool will attempt to send the bounty and clean everything up. I'm currently in the process of adding in some extra error handling and pushing the payout onto a separate thread. As Bitcoind is on a different server than the Pool, I can't expect both of them to be able to communicate all of the time. But that will be in the next version I'm preparing. For now some errors can occur - at some point I got a bug that allowed me to pay myself the bounty twice over (happened due to the call to Bitcoind timing out - the payment went through, but it did not register in the Pool).

Yep that was me.  The payment did go through, and it shows up on block explorer.  My testnet client unfortunately didn't see it because the transaction is on testnet2 and my client is on testnet3.

The pool keeps 20%, or 1 tBTC?
sr. member
Activity: 444
Merit: 313
Hi ThePiachu,

I really like what you've done with vanity pool!  This has a lot of potential.
Thank you, but it's not really that complicated.
- Give an option to the user to automatically fetch and submit work from a "vanity mining pool" through the use of the protocol outlined in https://vanitypooltest.appspot.com/faq

You might want to overhaul this a little bit before it becomes more popular.  It ought to behave more like a standard web service, with one URL to do everything, rather than two.  And if you're going to use POST, the example code shouldn't put the parameters in a query string, it should use x-www-form-urlencoded.  But you already know all of this, and are just trying to look like an upstart, and I respect that.
I guess you are right about the two strings, kind of silly of me to split them up. I'll probably just add the additional functionality to the /getWork address and delete the reference to the other one in the protocol specification, while still supporting it for awhile.

As for "knowing all of this", you give me a bit too much credit - I'm not really that proficient of a web programmer. I do a lot of projects because I know nothing about the field - my bachelor's thesis was about AI and used OpenGL, didn't know much about either before I started, and my master's thesis was about Bitcoin, Google App Engine and Go, also haven't used any before I started. When it comes to web stuff, I'm still learning a lot.

So, could you elaborate a bit more?
Indeed it found a match for "1Testo2" on vanitypooltest.appspot.com, which took a few hours on a cluster of AMD 5830s.  Unfortunately, while the address to receive the bounty passed validation, it wasn't valid in this case -- the bounty is in testnet coins, and the address is a regular net address.  The pool server replied with an error about the address not appearing to be valid, which is good, but it's unclear what the pool server did with the bounty.
From what I can see, the bounty was claimed by someone with the public key of
C2042FBA7ABE6DF861F7EF45E297EB684BE107D8CC4752F7740E7141FCD22470
Which uses the additive split-key mining. I programmed the Pool to not do anything with the bounty if some data is incorrect - be it an invalid key or Bitcoin address. This way the coins don't get lost or stolen by someone providing a valid solution without the proper means to pay. I figured this would be the fairest - I could implement a Pool that would register a solution without a valid payout address, but it is a bit wrong in my opinion.

If all the data is correct, the Pool will attempt to send the bounty and clean everything up. I'm currently in the process of adding in some extra error handling and pushing the payout onto a separate thread. As Bitcoind is on a different server than the Pool, I can't expect both of them to be able to communicate all of the time. But that will be in the next version I'm preparing. For now some errors can occur - at some point I got a bug that allowed me to pay myself the bounty twice over (happened due to the call to Bitcoind timing out - the payment went through, but it did not register in the Pool).
full member
Activity: 140
Merit: 430
Firstbits: 1samr7
Hi ThePiachu,

I really like what you've done with vanity pool!  This has a lot of potential.

- Give an option to the user to automatically fetch and submit work from a "vanity mining pool" through the use of the protocol outlined in https://vanitypooltest.appspot.com/faq

You might want to overhaul this a little bit before it becomes more popular.  It ought to behave more like a standard web service, with one URL to do everything, rather than two.  And if you're going to use POST, the example code shouldn't put the parameters in a query string, it should use x-www-form-urlencoded.  But you already know all of this, and are just trying to look like an upstart, and I respect that.

Anyway, there is currently source code to a vanitygen derivative that implements a polling loop and other mining client features, and it is available on github.  Here's what it looks like:

Code:
# ./oclvanityminer -p 0 -d 0 -u https://vanitypooltest.appspot.com/ -a 1samr7UZxtC6MEAFHqr1h3Kq453xJJbe4
Searching for pattern: "1Testo2" Reward: 5.000000 Value: 0.020260 BTC/MkeyHr
Difficulty: 888446610538
Compiling kernel, can take minutes...done!
Pattern: 1Testo2                                                               
Address: 1Testo2cH7JbqERjEkTz4MfmP2mQh6Aoi
PrivkeyPart: 5KHjU9V8tR6HNfoL5ZFmkgLzPPGt1u2BjQFMmL31ZtNWovptxDj

Like other mining software, oclvanityminer must be given a URL to the bounty server, with the -u parameter.  This URL is a base URL to which the /getWork and /solve paths are appended.  It also requires an address to receive bounties, specified with the -a parameter, which is checked against typos and cut-and-paste errors.  The other parameters specify which OpenCL device to use, and are the same as oclvanitygen.

The miner follows the basic logic of mskwik's perl script -- it polls the server on regular intervals, and selects the best bounty based on difficulty and reward.  If the best bounty has changed since the last poll, it will reconfigure the OpenCL engine.  If no bounties are available, it will halt the OpenCL engine.

Indeed it found a match for "1Testo2" on vanitypooltest.appspot.com, which took a few hours on a cluster of AMD 5830s.  Unfortunately, while the address to receive the bounty passed validation, it wasn't valid in this case -- the bounty is in testnet coins, and the address is a regular net address.  The pool server replied with an error about the address not appearing to be valid, which is good, but it's unclear what the pool server did with the bounty.

The address miner has a few wrinkles left to be worked out and isn't formally released yet.  For anyone who wants to try it out, there is a win32 binary of the miner program posted here.
sr. member
Activity: 444
Merit: 313
Ah, I see there is work now, data format just got switched around so it wasn't picking it up, will have to adjust that miner script.

Yeah, sorry about that, but this way things are more human-readable when it comes to a few things.
full member
Activity: 125
Merit: 100
Ah, I see there is work now, data format just got switched around so it wasn't picking it up, will have to adjust that miner script.
sr. member
Activity: 444
Merit: 313
I'll add a couple coins to the bounty. I would like to see something like this since it would allow an alternative to bitcoin mining as a source of revenue. Plus it will allow people to create whatever vanity addresses they wanted and hopefully receive them in a timely fashion. I just sent payment.

Thank you, your extra coins have been added to the bounty. Thank you for your support.

Well the code differences to have vanitygen do the generation are trivial, it only takes a handful of lines of code to get both the cpu and ocl versions to generate addresses (with the multiplication method) without any loss of speed.

Yes, I expected as much, but just in case lowered the required address generation rate by half just in case.

Not heavily tested since there hasn't been too much work posted there [...]

I posted a few test pieces of work to the site, and I see someone else also posted their desired address. Adding your own work is pretty simple, and since everything runs on testnet, it doesn't cost anything to test.
full member
Activity: 125
Merit: 100
So if you need something to get started with here's what I patched vanitygen with:

Code:
*** pattern.c.orig Fri Jun 29 01:51:26 2012
--- pattern.c Wed Jun 27 22:25:46 2012
***************
*** 42,47 ****
--- 42,52 ----
  int
  vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)
  {
+ EC_GROUP *ecgrp;
+ EC_POINT *tmpg;
+ BIGNUM order;
+ BIGNUM cofactor;
+
   memset(vxcp, 0, sizeof(*vxcp));
  
   vxcp->vxc_vc = vcp;
***************
*** 50,61 ****
   BN_init(&vxcp->vxc_bnbase);
   BN_init(&vxcp->vxc_bntmp);
   BN_init(&vxcp->vxc_bntmp2);
  
   BN_set_word(&vxcp->vxc_bnbase, 58);
  
   vxcp->vxc_bnctx = BN_CTX_new();
   assert(vxcp->vxc_bnctx);
! vxcp->vxc_key = EC_KEY_new_by_curve_name(NID_secp256k1);
   assert(vxcp->vxc_key);
   EC_KEY_precompute_mult(vxcp->vxc_key, vxcp->vxc_bnctx);
   return 1;
--- 55,76 ----
   BN_init(&vxcp->vxc_bnbase);
   BN_init(&vxcp->vxc_bntmp);
   BN_init(&vxcp->vxc_bntmp2);
+ BN_init(&order);
+ BN_init(&cofactor);
  
   BN_set_word(&vxcp->vxc_bnbase, 58);
  
   vxcp->vxc_bnctx = BN_CTX_new();
   assert(vxcp->vxc_bnctx);
! ecgrp=EC_GROUP_new_by_curve_name(NID_secp256k1);
! if(vcp->vc_opubkey){
!  tmpg=EC_POINT_hex2point(ecgrp,vcp->vc_opubkey,NULL,NULL);
!  EC_GROUP_get_order(ecgrp,&order,NULL);
!  EC_GROUP_get_cofactor(ecgrp,&cofactor,NULL);
!  EC_GROUP_set_generator(ecgrp,tmpg,&order,&cofactor);
! }
! vxcp->vxc_key = EC_KEY_new();
! EC_KEY_set_group(vxcp->vxc_key, ecgrp);
   assert(vxcp->vxc_key);
   EC_KEY_precompute_mult(vxcp->vxc_key, vxcp->vxc_bnctx);
   return 1;
*** pattern.h.orig Fri Jun 29 01:51:40 2012
--- pattern.h Wed Jun 27 09:14:34 2012
***************
*** 76,81 ****
--- 76,82 ----
   double vc_chance;
   const char *vc_result_file;
   const char *vc_key_protect_pass;
+ const char *vc_opubkey;
   int vc_remove_on_match;
   int vc_verbose;
   vg_free_func_t vc_free;
*** oclvanitygen.c.orig Wed Mar 21 19:54:31 2012
--- oclvanitygen.c Fri Jun 29 02:04:31 2012
***************
*** 2541,2546 ****
--- 2541,2547 ----
  "Options:\n"
  "-v            Verbose output\n"
  "-q            Quiet output\n"
+ "-D            Print difficulty info only and exit\n"
  "-r            Use regular expression match instead of prefix\n"
  "              (Feasibility of expression is not checked)\n"
  "-i            Case-insensitive prefix search\n"
***************
*** 2550,2555 ****
--- 2551,2557 ----
  "-X  Generate address with the given version\n"
  "-e            Encrypt private keys, prompt for password\n"
  "-E Encrypt private keys with (UNSAFE)\n"
+ "-P Add Public key to generated before checking\n"
  "-p Select OpenCL platform\n"
  "-d   Select OpenCL device\n"
  "-S            Safe mode, disable OpenCL loop unrolling optimizations\n"
***************
*** 2580,2585 ****
--- 2582,2588 ----
   FILE *fp = NULL;
   char **patterns, *pend;
   int verbose = 1;
+ int diffonly = 0;
   int npatterns = 0;
   int nthreads = 0;
   int worksize = 0;
***************
*** 2592,2600 ****
   cl_device_id did;
   const char *result_file = NULL;
   const char *key_password = NULL;
  
   while ((opt = getopt(argc, argv,
!     "vqrikNTX:eE:p:d:w:t:g:b:VSh?f:o:s:")) != -1) {
   switch (opt) {
   case 'v':
   verbose = 2;
--- 2595,2604 ----
   cl_device_id did;
   const char *result_file = NULL;
   const char *key_password = NULL;
+ const char *opubkey = NULL;
  
   while ((opt = getopt(argc, argv,
!     "vqrDikNTX:eE:p:d:w:t:g:b:VSh?f:o:s:P:")) != -1) {
   switch (opt) {
   case 'v':
   verbose = 2;
***************
*** 2605,2610 ****
--- 2609,2617 ----
   case 'r':
   regex = 1;
   break;
+ case 'D':
+        diffonly = 1;
+        break;
   case 'i':
   caseinsensitive = 1;
   break;
***************
*** 2717,2722 ****
--- 2724,2732 ----
   }
   seedfile = optarg;
   break;
+ case 'P':
+        opubkey = optarg;
+        break;
   default:
   usage(argv[0]);
   return 1;
***************
*** 2785,2790 ****
--- 2795,2801 ----
   vcp->vc_verbose = verbose;
   vcp->vc_result_file = result_file;
   vcp->vc_remove_on_match = remove_on_match;
+ vcp->vc_opubkey = opubkey;
  
   if (!vg_context_add_patterns(vcp, patterns, npatterns))
   return 1;
***************
*** 2811,2816 ****
--- 2822,2830 ----
   fprintf(stderr,
   "Regular expressions: %ld\n", vcp->vc_npatterns);
  
+ if(diffonly==1)
+ return 0;
+
   did = get_opencl_device(platformidx, deviceidx);
   if (!did) {
   return 1;

And here's the simple script to run it (the few configurable things are variables at the top) (Now edited to work with the new getwork data format)

Code:
#!/usr/bin/perl

$newworkpolltime=180;
$vanitygen="./oclvanitygen -d 0 -p 0";
$myaddress="mhFwRrjRNt8hYeWtm9LwqCpCgXjF38RJqn";

use IO::Handle;
use IO::Select;
$|=1;

while(1){
  if($servercheck    print "\nPolling server for new work\n";undef %prefix;undef %diff;
    @data=readpipe("curl -L -m 20 -s https://vanitypooltest.appspot.com/getWork");
    foreach $l(@data){chomp($l);
      ($p,$pk,$n,$r,@x)=split(/:/,$l);
      $n=int($n);$p=~s/[^0-9a-zA-Z]//g;$pk=~s/[^0-9a-fA-F]//g;
      $_=readpipe($vanitygen." -X $n -D $p 2>&1");
      if(/Difficulty: ([0-9]*)/ig){$d=$1;
        $d=int($r/$d*(10**14));if($d>0){
          $diff{"$pk:$n"}+=$d;$prefix{"$pk:$n"}.=$p." ";
        }
      }
    }my @d;
    for my $k(keys %diff){push(@d,$diff{$k}.":".$k);}
    @work=sort{($b=~/([0-9\.]*):(.*)/)[0]<=>($a=~/([0-9\.]*):(.*)/)[0]}@d;
  }
  ($d,$pk,$n)=split(/:/,$work[0]);$p=$prefix{"$pk:$n"};
  if($d==0){
    if($running ne ''){close($vgen);kill(15,$pid);$running='';}
    print "No work\n";sleep(30);
  }
  if($running ne "$pk:$n:$p" && $d>0){
    if($running ne ''){close($vgen);kill(15,$pid);}
    $running="$pk:$n:$p";
    $pid=open($vgen, $vanitygen." -X $n -P $pk -v $p 2>&1 |");
    $ss=IO::Select->new();$ss->add($vgen);
    $vgen->blocking(0);$searchpk=$pk;
  }
  if($running ne ''){if($ss->can_read(5)){$line=$vgen->getline();
    while($line){print $line;
      $_=$line;if(/Pattern: ([0-9a-zA-Z]*)/ig){$foundp=$1;}
      $_=$line;if(/Privkey \(hex\): ([0-9A-F]*)/ig){$foundk=$1;
        print "\nSubmitting found work\n";
        $url="https://vanitypooltest.appspot.com/solveWork?key=$foundp%3A$searchpk&privateKey=$foundk&bitcoinAddress=$myaddress";
        $data=readpipe("curl -L -m 30 -s \"$url\"");chomp($data);
print "\nServer returned $data\n";
shift(@work);
      }$line=$vgen->getline();
    }
  }}sleep(1);
}

Not horribly user-friendly, but a reasonable starting spot.
Pages:
Jump to: