How to calculate multisig address? Given the transaction below, how can I -


Identify this tx involves multisig
What tool/s can I then use to calculate the resulting multisig address


The second HEX address 9d07acef34e0ad5a54f92aae65f49e2f3a24dd39 is easy enough - Base58Check converts it to 1FKJHRVHmyvjDfVbPuBW9e1tdCgt2XWtCb. I can follow the technical background for standard addresses at https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses

To calculate the multisig address I can use bitcoind to decode the raw tx: 

./bitcoind decoderawtransaction 010000000147759651f76ec0dbc7c248337d791afa7363636da4af0006fbafb77b9ac8214f070000008b483045022100b980b3bf9b20d1dc98a6cc8c76e19c67c9c24a23fc44a3f6baf1020fb7b6b9ce022029bd5fda88553f1dac92b12c404f65cd2ed97b481244d45558129698e43595ce0141040ab4a6619b82e1555f6c3ac9bd9b62c17433f3fb502d054dce9474ae6639777454b2509aae137c9048adb8491d28710c785b86aee766110d6aa0bcd3b07860a9ffffffff02a08601000000000017a914f815b036d9bbbce5e9f2a00abd1bf3dc91e9551087d0e89600000000001976a9149d07acef34e0ad5a54f92aae65f49e2f3a24dd3988ac00000000

"vout" : [

    {
        "value" : 0.00100000,
        "n" : 0,
        "scriptPubKey" : {
            "asm" : "OP_HASH160 f815b036d9bbbce5e9f2a00abd1bf3dc91e95510 OP_EQUAL",
            "hex" : "a914f815b036d9bbbce5e9f2a00abd1bf3dc91e9551087",
            "reqSigs" : 1,
            "type" : "scripthash",
            "addresses" : [
                "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC"
            ]


But this took over 6 seconds to complete.

Is there an easier/quicker to simply calculate a multisig address?

The raw tx:

{

  "value":"0.00100000",

  "scriptPubKey":"OP_HASH160 f815b036d9bbbce5e9f2a00abd1bf3dc91e95510 OP_EQUAL"

},

{

  "value":"0.09890000",

  "scriptPubKey":"OP_DUP OP_HASH160 9d07acef34e0ad5a54f92aae65f49e2f3a24dd39
[ANSWER PART #1/2]


  To calculate the multisig address I can use bitcoind to decode the raw
  tx [...] But this took over 6 seconds to complete.


May be the daemon was too busy processing other things?

The transaction has very simple and easy-to-parse format. You can parse it without bitcoind. It is possible to do it even manually. Look here! Lets take your raw data

01000000 // version id
01       // inputs count
47759651f76ec0dbc7c248337d791afa7363636da4af0006fbafb77b9ac8214f // prev tx hash
07000000  // prev tx output index
8b        // scripSig len
48        // push signature + type
3045022100b980b3bf9b20d1dc98a6cc8c76e19c67c9c24a23fc44a3f6baf1020fb7b6b9ce022029bd5fda88553f1dac92b12c404f65cd2ed97b481244d45558129698e43595ce01
41        // push pubkey
040ab4a6619b82e1555f6c3ac9bd9b62c17433f3fb502d054dce9474ae6639777454b2509aae137c9048adb8491d28710c785b86aee766110d6aa0bcd3b07860a9
ffffffff  // sequence
02        // outputs count
a086010000000000 // value1
17        // scriptPubkey len
a914f815b036d9bbbce5e9f2a00abd1bf3dc91e9551087 // scriptPubkey
d0e8960000000000 // value2 
19        // scriptpubkey len
76a9149d07acef34e0ad5a54f92aae65f49e2f3a24dd3988ac // scriptPubkey
00000000 // lock


OK, I've spent more than 6 seconds, but I parsed it with hands :)

take first output script a9 14 f815b036d9bbbce5e9f2a00abd1bf3dc91e95510 87

it is p2sh script - OP_HASH160 f815b036d9bbbce5e9f2a00abd1bf3dc91e95510 OP_EQUAL

convert these 20 bytes to p2sh address and you will get 3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC



[ANSWER PART #2/2]


  A standard address is
  Base58Check(f815b036d9bbbce5e9f2a00abd1bf3dc91e95510)


#define NET_BYTE  0x00
#define P2SH_BYTE 0x05  // https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki
//--------------------------------------------------------------
const QString MyKey20::toStringP2SH ( ) const
{
  quint8 tmp1 [21];                           // buffer
  tmp1 [0] = P2SH_BYTE;                       // first byte = 0x05 for p2sh addr
  memcpy ( tmp1 + 1, constData ( ), 20 );     // next 20 bytes
  const MyKey32 key ( tmp1, 21 );             // sha256 ( sha256 ( buffer ) )
  quint8 tmp2 [25];                           // another buffer
  memcpy ( tmp2, tmp1, sizeof ( tmp1 ) );     // copy 21 bytes
  memcpy ( tmp2 + 21, key.constData ( ), 4 ); // and concat with checksum
  char addr [40];                             // buffer for human-readable string
  memset ( addr, 0, sizeof ( addr ) );        // clear it and base58 encode data
  BASE58::encodeBase58 ( tmp2, sizeof ( tmp2 ), addr, sizeof ( addr ) - 1 );
  return QString ( addr );
}


and a method for creating "classic" addresses (to compare the diffs)

const QString MyKey20::toString ( ) const
{
  quint8 tmp1 [21];
  tmp1 [0] = NET_BYTE;
  memcpy ( tmp1 + 1, constData ( ), 20 );
  const MyKey32 key ( tmp1, 21 );
  quint8 tmp2 [25];
  memcpy ( tmp2, tmp1, sizeof ( tmp1 ) );
  memcpy ( tmp2 + 21, key.constData ( ), 4 );
  char addr [40];
  memset ( addr, 0, sizeof ( addr ) );
  BASE58::encodeBase58 ( tmp2, sizeof ( tmp2 ), addr, sizeof ( addr ) - 1 );
  return QString ( addr );
}