Bitcoin Forum
November 15, 2024, 03:52:07 PM *
News: Check out the artwork 1Dq created to commemorate this forum's 15th anniversary
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Construction of multisig address  (Read 1406 times)
waxwing (OP)
Sr. Member
****
Offline Offline

Activity: 469
Merit: 253


View Profile
October 24, 2013, 09:38:56 PM
 #1

Can anybody show me where in the bitcoin source the construction of multisig addresses occurs? I found the createmultisig method in script.cpp which creates a CScript object, but I can't see exactly where that gets converted to a base58 address. I'm trying to make sure I understand exactly how it's done. I know it's written here, but I'm not getting the correct result here, so I need somehow to audit each step. Thanks for any pointers.

PGP fingerprint 2B6FC204D9BF332D062B 461A141001A1AF77F20B (use email to contact)
kjj
Legendary
*
Offline Offline

Activity: 1302
Merit: 1026



View Profile
October 25, 2013, 02:56:18 PM
 #2

I'm not sure about the main client, but here is some ghetto PHP code that works.  I've used it to create a bunch of multisig p2sh addresses.

Code: (multisig.php)
function createmultisig($nReq,$keys,$sortkeys=TRUE){
 $debug=FALSE;

 // I always sort keys so that I end up with a canonical p2sh address for any given set of keys and parameters
 // if you are testing this against another implementation, disable the sorting, or put them in sorted order before calling the other code
 if($sortkeys)sort($keys,SORT_STRING);

 // P2SH multisig in bitcoin requires between 2 and 16 (inclusive) keys
 // this appears mostly to be because of the single-byte PUSH_x opcodes, 0x52 to 0x60
 if($nReq<2 OR $nReq>16 OR $nReq>count($keys))return FALSE;

 // the structure of P2SH multisig is very simple.  This short block assembles the redeemscript
 $rs=chr(0x50+$nReq);
 while(list($key,$val)=each($keys)){
  $bpk=hex2bin($val);
  $rs.=chr(strlen($bpk)).$bpk;
 }
 $rs.=chr(0x50+count($keys));
 $rs.=chr(0xae);

 // this block then turns the redeem script into an address.
 // the debug lines allow easy verification of each step to compare with published examples

 if($debug)echo "In: ".$rs."\n";
 $h=hash("sha256",$rs,TRUE);
 if($debug)echo "H: ".bin2hex($h)."\n";
 $h2=hash("ripemd160",$h,TRUE);
 if($debug)echo "H2: ".bin2hex($h2)."\n";
 $h3="\x05".$h2;
 if($debug)echo "H3: ".bin2hex($h3)."\n";
 $h4=hash("sha256",$h3,TRUE);
 if($debug)echo "H4: ".bin2hex($h4)."\n";
 $h5=hash("sha256",$h4,TRUE);
 if($debug)echo "H5: ".bin2hex($h5)."\n";
 $chk=substr($h5,0,4);
 if($debug)echo "Chk: ".bin2hex($chk)."\n";
 $addr_bin=$h3.$chk;
 if($debug)echo "addr: ".bin2hex($addr_bin)."\n";
 $addr=encodeBase58($addr_bin);
 if($debug)echo $addr."\n";

 return array("redeemScript"=>bin2hex($rs),"address"=>$addr);
}

17Np17BSrpnHCZ2pgtiMNnhjnsWJ2TMqq8
I routinely ignore posters with paid advertising in their sigs.  You should too.
waxwing (OP)
Sr. Member
****
Offline Offline

Activity: 469
Merit: 253


View Profile
October 25, 2013, 05:39:58 PM
 #3

Thanks for the suggestion. The problem I was having turned out to be down to blockchain.info not accepting raw multisig txs. I've found another way (using electrum) for now.

PGP fingerprint 2B6FC204D9BF332D062B 461A141001A1AF77F20B (use email to contact)
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!