ビットコインアドレス生成アルゴリズムのP 2 SH
2502 ワード
機能コード:
テストコード:
ここでのテストケースは,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
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