Skip to content

Commit

Permalink
Lots of changes including the long awaited support for multi-sig:
Browse files Browse the repository at this point in the history
    - Edited TODO
    - Edited README
    - Added a command to dump "weird" output script types
    - Added detection of a lot more types of scripts in util.cpp, including broken ones
    - In particular, we now properly recognize naked multi-sig output scripts
    - Refactor altcoin codes in a single place
    - Added a P2SH-inspired neat trick to deal with naked multi-sig in allBalances
  • Loading branch information
Znort987 committed Nov 19, 2015
1 parent 72d0821 commit 379a4da
Show file tree
Hide file tree
Showing 14 changed files with 565 additions and 209 deletions.
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ all:parser
@${CPLUS} -MD ${INC} ${COPT} -c cb/dumpTX.cpp -o .objs/dumpTX.o
@mv .objs/dumpTX.d .deps

.objs/txoTypes.o : cb/txoTypes.cpp
@echo c++ -- cb/txoTypes.cpp
@mkdir -p .deps
@mkdir -p .objs
@${CPLUS} -MD ${INC} ${COPT} -c cb/txoTypes.cpp -o .objs/txoTypes.o
@mv .objs/txoTypes.d .deps

.objs/pristine.o : cb/pristine.cpp
@echo c++ -- cb/pristine.cpp
@mkdir -p .deps
Expand Down Expand Up @@ -292,6 +299,7 @@ OBJS= \
.objs/sql.o \
.objs/taint.o \
.objs/transactions.o \
.objs/txoTypes.o \
\
.objs/blake.o \
.objs/bmw.o \
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ blockparser
compendium (there's so many of the darn things these days), but adding your
fave alt is very easy.

Talking about zoo, I've also started to track and document "weird" TXO's
in the chain (comments, p2sh, multi-sigs, bugs, etc ...). Not a complete
compendium yet, but getting there.

A side goal was also to build something that can independently (as in : the
codebase is *very* different from that of bitcoin core) verify some of the
conclusions of other bitcoin implementations, such as how many coins are
Expand Down Expand Up @@ -143,6 +147,32 @@ blockparser

http://askubuntu.com/questions/178712/how-to-increase-swap-space

How does it blockparser deal with multi-sig transactions ?
----------------------------------------------------------

AFAIK, there are two types of multi-sig transactions:

1) Pay-to-script (which is in fact more general than multisig). This one is
easy, because it pays to a hash, which can readily be converted to an
address that starts with the character '3' instead of '1'

2) Naked multi-sig transactions. These are harder, because the output of
the transactions does not neatly map to a specific bitcoin address. I
think I have found a neat work-around: I compute:

hash160(M, N, sortedListOfAddresses)

which can now be properly mapped to a bitcoin address. To mark the fact
that this addres is neither a "pay to script" (type '3') nor a
"pay to pubkey or pubkeyhash" (type '1'), I prefix them with '4'

Note : this may be worthy of an actual BIP. If someone writes one,
I'll happily adjust the code.

Note : this trick is only a blockparser thing. This means that these
new address types starting with a '4' won't be recognized by other
bitcoin implementations (such as blockchain.info)

Examples
--------

Expand Down Expand Up @@ -188,6 +218,14 @@ blockparser

./parser pristine

. Show the first valid "pay to script hash (P2SH)" transaction in the chain:

./parser showtx 9c08a4d78931342b37fd5f72900fb9983087e6f46c4a097d8a1f52c74e28eaf6

