比特幣地址(Bitcoin Address)是用於接收和傳送比特幣的唯一識別符號,類似於傳統金融系統中的銀行賬號。一個比特幣地址由一串字母和數字組成,通常以1、3或bc1開頭,具體長度為26至35個字元。以下是比特幣地址的主要型別及其特點:
- P2PKH地址(Pay-to-PubKey-Hash):
- 以“1”開頭。
- 例子:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
- 最為傳統和常見的比特幣地址型別。
- P2SH地址(Pay-to-Script-Hash):
- 以“3”開頭。
- 例子:3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy
- 用於實現更復雜的支付條件,例如多重簽名地址。
- Bech32地址(也稱為SegWit地址):
- 以“bc1”開頭。
- 例子:bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf3q0s
- 這是比特幣協議升級SegWit(隔離見證)後的新地址格式,提供更高的效率和安全性。
地址生成過程
比特幣地址是透過以下步驟生成的:
- 私鑰生成:透過隨機生成一個256位的數字,即私鑰。私鑰是保密的,任何人掌握私鑰就能控制相關地址中的比特幣。
- 公鑰生成:使用橢圓曲線加密演算法(通常是SECP256K1),從私鑰生成公鑰。
- 公鑰雜湊:對公鑰進行兩次雜湊:第一次使用SHA-256,第二次使用RIPEMD-160,生成公鑰雜湊(Public Key Hash)。
- 新增版本位元組和校驗和:
- 在公鑰雜湊前新增一個版本位元組(例如,P2PKH地址的版本位元組為0x00)。
- 對上述資料進行兩次SHA-256雜湊,從中取前4位元組作為校驗和,並新增到資料末尾。
- Base58編碼:最後,對結果進行Base58編碼,生成最終的比特幣地址。
使用與安全
- 接收比特幣:使用者可以將自己的比特幣地址提供給他人,以接收比特幣。
- 傳送比特幣:使用者需要用相應的私鑰對交易進行簽名,證明其對地址內比特幣的所有權,然後廣播交易到比特幣網路。
安全建議
- 保管私鑰:私鑰應安全儲存,不能洩露給他人。建議使用硬體錢包或離線冷錢包來儲存私鑰。
- 備份:定期備份私鑰或助記詞,以防丟失。
- 謹慎使用:儘量避免在不安全的網路或裝置上操作比特幣交易。
btcd示例
使用btcutil
來建立比特幣地址涉及幾個步驟,包括生成金鑰對(私鑰和公鑰),然後使用公鑰生成地址。
func NewBTCAddress(){
// 生成私鑰
privKey, err := btcec.NewPrivateKey()
if err != nil {
panic(err)
}
// 匯出公鑰
pubKey := privKey.PubKey()
// 生成BTC地址(P2PKH)
addressPKH, err := btcutil.NewAddressPubKey(pubKey.SerializeUncompressed(), &chaincfg.MainNetParams)
if err != nil{
panic(err)
}
fmt.Printf("Private Key: %x\n",privKey.Serialize())
fmt.Printf("Public Key: %x\n",pubKey.SerializeUncompressed())
fmt.Printf("BTC Address: %s\n",addressPKH.EncodeAddress())
// 生成公鑰hash
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
// 建立一個簡單的多重簽名指令碼
script, err := txscript.NewScriptBuilder().AddOp(txscript.OP_DUP).
AddOp(txscript.OP_HASH160).AddData(pubKeyHash).
AddOp(txscript.OP_EQUALVERIFY).AddOp(txscript.OP_CHECKSIG).Script()
if err != nil {
panic(err)
}
// 生成P2SH地址
addressP2SH, err := btcutil.NewAddressScriptHashFromHash(pubKeyHash, &chaincfg.MainNetParams)
if err != nil{
panic(err)
}
fmt.Printf("P2SH Address: %s\n",addressP2SH.EncodeAddress())
// 生成Bech32地址(P2WPKH)
addressBech32,err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash, &chaincfg.MainNetParams)
if err != nil{
panic(err)
}
fmt.Printf("Bech32 Address: %s\n",addressBech32.EncodeAddress())
}
宣告:本作品採用署名-非商業性使用-相同方式共享 4.0 國際 (CC BY-NC-SA 4.0)進行許可,使用時請註明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無意
騰訊雲開發者社群:孟斯特