zoukankan      html  css  js  c++  java
  • 比特币的地址类型

    比特币的地址类型

    这部分内容主要来自于btcutil/address.go

    一直困惑比特币是如何验证交易的,看了这个地质类型算是有点豁然开朗,实际上比特币的交易验证规则还是有点复杂的,它并不像以太坊那么简单明确.

    个人理解,比特币对于交易的处理,首先是根据 pubkey script 判断是什么地址类型,然后进行不同的验证方法. 比如如果地质类型是AddressWitnessPubKeyHash,那么验证规则就明显和 P2PKH 不一样.

    以下是address.go 中如何解析出地址:

    // DecodeAddress decodes the string encoding of an address and returns
    // the Address if addr is a valid encoding for a known address type.
    //
    // The bitcoin network the address is associated with is extracted if possible.
    // When the address does not encode the network, such as in the case of a raw
    // public key, the address will be associated with the passed defaultNet.
    func DecodeAddress(addr string, defaultNet *chaincfg.Params) (Address, error) {
    	// Bech32 encoded segwit addresses start with a human-readable part
    	// (hrp) followed by '1'. For Bitcoin mainnet the hrp is "bc", and for
    	// testnet it is "tb". If the address string has a prefix that matches
    	// one of the prefixes for the known networks, we try to decode it as
    	// a segwit address.
    	oneIndex := strings.LastIndexByte(addr, '1')
    	if oneIndex > 1 {
    		// The HRP is everything before the found '1'.
    		hrp := strings.ToLower(addr[:oneIndex])
    		if hrp == defaultNet.Bech32HRPSegwit {
    			witnessVer, witnessProg, err := decodeSegWitAddress(addr)
    			if err != nil {
    				return nil, err
    			}
    
    			// We currently only support P2WPKH and P2WSH, which is
    			// witness version 0.
    			if witnessVer != 0 {
    				return nil, UnsupportedWitnessVerError(witnessVer)
    			}
    
    			switch len(witnessProg) {
    			case 20:
    				return newAddressWitnessPubKeyHash(hrp, witnessProg)
    			case 32:
    				return newAddressWitnessScriptHash(hrp, witnessProg)
    			default:
    				return nil, UnsupportedWitnessProgLenError(len(witnessProg))
    			}
    		}
    	}
    
    	// Serialized public keys are either 65 bytes (130 hex chars) if
    	// uncompressed/hybrid or 33 bytes (66 hex chars) if compressed.
    	if len(addr) == 130 || len(addr) == 66 {
    		serializedPubKey, err := hex.DecodeString(addr)
    		if err != nil {
    			return nil, err
    		}
    		return NewAddressPubKey(serializedPubKey, defaultNet)
    	}
    
    	// Switch on decoded length to determine the type.
    	decoded, netID, err := base58.CheckDecode(addr)
    	if err != nil {
    		if err == base58.ErrChecksum {
    			return nil, ErrChecksumMismatch
    		}
    		return nil, errors.New("decoded address is of unknown format")
    	}
    	switch len(decoded) {
    	case ripemd160.Size: // P2PKH or P2SH
    		isP2PKH := netID == defaultNet.PubKeyHashAddrID
    		isP2SH := netID == defaultNet.ScriptHashAddrID
    		switch hash160 := decoded; {
    		case isP2PKH && isP2SH:
    			return nil, ErrAddressCollision
    		case isP2PKH:
    			return newAddressPubKeyHash(hash160, netID)
    		case isP2SH:
    			return newAddressScriptHashFromHash(hash160, netID)
    		default:
    			return nil, ErrUnknownAddressType
    		}
    
    	default:
    		return nil, errors.New("decoded address is of unknown size")
    	}
    }
    

    总共有四中地质类型:

    AddressPubKey

    // AddressPubKey is an Address for a pay-to-pubkey transaction.
    type AddressPubKey struct {
    	pubKeyFormat PubKeyFormat
    	pubKey       *btcec.PublicKey
    	pubKeyHashID byte
    }
    

    AddressPubKeyHash

    // AddressPubKeyHash is an Address for a pay-to-pubkey-hash (P2PKH)
    // transaction.
    type AddressPubKeyHash struct {
    	hash  [ripemd160.Size]byte
    	netID byte
    }
    

    AddressScriptHash

    // AddressScriptHash is an Address for a pay-to-script-hash (P2SH)
    // transaction.
    type AddressScriptHash struct {
    	hash  [ripemd160.Size]byte
    	netID byte
    }
    

    AddressScriptHash

    // AddressScriptHash is an Address for a pay-to-script-hash (P2SH)
    // transaction.
    type AddressScriptHash struct {
    	hash  [ripemd160.Size]byte
    	netID byte
    }
    

    AddressWitnessPubKeyHash

    // AddressWitnessPubKeyHash is an Address for a pay-to-witness-pubkey-hash
    // (P2WPKH) output. See BIP 173 for further details regarding native segregated
    // witness address encoding:
    // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
    type AddressWitnessPubKeyHash struct {
    	hrp            string
    	witnessVersion byte
    	witnessProgram [20]byte
    }
    

    AddressWitnessScriptHash

    // AddressWitnessScriptHash is an Address for a pay-to-witness-script-hash
    // (P2WSH) output. See BIP 173 for further details regarding native segregated
    // witness address encoding:
    // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
    type AddressWitnessScriptHash struct {
    	hrp            string
    	witnessVersion byte
    	witnessProgram [32]byte
    }
    
    
  • 相关阅读:
    复位电路
    Tcl与Design Compiler (十三)——Design Compliler中常用到的命令(示例)总结
    Python Twisted系列教程1:Twisted理论基础
    Python Twisted架构英文版
    Python Twisted网络编程框架与异步编程入门教程
    windows下安装Python虚拟环境virtualenvwrapper-win
    数据库事务解析
    Python之select模块解析
    windows右键打开方式里面添加新的应用程序
    HTTP协议的状态码
  • 原文地址:https://www.cnblogs.com/baizx/p/9491455.html
Copyright © 2011-2022 走看看