比特币的地址类型

简介: 比特币的地址类型这部分内容主要来自于btcutil/address.go一直困惑比特币是如何验证交易的,看了这个地质类型算是有点豁然开朗,实际上比特币的交易验证规则还是有点复杂的,它并不像以太坊那么简单明确.

比特币的地址类型

这部分内容主要来自于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
}
目录
相关文章
|
NoSQL IDE 网络协议
Redis高级客户端Lettuce详解(下)
Lettuce是一个Redis的Java驱动包,初识她的时候是使用RedisTemplate的时候遇到点问题Debug到底层的一些源码,发现spring-data-redis的驱动包在某个版本之后替换为Lettuce。既然能被Spring生态所认可,Lettuce想必有过人之处,于是笔者花时间阅读她的官方文档,整理测试示例,写下这篇文章。
5506 0
|
11月前
|
搜索推荐 关系型数据库 MySQL
MySQL中的模糊匹配技巧:无需ES的高效实现
在数据库应用中,模糊匹配是一个常见的需求,尤其在处理搜索功能时。虽然Elasticsearch(ES)等搜索引擎在处理文本搜索方面表现出色,但在一些场景下,直接使用MySQL数据库实现模糊匹配也是一个经济且高效的选择。本文将分享如何在不引入ES的情况下,利用MySQL实现模糊匹配的五大步骤和十个实战案例。
748 1
学生0元购|低配也能畅玩!《黑神话:悟空》云电脑攻略
《黑神话:悟空》正式上市,这款备受期待的游戏对电脑配置要求不低,但通过云电脑,你无需担心硬件限制,随时随地畅玩大作。最低仅需1.2元/小时,还能利用学生福利免费畅玩。快速上手教程与省钱攻略,助你轻松征服《黑神话:悟空》!
696 8
学生0元购|低配也能畅玩!《黑神话:悟空》云电脑攻略
|
数据采集 数据挖掘 数据处理
使用Python和Pandas处理CSV数据
使用Python和Pandas处理CSV数据
280 5
|
弹性计算 运维 Java
揭秘!如何用SAE在几分钟内部署应用,让你的开发速度飞跃式提升?
【8月更文挑战第21天】在现代软件开发中,快速部署与高效运维至关重要。SAE(Serverless App Engine)作为一款全场景Serverless云应用引擎,极大简化了云应用的部署与管理。开发者仅需专注业务逻辑,SAE则负责底层资源。通过自动扩缩容、弹性计算等功能,SAE降低了资源管理的复杂度,加速了从代码到部署的进程。创建应用后,只需上传如Spring Boot应用的Jar包,SAE便会自动完成部署与健康检查,确保应用稳定运行。无论是初创企业还是大型组织,SAE均能提供高效便捷的部署方案。
161 0
|
机器学习/深度学习 算法 TensorFlow
Inception v3算法的实战与解析
Inception v3算法的实战与解析
485 0
|
IDE 开发工具 Python
selenium.common.exceptions.NoSuchDriverException: Message: Unable to obtain driver for MicrosoftEdge
selenium.common.exceptions.NoSuchDriverException: Message: Unable to obtain driver for MicrosoftEdge
1161 3
langchain中的chat models介绍和使用
之前我们介绍了LLM模式,这种模式是就是文本输入,然后文本输出。 chat models是基于LLM模式的更加高级的模式。他的输入和输出是格式化的chat messages。 一起来看看如何在langchain中使用caht models吧。
|
JavaScript 前端开发
01EasyUI - EasyUI简介
01EasyUI - EasyUI简介
230 0
|
安全 关系型数据库 MySQL
MySQL安全与权限管理:保障数据安全与访问控制
本文深入探讨了MySQL数据库的安全与权限管理,通过详细的代码示例,介绍了用户与权限的概念,权限管理与访问控制的方法,以及数据库安全性策略的制定与实施。MySQL提供了强大的安全性功能,能够帮助管理员保护数据库的数据安全和限制用户的访问权限。了解如何创建用户、授予权限,以及如何制定数据库安全性策略,将使管理员能够有效地管理和保护数据库,降低潜在的安全风险。
2651 0