通過P2PKH 反推比特幣地址
阿新 • • 發佈:2018-11-23
這要從比特幣地址的結構說起:
比特幣地址結構: 【版本 + 公鑰雜湊 + 驗證碼】
版本:預設0x00, 即可空白的一位元組。
公鑰:由非對稱加密演算法得出。
公鑰雜湊:就是給公鑰做雜湊演算法得出的結果。
驗證碼:給 [版本 + 公鑰雜湊],sha256兩次,取頭4個字元作為驗證碼。
常見非對稱加密:rsa,ecdsa
常見hash演算法:MD5、sha1、sha256
比特幣由ecdsa算出私鑰、公鑰,再通過公鑰算出比特幣地址。
上面的公鑰雜湊做了 兩次雜湊:首先是sha256,再在此結果再做ripemd160。才變成上面所稱的公鑰雜湊。
以上基本的說完了
那麼 通過P2PKH(pay to public key hash) 反推比特幣地址,要怎樣操作呢?
public key hash 就是上面的 公鑰雜湊
反推地址 不就是 在 公鑰雜湊前面加上版本號,後面加上驗證碼就可以了嗎?
我們可以先看看比特幣轉賬的賬單。
收款方地址對應下圖的紅框中的PublicKeyHash。
即:
DUP HASH160 PUSHDATA(20)[5410d53b33362bc4f5bf5255767e5ce607415457] EQUALVERIFY CHECKSIG
中的 5410d53b33362bc4f5bf5255767e5ce607415457
將下列go語言程式碼編譯,並且執行。可以由5410d53b33362bc4f5bf5255767e5ce607415457推回比特幣地址。
package main import ( "crypto/sha256" "encoding/hex" "fmt" "log" "github.com/btcsuite/btcutil/base58" ) const version = byte(0x00) func P2PKHToAddress(pkscript string) (string, error) { hash, err := hex.DecodeString(pkscript) if err != nil { log.Fatal(err) } pf := append([]byte{version}, hash...) b := append(pf, checkSum(pf)...) address := base58.Encode(b) return address, nil } func checkSum(publicKeyHash []byte) []byte { first := sha256.Sum256(publicKeyHash) second := sha256.Sum256(first[:]) return second[0:4] } func main() { address, err := P2PKHToAddress("5410d53b33362bc4f5bf5255767e5ce607415457") if err != nil { panic(err) } fmt.Println("BITCOIN ADDRESS: ", address) }
go get -u github.com/btcsuite/btcutil
go build
跑起
呃…剛開始我在想為什麼收款地址不能直接寫成比特幣地址,非要寫個公鑰雜湊上去。
現在想想中本聰應該是為了省空間吧,直接寫公鑰雜湊比特幣地址省5個位元組。
比特幣地址多數給使用者使用,所以在校驗方面就比較重要。