Bitcoin Forum
May 28, 2024, 06:35:58 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Raw Tx Tool - Use for coin control, and never accidentally pay a huge fee again!  (Read 4537 times)
mb300sd (OP)
Legendary
*
Offline Offline

Activity: 1260
Merit: 1000

Drunk Posts


View Profile WWW
October 22, 2013, 06:43:00 AM
Last edit: October 25, 2013, 03:06:31 AM by mb300sd
 #1

Avoid horror stories like this one, https://bitcointalk.org/index.php?topic=296217.0

Use this tool for creating your raw transactions.
Lets you graphically build the transaction, selecting inputs from multiple sources at the same time.
Calculates total inputs, outputs and tx fee to prevent costly mistakes.
Sign transactions with keys from multiple sources.
Broadcast tx with a click of a button.



Source: https://github.com/mb300sd/RawTxTool
Binary: https://github.com/mb300sd/RawTxTool/raw/master/bin/RawTxTool.exe
Disassembler if you don't trust my binaries and can't compile: http://ilspy.net/

This is pre-alpha code. Please double check everything with decoderawtransaction in bitcoind if your dealing with significant amounts of coins. I am not responsible if this code causes loss of coins.

1D7FJWRzeKa4SLmTznd3JpeNU13L1ErEco
piotr_n
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
October 22, 2013, 10:26:52 AM
 #2

Great stuff, man.

Think about adding an option to export the fetched inputs to a file - and then to get them from the file at another (offline) PC.

By this you will essentially turn your app into a nice cold wallet solution, that can work with bitcoind gateway, or even without it.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
jgarzik
Legendary
*
qt
Offline Offline

Activity: 1596
Merit: 1091


View Profile
October 22, 2013, 03:04:46 PM
 #3

Glad to see a GUI version of my txtool crop up Smiley   https://github.com/jgarzik/txtool/

Jeff Garzik, Bloq CEO, former bitcoin core dev team; opinions are my own.
Visit bloq.com / metronome.io
Donations / tip jar: 1BrufViLKnSWtuWGkryPsKsxonV2NQ7Tcj
mb300sd (OP)
Legendary
*
Offline Offline

Activity: 1260
Merit: 1000

Drunk Posts


View Profile WWW
October 22, 2013, 03:59:55 PM
Last edit: October 24, 2013, 01:18:49 AM by mb300sd
 #4

Great stuff, man.

Think about adding an option to export the fetched inputs to a file - and then to get them from the file at another (offline) PC.

By this you will essentially turn your app into a nice cold wallet solution, that can work with bitcoind gateway, or even without it.

Done.

Binaries: https://mega.co.nz/#!5RZ1EboJ!LTvWpR3xXDY1vZYCtJzm5kWyTHt8TB-CQgvL1OaqTFU

1D7FJWRzeKa4SLmTznd3JpeNU13L1ErEco
piotr_n
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
October 22, 2013, 05:10:14 PM
Last edit: October 22, 2013, 05:35:56 PM by piotr_n
 #5

BTW guys, maybe we should think of some kind of standard for such a "wallet balance" file.

Because I also have a wallet app which does quite the same things and it would be cool if it could import the data from other blockchain sources, rather than only the one I developed myself. It would be nice if it could also take a file that e.g. "Raw Tx Tool" fetched from blockchain.info. It's very useful, since then you don't need any bitcoin node, but just your wallet and blockchain.info webpage and you can still receive and send money using a cold wallet of your choice.


What I use is a zip file that contains unspent.txt, where each line has a format of:
Code:
<txid>-<vout> # comment (amount, b58 address, etc - not mandatory)

Besides the text file, inside the zip, there is a number of <txid>.tx files, that carry a binary content of the transactions mentioned in the unspent.txt

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
chriswilmer
Legendary
*
Offline Offline

Activity: 1008
Merit: 1000


View Profile WWW
October 22, 2013, 05:17:13 PM
 #6

Quick question... can this be used to "read" raw transactions? That is something I would really appreciate having!
mb300sd (OP)
Legendary
*
Offline Offline

Activity: 1260
Merit: 1000

Drunk Posts


View Profile WWW
October 22, 2013, 05:51:12 PM
Last edit: October 24, 2013, 04:18:12 AM by mb300sd
 #7

The issue with reading raw tx, and the above file format, is that it doesn't contain complete original txout, which is required to get the address and to sign the tx. (bitcoind only requires txid and vout because it has all the tx already)

I could add a gui popup with the output of decoderawtransaction if thats of any use.
Edit: added ability to decode pasted raw transaction, but requires access to bitcoind or blockchain

The current output format is
32 bytes txid
4 bytes vout
x bytes txout (same format as serialized into transaction)
repeat