. Show the first valid naked multi-sig transaction in the chain (it's a 1 Of 2 multi-sig)

./parser showtx 60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1

NOTE: the general syntax is:

./parser <command> <option> <option> ... <arg> <arg> ...
Expand Down
1 change: 1 addition & 0 deletions TODO.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

TODO:
Make ^C global, not per callback
Better progress in full parse (w/ ETA)
Fix completion estimates in allBalances

Expand Down
15 changes: 12 additions & 3 deletions cb/allBalances.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct Output {
typedef std::vector<Output> OutputVec;

struct Addr {
uint8_t type;
uint64_t sum;
uint64_t nbIn;
uint64_t nbOut;
Expand Down Expand Up @@ -229,8 +230,15 @@ struct AllBalances:public Callback {
{
uint8_t addrType[3];
uint160_t pubKeyHash;
int type = solveOutputScript(pubKeyHash.v, script, scriptSize, addrType);
if(unlikely(type<0)) return;
auto scriptType = solveOutputScript(
pubKeyHash.v,
script,
scriptSize,
addrType
);
if(unlikely(scriptType<0)) {
return;
}

if(0!=restrictMap.size()) {
auto r = restrictMap.find(pubKeyHash.v);
Expand All @@ -248,6 +256,7 @@ struct AllBalances:public Callback {
addr = allocAddr();

memcpy(addr->hash.v, pubKeyHash.v, kRIPEMD160ByteSize);
addr->type = addrType[0];
addr->outputVec = 0;
addr->nbOut = 0;
addr->nbIn = 0;
Expand Down Expand Up @@ -418,7 +427,7 @@ struct AllBalances:public Callback {
} else {
if(i<showAddr || 0!=nbRestricts) {
uint8_t buf[64];
hash160ToAddr(buf, addr->hash.v, true);
hash160ToAddr(buf, addr->hash.v, true, addr->type);
printf(" %s", buf);
} else {
printf(" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
Expand Down
37 changes: 16 additions & 21 deletions cb/dumpTX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
#include <string.h>
#include <callback.h>

typedef GoogMap<Hash256, int, Hash256Hasher, Hash256Equal >::Map TxMap;
typedef GoogMap<
Hash256,
int,
Hash256Hasher,
Hash256Equal
>::Map TxMap;

struct DumpTX:public Callback {

Expand Down Expand Up @@ -89,8 +94,7 @@ struct DumpTX:public Callback {
virtual void startBlock(
const Block *b,
uint64_t
)
{
) {
currBlock = b->height;

const uint8_t *p = b->chunk->getData();
Expand All @@ -104,8 +108,7 @@ struct DumpTX:public Callback {
virtual void startTX(
const uint8_t *p,
const uint8_t *hash
)
{
) {
#if defined(CLAM)
auto pBis = p;
LOAD(uint32_t, nVersion, pBis);
Expand Down Expand Up @@ -144,20 +147,17 @@ struct DumpTX:public Callback {

virtual void startInputs(
const uint8_t *p
)
{
) {
}

virtual void endInputs(
const uint8_t *p
)
{
) {
}

virtual void startInput(
const uint8_t *p
)
{
) {
if(dump) {
printf(
" input[%" PRIu64 "] = {\n\n",
Expand Down Expand Up @@ -192,8 +192,7 @@ struct DumpTX:public Callback {
uint64_t inputIndex,
const uint8_t *inputScript,
uint64_t inputScriptSize
)
{
) {
if(dump) {
uint8_t buf[1 + 2*kSHA256ByteSize];
toHex(buf, upTXHash);
Expand All @@ -214,17 +213,15 @@ struct DumpTX:public Callback {

virtual void endInput(
const uint8_t *p
)
{
) {
if(dump) {
printf(" }\n\n");
}
}

virtual void startOutputs(
const uint8_t *p
)
{
) {
}

virtual void endOutputs(
Expand All @@ -246,8 +243,7 @@ struct DumpTX:public Callback {

virtual void startOutput(
const uint8_t *p
)
{
) {
if(dump) {
printf(
"\n"
Expand All @@ -264,8 +260,7 @@ struct DumpTX:public Callback {
uint64_t outputIndex, // Index of this output in the current transaction
const uint8_t *outputScript, // Raw script (challenge to would-be spender) carried by this output
uint64_t outputScriptSize // Byte size of raw script
)
{
) {
if(dump) {
printf(" value = %.8f\n", satoshisToNormaForm(value));
printf(" challenge script, bytes=%" PRIu64 " :\n", outputScriptSize);
Expand Down
47 changes: 21 additions & 26 deletions cb/pristine.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

// Find pristine blocks
// Find pristine blocks and rewards

#include <util.h>
#include <string.h>
Expand All @@ -8,10 +8,15 @@
#include <option.h>
#include <callback.h>

typedef GoogMap<Hash256, uint64_t, Hash256Hasher, Hash256Equal >::Map TxMap;
typedef GoogMap<
Hash256,
uint64_t,
Hash256Hasher,
Hash256Equal
>::Map TxMap;

struct Pristine:public Callback {

struct Pristine:public Callback
{
optparse::OptionParser parser;

TxMap txMap;
Expand All @@ -22,8 +27,7 @@ struct Pristine:public Callback
uint64_t nbPristine;
const uint8_t *currTXHash;

Pristine()
{
Pristine() {
parser
.usage("")
.version("")
Expand All @@ -32,15 +36,14 @@ struct Pristine:public Callback
;
}

virtual const char *name() const { return "pristine"; }
virtual const char *name() const { return "pristine"; }
virtual const optparse::OptionParser *optionParser() const { return &parser; }
virtual bool needTXHash() const { return true; }
virtual bool needTXHash() const { return true; }

virtual int init(
int argc,
const char *argv[]
)
{
) {
info("Finding all pristine blocks in blockchain");
static uint8_t empty[kSHA256ByteSize] = { 0x42 };
static uint64_t sz = 15 * 1000 * 1000;
Expand All @@ -53,38 +56,33 @@ struct Pristine:public Callback
virtual void startBlock(
const Block *b,
uint64_t
)
{
) {
const uint8_t *p = b->chunk->getData();
SKIP(uint32_t, version, p);
SKIP(uint256_t, prevBlkHash, p);
SKIP(uint256_t, blkMerkleRoot, p);
LOAD(uint32_t, blkTime, p);

currBlock = b->height;
currTime = blkTime;
}

virtual void startTX(
const uint8_t *p,
const uint8_t *hash
)
{
) {
currTXHash = hash;
}

virtual void startInputs(
const uint8_t *p
)
{
) {
hasGenInput = false;
nbInputs = 0;
}

virtual void startInput(
const uint8_t *p
)
{
) {
static uint256_t gNullHash;
bool isGenInput = (0==memcmp(gNullHash.v, p, sizeof(gNullHash)));
if(isGenInput) {
Expand All @@ -95,8 +93,7 @@ struct Pristine:public Callback

virtual void endInputs(
const uint8_t *p
)
{
) {
if(hasGenInput) {

if(1!=nbInputs) {
Expand All @@ -120,19 +117,17 @@ struct Pristine:public Callback
uint64_t inputIndex,
const uint8_t *inputScript,
uint64_t inputScriptSize
)
{
) {
auto i = txMap.find(upTXHash);
if(txMap.end()!=i) {
if(0<i->second) --nbPristine;
i->second = 0;
}
}

virtual void wrapup()
{
auto i = txMap.begin();
virtual void wrapup() {
auto e = txMap.end();
auto i = txMap.begin();
info("Found %" PRIu64 " pristine blocks", nbPristine);
printf("Block # Time TX hash\n");
printf("===========================\n");
Expand Down
Loading

0 comments on commit 379a4da

Please sign in to comment.