ビットコインアドレス生成アルゴリズムのP 2 SH


機能コード:
 
import (
	"encoding/hex"
	"errors"
	"github.com/btcsuite/btcutil/base58"
	"github.com/decred/dcrd/dcrec/secp256k1"
)

//P2WPKH-P2SH
func NewP2SH(rawPrivKey []byte, netType string, isCompress bool) (string, error) {
	//    
	var mapNet = map[string]byte{"main":0x05, "testnet":0x6f}
	if _, ok := mapNet[netType]; !ok {
		return "", errors.New("invalid net type")
	}

	var (
		privKey *secp256k1.PrivateKey
		err error
		hash160 []byte
		pubKey []byte
	)

	privKey = secp256k1.PrivKeyFromBytes(rawPrivKey)
	
	//    
	if isCompress {
		pubKey, _ = hex.DecodeString(NewCompressPubKey(privKey.PubKey().X().Bytes(), privKey.PubKey().Y().Bytes()))
	} else {
		pubKey,_ = hex.DecodeString(NewUncompressPubKey(privKey.PubKey().X().Bytes(), privKey.PubKey().Y().Bytes()))
	}
	// BASE58CHECK( 0x05 HASH160( 0x00 0x14 HASH160( pubKey ) ) )
	//    HASH160(x) = RIPEMD160(Sha256(x)),base58check(x) = x Sha256(Sha256(x)).substring(0,4)
	if hash160, err = Ripemd160AfterSha256(pubKey); err != nil {
		return "", err
	}

	if hash160, err = Ripemd160AfterSha256(append([]byte{0x00,0x14}, hash160...)); err != nil {
		return "", err
	}

	buf := append([]byte{mapNet[netType]}, hash160...)
	checksum := Sha256AfterSha256(buf)
	buf = append(buf, checksum[:4]...)
	return base58.Encode(buf),nil
}

テストコード:
func TestNewP2SH(t *testing.T) {
	var testcases = []struct{
		originalPrivKey string
		netType string
		address string
	} {
		{"cff0fbaaae8f6ee6ebb35f98afa4036958d929ee18143b26c466251cd966b128",
			"main",
			"3QehmGVcZsJEVc1uPSvXwamRQn56JR7qKd",
		},
	}
	var err error
	var address string

	for _, oneCase := range testcases {
		privKey,_ := hex.DecodeString(oneCase.originalPrivKey)
		if address,err = NewP2SH(privKey, oneCase.netType,true);err != nil {
			t.Error(err)
			return
		}
		if address != oneCase.address {
			t.Error("genereate compressed address error")
			t.Error("want: ", oneCase.address)
			t.Error("got:  ", address)
			return
		}
	}
}

ここでのテストケースは,Electrum財布で生成したアドレステストを用いることができる.ただし、Electrum財布から導出された秘密鍵はWIF形式であり、それを復号してバイト配列に変換する形式で試験例に記入する必要がある.
 
(全文完了)
参考資料:
https://learnmeabitcoin.com/guide/p2sh https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki https://en.bitcoin.it/wiki/List_of_address_prefixes