The code uses my BitcoinTool library (https://github.com/mb300sd/Bitcoin-Tool) which has functions to directly read and write the binary formats used by bitcoind

1D7FJWRzeKa4SLmTznd3JpeNU13L1ErEco
jgarzik
Legendary
*
qt
Offline Offline

Activity: 1596
Merit: 1091


View Profile
October 22, 2013, 06:02:46 PM
 #8


See BIP 10 for a transaction distribution format: https://en.bitcoin.it/wiki/BIP_0010

I'm not sure it's my favorite format, but it's the one concrete proposal right now.


Jeff Garzik, Bloq CEO, former bitcoin core dev team; opinions are my own.
Visit bloq.com / metronome.io
Donations / tip jar: 1BrufViLKnSWtuWGkryPsKsxonV2NQ7Tcj
piotr_n
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
October 23, 2013, 01:00:30 PM
 #9


See BIP 10 for a transaction distribution format: https://en.bitcoin.it/wiki/BIP_0010

I'm not sure it's my favorite format, but it's the one concrete proposal right now.
Thanks.

To be honest, I prefer moving txs to/from my cold storage in a raw format.
Then I can easily check if a tx has not been tempered with, doing e.g.:
Code:
cat transaction.bin | openssl sha256 -binary | openssl sha256

Besides, before spending them my wallet app needs the original raw data anyway, to make sure that it has the expected ID.
So IMO, it is more convenient for a wallet app to have a tx (carrying an unspent output) as a raw data already.

And if I need to see whats inside a raw tx, I have a tool to display it in a human readable format.
I always use it on a signed tx, before moving it out from my cold storage. Just in case if my wallet would screw something up.

Code:
/*
gcc bctrans.c -o bctrans.exe -lcrypto -I /local/ssl/include -L /local/ssl/lib
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <strings.h>
#include <openssl/sha.h>
#include <openssl/bn.h>


static unsigned char addr_version = 0x00;
static FILE *f = NULL;

BIGNUM *bn58, dv, mo;
BN_CTX *ctx;


#define SHA256(p,l,o) { \
SHA256_CTX shactx; \
SHA256_Init(&shactx); \
SHA256_Update(&shactx, (p), (l)); \
SHA256_Final((o), &shactx); }


void readfile(unsigned char *p, int len) {
if (!f) {
int c, i;
char s[3];
while (len>0) {
for (i=0;i<2;) {
c = getchar();
if (c==EOF) {
fprintf(stderr, "File too short\n");
exit(1);
}
c = tolower(c);
if (c<='9' && c>='0' || c<='f' && c>='a')  s[i++] = (char)c;
}
s[2] = 0;
sscanf(s, "%x", &c);
*p = (unsigned char)c;
p++;
len--;
}
} else {
if (fread(p, 1, len, f)!=len) {
fprintf(stderr, "File too short\n");
fclose(f);
exit(1);
}
}
}

unsigned long long getle(unsigned char *p, int bytes) {
unsigned long long res=0;
while (bytes--) {
res|= ((unsigned long long)(p[bytes]))<<(8*bytes);
}
return res;
}

unsigned long long getvl() {
unsigned char b[8];
readfile(b, 1);
switch (*b) {
case 0xfd:
readfile(b, 2);
return getle(b, 2);
case 0xfe:
readfile(b, 4);
return getle(b, 4);
case 0xff:
readfile(b, 8);
return getle(b, 8);
}
return *b;
}


void prhash(unsigned char *p, unsigned int l) {
while (l--) printf("%02x", p[l]);
}


void hexdump(unsigned char *p, unsigned int l) {
while (l--) printf("%02x", *p++);
}


void printbtcaddr(unsigned char *p) {
static const char *chrs = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
unsigned char mod;
char out[64];
int i=0, j=0;
BIGNUM *bn = BN_bin2bn(p, 25, NULL);
while (!BN_is_zero(bn)) {
BN_div(&dv, &mo, bn, bn58, ctx);
if (BN_bn2bin(&mo, &mod)==0)  mod = 0;
out[i++] = chrs[mod];
BN_copy(bn, &dv);
}
BN_free(bn);
while ((*p)==0) {
putchar('1');
p++;
}
while (i--)  putchar(out[i]);
}


int main(int argc, char * argv[]) {
static unsigned char buf[0x10000];
unsigned long long i, sl, txcnt, v;
unsigned va, vb;
int x;
long fpos;
char *fname = NULL;

for (x=1; x<argc; x++) {
if (strcmp(argv[x], "-t")==0) {
addr_version = 0x6f; // testnet
} else {
fname = argv[x];
}
}

if (!fname) {
printf("Enter transactions hexdump data:\n");
} else {
f = fopen(fname, "rb");
if (!f) {
fprintf(stderr, "File %s not found\n", fname);
return 1;
}
}

readfile(buf, 4);
printf("Version: %llu\n", getle(buf, 4));

txcnt = getvl();
printf("TX IN cnt: %llu\n", txcnt);
for (i=0; i<txcnt; i++) {
readfile(buf, 36);
sl = getvl();

printf("%6d) : ", (int)i);
prhash(buf, 32);
printf(" Idx=%2lld  sl=%lld", getle(buf+32, 4), sl);
readfile(buf, sl);
readfile(buf, 4);

printf(" seq=%x\n", (unsigned)getle(buf, 4));
}

txcnt = getvl();
printf("TX OUT cnt: %llu\n", txcnt);

ctx = BN_CTX_new();
bn58 = BN_bin2bn("\x3a", 1, NULL);
BN_init(&dv);
BN_init(&mo);

for (i=0; i<txcnt; i++) {
readfile(buf, 8);
sl = getvl();
v = getle(buf, 8);
va = (unsigned)(v/100000000LL);
vb = (unsigned)(v%100000000LL);
printf("%6d) : %7u.%08u BTC", (int)i, va, vb, sl);
readfile(buf, sl);
if (sl!=25 || memcmp(buf, "\x76\xa9\x14", 3) || buf[23]!=0x88 || buf[24]!=0xac) {
printf("  WARNING! Unexpected SIG_SCRIPT:\n"); hexdump(buf, sl);
} else {
unsigned char dat[25];
unsigned char sha[SHA256_DIGEST_LENGTH];
unsigned char sha2[SHA256_DIGEST_LENGTH];
dat[0] = addr_version; // version
memcpy(dat+1, buf+3, 20);
SHA256(dat, 21, sha);
SHA256(sha, SHA256_DIGEST_LENGTH, sha2);
//printf("  chsum:%02x%02x%02x%02x", sha2[0], sha2[1], sha2[2], sha2[3]);
memcpy(dat+21, sha2, 4);
printf("  to address "); printbtcaddr(dat);
}
putchar('\n');
}

BN_free(bn58);
BN_CTX_free(ctx);

readfile(buf, 4);
printf("Lock Time: %llu\n", getle(buf, 4));

if (f) {
fpos = ftell(f);
fseek(f, 0, SEEK_END);
if (fpos!=ftell(f)) {
printf("WARNING!!! File too long. Only %ld bytes expected (%ld too many)\n",
fpos, ftell(f)-fpos);
} else {
printf("File size checked OK - %ld bytes\n", fpos);
}
fclose(f);
}

return 0;
}

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
mb300sd (OP)
Legendary
*
Offline Offline

Activity: 1260
Merit: 1000

Drunk Posts


View Profile WWW
October 24, 2013, 01:23:51 AM
Last edit: October 24, 2013, 09:14:30 AM by mb300sd
 #10

New version posted, fixes a crash. Been using this to move several hundred bitcoins today.

Edit: added ability to read pasted raw tx

http://goo.gl/K64AQ4

https://github.com/mb300sd/RawTxTool/raw/master/bin/RawTxTool.exe

1D7FJWRzeKa4SLmTznd3JpeNU13L1ErEco
chriswilmer
Legendary
*
Offline Offline

Activity: 1008
Merit: 1000


View Profile WWW
October 24, 2013, 10:25:23 PM
 #11

New version posted, fixes a crash. Been using this to move several hundred bitcoins today.

Edit: added ability to read pasted raw tx

http://goo.gl/K64AQ4

https://github.com/mb300sd/RawTxTool/raw/master/bin/RawTxTool.exe

Thanks again for the ability to read raw tx's... I think that is REALLY AWESOME. Is the Blockchain.info guy listening? THIS WOULD BE REALLY GREAT IF THE PUSHTX PAGE ON BLOCKCHAIN.IFO PARSED RAW TXs SO YOU COULD SEE WHAT YOU ARE DOING BEFORE YOU BROADCAST!

I AM TYPING ALL CAPS BECAUSE I LOVE ALL OF YOU AND AM VERY EXCITED!  Grin
slothbag
Sr. Member
****
Offline Offline

Activity: 369
Merit: 250



View Profile
October 25, 2013, 12:24:04 AM
 #12

Someone should make this for Mac OSX Wink

Install Mono, it'll probably run fine as is.
mb300sd (OP)
Legendary
*
Offline Offline

Activity: 1260
Merit: 1000

Drunk Posts


View Profile WWW
October 25, 2013, 12:29:24 AM
 #13

Someone should make this for Mac OSX Wink

Install Mono, it'll probably run fine as is.

Yes, if anyone is trying to run this on Mono, please send me any errors/missing dependencies, and I'll try to work around. None of my linux boxes have GUIs.

I've also updated the underlying Bitcoin Tool library to support signing p2sh and multisig tx, so it should work here, but as of now its completely untested.

1D7FJWRzeKa4SLmTznd3JpeNU13L1ErEco
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!