通过P2PKH 反推比特币地址

这要从比特币地址的结构说起:

比特币地址结构: 【版本 + 公钥哈希 + 验证码】

版本:默认0x00, 即可空白的一字节。
公钥:由非对称加密算法得出。
公钥哈希:就是给公钥做哈希算法得出的结果。
验证码:给 [版本 + 公钥哈希],sha256两次,取头4个字符作为验证码。

常见非对称加密:rsa,ecdsa
常见hash算法:MD5、sha1、sha256

比特币由ecdsa算出私钥、公钥,再通过公钥算出比特币地址。
上面的公钥哈希做了 两次哈希:首先是sha256,再在此结果再做ripemd160。才变成上面所称的公钥哈希。

以上基本的说完了

那么 通过P2PKH(pay to public key hash) 反推比特币地址,要怎样操作呢?

public key hash 就是上面的 公钥哈希
反推地址 不就是 在 公钥哈希前面加上版本号,后面加上验证码就可以了吗?

我们可以先看看比特币转账的账单。

https://www.blockchain.com/zh-cn/btc/tx/b6f6b339b546a13822192b06ccbdd817afea5311845f769702ae2912f7d94ab5?show_adv=true

通过P2PKH 反推比特币地址_第1张图片

收款方地址对应下图的红框中的PublicKeyHash。
通过P2PKH 反推比特币地址_第2张图片

即:
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个字节。

比特币地址多数给用户使用,所以在校验方面就比较重要。

你可能感兴趣的:(golang)