比特币的地址类型

简介: 比特币的地址类型这部分内容主要来自于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
}
目录
相关文章
|
Rust JavaScript 前端开发
【Rust 实战】Rust 与 Wasm
【Rust 实战】Rust 与 Wasm
3096 0
【Rust 实战】Rust 与 Wasm
|
存储 安全 算法
使用jotp实现双因子验证
扫盲使用totp增强身份安全性指南,原理看懂也不用自己造轮子呀,最讨厌哪些啥也不懂的搬运工,我这里给大家解惑吧
1755 0
|
存储 SQL 分布式计算
【存储】2022 年的 4 个开源对象存储平台
【存储】2022 年的 4 个开源对象存储平台
|
存储 Linux 数据安全/隐私保护
如何在本地Docker中部署MinIO服务并实现远程访问管理界面
如何在本地Docker中部署MinIO服务并实现远程访问管理界面
2102 0
|
6月前
|
存储 人工智能 关系型数据库
OpenClaw怎么可能没痛点?用RDS插件来释放OpenClaw全部潜力
OpenClaw插件是深度介入Agent生命周期的扩展机制,提供24个钩子,支持自动注入知识、持久化记忆等被动式干预。相比Skill/Tool,插件可主动在关键节点(如对话开始/结束)执行逻辑,适用于RAG增强、云化记忆等高级场景。
1372 56
OpenClaw怎么可能没痛点?用RDS插件来释放OpenClaw全部潜力
|
7月前
|
人工智能 监控 API
2026年零基础部署OpenClaw(Clawdbot),安装OpenClaw Skills,打造专属全能AI助理!
“OpenClaw好像没想象中厉害?”这是很多用户初体验后的共同困惑。就像拿到一台只装了基础系统的电脑,没有办公软件、没有娱乐应用,自然难以感受其价值。OpenClaw的真正潜力,从来不在其本身的基础功能,而在于由Skills构建的庞大生态——如同操作系统的应用商店,Skills为这个AI助手注入了无限可能。
1226 1
|
开发工具 git
【git】解决Gitea推送创建失败
【git】解决Gitea推送创建失败
1173 0
|
域名解析 弹性计算 网络协议
阿里云ipv6设置,免费将ipv4网站升级为ipv6
阿里云ipv6设置,免费将ipv4网站升级为ipv6,网站ipv6设置
3249 0
|
存储 算法 Java
Java实现AWS S3 V4 Authorization自定义验证
最近在开发文件存储服务,需要符合s3的协议标准,可以直接接入aws-sdk,本文针对sdk发出请求的鉴权信息进行重新组合再签名验证有效性,sdk版本如下
578 0
|
开发框架 Dart 前端开发
Android 跨平台方案对比之Flutter 和 React Native
本文对比了 Flutter 和 React Native 这两个跨平台移动应用开发框架。Flutter 使用 Dart 语言,提供接近原生的性能和丰富的组件库;React Native 则基于 JavaScript,具备庞大的社区支持和灵活性。两者各有优势,选择时需考虑团队技能和项目需求。
1571 9