比特币地址生成算法之P2SH

功能代码:

 

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

你可能感兴趣的:(比特币技术研究)