Title: . Post by: ingrownpocket on October 27, 2014, 05:31:24 PM .
Title: Re: Generate new addresses using PHP with an Armory wallet Post by: inf on October 28, 2014, 12:08:58 PM Of course you can, but i guess you have to write that lib on your own...
Take a look at https://github.com/etotheipi/BitcoinArmory/blob/d59e38d2904e7054b3c71728439b085033e10260/cppForSwig/EncryptionUtils.cpp#L768 how chained public keys are computed in Armory and port it to PHP. You need nothing more than the root public key and the chaincode then on your webserver. Title: Re: Generate new addresses using PHP with an Armory wallet Post by: inf on October 28, 2014, 07:43:05 PM Hi,
I sat down half an hour and coded a function in PHP to compute chained pubkeys for armory based on Bit-Wasps bitcoin lib (https://github.com/Bit-Wasp/bitcoin-lib-php (https://github.com/Bit-Wasp/bitcoin-lib-php)): Code: function compute_chained_pubkey($pubkey, $chaincode) You now need to extract the root pubkey and the chaincode from the armory wallet (I do it with a hex editor according to the wallet format in https://bitcoinarmory.com/developers/armory-wallet-files/ (https://bitcoinarmory.com/developers/armory-wallet-files/)). Then you can for example generate the first 10 addresses in the chain like this: Code: $rootpubkey = "04428C01906362DA5484B316C807C8B2A45603290515BBDBB2ACA1C4AFA7802DE81BB1C20BEB3B6CD32EAB4DEACCBE26EBA7FDFEA2DCC35E3ACA2704CFAD05589D"; If this helped you, I would appreciate some donation to the first address in the example chain :) Title: Re: Generate new addresses using PHP with an Armory wallet Post by: inf on October 28, 2014, 10:03:34 PM EDIT: Please see my next post in this thread, in which I corrected some mistakes from this post!
Yep, this is the first address of my wallet. Cool, I did not know one can export this watch-only wallet data directly as well. But it seems to be a bit more complicated than I thought this way. The translation map is this: NORMALCHARS = '0123 4567 89ab cdef' EASY16CHARS = 'asdf ghjk wert uion' so your export translates to 817d 9216 ee19 0036 ba 749d 0e7a 9da0 451b 23e2 cb23 26b9 baeb 8446 b0dc 4a3a 0cb7 d2a9 bc45 1e2d 28c7 3388 191f 7e9b 5347 b656 7083 4921 84af 95bb 8e3e 3db0 745b f145 bb9b fbd0 4447 b6e2 cfc7 2408 2056 The green part is the x-coord of the root public key, the red part is the chaincode. The blocks after them are checksums. I do not know yet what the root ID is for. But half the key does not help, you have to calculate the y-part... I will look into it tomorrow, or maybe someone else can elaborate quicker, it is too late in the night now here for me ;) EDIT: Okay, the root ID simply contains the wallet id + checksum. Anyway, you have to calculate the y-coord from the x-coord via elliptic curve math (in the bitcoin-php-lib with BitcoinLib::decompress_public_key()) but you need the parity byte for that, which I do not see in this backup data. But I will look into it tomorrow again. EDIT2: Okay, powered by such a generous tip I found the part which is encoding the root data :D: Code: ---PART 1: Root Data ID (9 bytes)--- So the parity is encoded in the MSB of the first byte, which in your case is 0x81 = 10000001b, so the sign is +. So your compressed public root key translates to Code: !03! 749d 0e7a 9da0 451b 23e2 cb23 26b9 baeb 8446 b0dc 4a3a 0cb7 d2a9 bc45 1e2d 28c7 Using Code: $rootpubkey = BitcoinLib::decompress_public_key("03749d0e7a9da0451b23e2cb2326b9baeb8446b0dc4a3a0cb7d2a9bc451e2d28c7"); returns the following first 10 adresses in your wallet: Code: 14nTEtvpN7yBUZDcDnvYfBkGMpQmp4hQn6 Is this correct? Good night :) Title: Re: Generate new addresses using PHP with an Armory wallet Post by: etotheipi on October 29, 2014, 03:05:13 PM It's kind of fun watching you guys attempt to reverse engineer this stuff :)
Looks like inf got it except for one mistake (if I read his text formatting correctly): the lines in the backup data actually have 2-bytes of checksum per line, instead of 4 bytes of checksum per two lines. i.e. you wrote: 817d 9216 ee19 0036 ba 749d 0e7a 9da0 451b 23e2 cb23 26b9 baeb 8446 b0dc 4a3a 0cb7 d2a9 bc45 1e2d 28c7 3388 191f 7e9b 5347 b656 7083 4921 84af 95bb 8e3e 3db0 745b f145 bb9b fbd0 4447 b6e2 cfc7 2408 2056 But it should be: Quote 817d 9216 ee19 0036 ba 749d 0e7a 9da0 451b 23e2 cb23 26b9 baeb 8446 b0dc 4a3a 0cb7 d2a9 bc45 1e2d 28c7 3388 191f 7e9b 5347 b656 7083 4921 84af 95bb 8e3e 3db0 745b f145 bb9b fbd0 4447 b6e2 cfc7 2408 2056 You can confirm your understanding of it by look up the two functions "makeSixteenBytesEasy()" and "readSixteenEasyBytes()" (both are in ArmoryUtils.py) Title: Re: Generate new addresses using PHP with an Armory wallet Post by: inf on October 29, 2014, 05:05:29 PM Hi all,
thank you, etotheipi, I stand corrected. I wanted to help too quickly last night :) And yes, I am reverse engineering the shit out of the Armory code, tx files and wallets since several weeks lately, I hope I can present soon what for :D I took another 30 mins and wrote a (now tested and working) import function in PHP: Code: function import_watchonly_wallet($root_id, $root_data) You can use it like this now: Code: $root_id = "wski edsj oose aafj tr"; which actually spits out now Code: 13N77TDamXjsHH1mHFgBty3VLbHBidychP Have fun! Btw, I would generate the rootpubkey and chaincode only once and store it somehow, then. You also do not have to start the generation again beginning with the root pubkey, just always store the last used pubkey and generate more from that point, this saves computation time. |