bitcoin-go:基于 Bitcoin SV 生态的纯 Go 语言库项目

可用于在 Go 项目中构建、签名、验证 Bitcoin SV 交易,处理密钥、地址、脚本和区块等。项目从 JavaScript 版 BSV 库移植,提供与官方 bitcoind 测试向量和 JS 库交叉验证的完整测试套件,涵盖加密、编码、HD 钱包、脚本解释器等核心功能。【此简介由AI生成】

分支1Tags0
当前项目代码仓暂无内容

bitcoin-go

A pure and powerful Go implementation of the Bitcoin SV (BSV) library, ported from the JavaScript library @scrypt-inc/bsv.

The port aims for behavioral equivalence with the JS library: every module was translated faithfully from the original source, and the test suite is driven by the same official bitcoind test vectors plus cross-implementation round-trips against the JS library.

Getting started

# clone and build
git clone git@gitcode.com:Youyi-Labs/bitcoin-go.git
cd bitcoin-go
go build ./...

# run the full test suite (2650+ tests)
go test ./...

# run the example program
go run ./examples

Add it to your module:

go get gitcode.com/Youyi-Labs/bitcoin-go
import bsv "gitcode.com/Youyi-Labs/bitcoin-go"

License

MIT. This is a Go port of the JavaScript library @scrypt-inc/bsv; the original copyright notices are preserved in the LICENSE file.

Features

Area Modules
Crypto secp256k1 ECDSA (RFC 6979 deterministic k, low-S, pubkey recovery), SHA-1/SHA-256/SHA-512, double-SHA256, RIPEMD-160, HASH160, HMAC, AES-CBC
Encoding Base58, Base58Check, CompactSize varints, buffer reader/writer
Keys PrivateKey (WIF), PublicKey (SEC1 DER), Address (P2PKH/P2SH), HD keys (BIP32)
Script Full BSV script interpreter with P2SH, CLTV/CSV, and the Magnetic/Monolith opcodes (OP_CAT, OP_SPLIT, OP_MUL, …)
Transactions Build, serialize, sign (SIGHASH_ALL/NONE/SINGLE + FORKID), BIP69 sorting, sighash with HashCache
Block Block, BlockHeader, MerkleBlock (BIP37)
Extra Bitcoin signed Message (BIP137), Mnemonic (BIP39, 6 wordlists), ECIES (Bitcore + Electrum BIE1)

Usage

A complete, runnable version of every example below lives in examples/main.go; the script-interpreter walkthrough lives in examples/interpreter/main.go.

cd bitcoin-go
go run ./examples            # keys, wallets, scripts, transactions, ...
go run ./examples/interpreter # the script interpreter (VerifyScript)

1. Keys and addresses

import bsv "gitcode.com/Youyi-Labs/bitcoin-go"

// parse a WIF private key
priv, err := bsv.PrivateKeyFromWIF("cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY")
if err != nil { /* handle */ }

// derive the public key and an address (testnet / livenet)
pub := priv.ToPublicKey()
addr, _ := priv.ToAddress(bsv.Testnet)          // mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1
fmt.Println(pub.ToString(), addr.ToString())

// parse an address back and check its type
parsed, _ := bsv.AddressFromString("mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1", nil, "")
parsed.IsPayToPublicKeyHash() // true

// generate random keys
randomPriv, _ := bsv.PrivateKeyFromRandom("testnet")

2. HD wallet keys (BIP32)

// master key from a seed
seed, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f")
master, _ := bsv.HDPrivateKeyFromSeed(seed, nil)
fmt.Println(master.Xprivkey)               // xprv9s21ZrQH143K3QTDL4...
fmt.Println(master.Xpubkey())              // xpub661MyMwAqRbcFtXgS5...

// derive children (hardened with ')
child, _ := master.DeriveChild("m/0'/1/2'", false)

// derive from the public key only (non-hardened)
xpub, _ := bsv.NewHDPublicKey(master.Xpubkey())
grandchild, _ := xpub.DeriveChild("m/0/1", false)

3. Mnemonic (BIP39)

// generate a random 12-word phrase
m, _ := bsv.MnemonicFromRandom(nil)
fmt.Println(m.ToString())

// restore from a known phrase and derive the BIP32 seed + HD key
fixed, _ := bsv.MnemonicFromString(
    "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", nil)
seed := fixed.ToSeed("TREZOR")              // 64-byte BIP39 seed
hd, _ := fixed.ToHDPrivateKey("", nil)      // *bsv.HDPrivateKey

4. Scripts

// build a P2PKH output script from an address
p2pkh, _ := bsv.BuildPublicKeyHashOut(addr)
fmt.Println(p2pkh.ToASM()) // OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG

// OP_RETURN data outputs (plain and safe OP_FALSE OP_RETURN style)
dataOut, _ := bsv.BuildDataOut("hello bsv", "")
safeOut, _ := bsv.BuildSafeDataOut([]byte{1, 2, 3}, "")

// parse a serialized script and classify it
s, _ := bsv.ScriptFromHex("76a914f4c03610e60ad15100929cc23da2f3a799af172588ac")
s.IsPublicKeyHashOut()         // true
scriptAddr, _ := s.ToAddress(bsv.Livenet)  // address the script pays to

// 2-of-2 multisig output
multisig, _ := bsv.BuildMultisigOut([]*bsv.PublicKey{k1, k2}, 2, false)

5. Transactions

// the UTXO to spend (a P2PKH output we control)
scriptPubkey, _ := bsv.BuildPublicKeyHashOut(fromAddr)
utxo := map[string]interface{}{
    "txId":        "a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458",
    "outputIndex": 0,
    "script":      scriptPubkey,
    "satoshis":    100000,
}

tx, _ := bsv.NewTransaction(nil)
tx.From(utxo, nil, 0)                                   // add input
tx.To("mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc", 40000)      // add outputs
tx.To("n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X", 30000)
tx.Sign(priv, 0)                                        // SIGHASH_ALL|FORKID by default

fmt.Println(tx.IsFullySigned())    // true
fmt.Println(tx.GetID())            // txid
fmt.Println(tx.ToHex())            // broadcast-ready serialization

// verify the input script with the full interpreter
verified, errstr := bsv.VerifyScript(tx.Inputs[0].GetScript(), scriptPubkey, tx, 0,
    bsv.SCRIPT_VERIFY_P2SH|bsv.SCRIPT_VERIFY_STRICTENC|bsv.SCRIPT_ENABLE_SIGHASH_FORKID,
    bsv.NewBNFromNumber(100000), nil)

// deserialize back, apply BIP69 ordering, append OP_RETURN data
copy, _ := bsv.TransactionFromString(tx.ToHex())
tx.Sort()
tx.AddData("genesis is coming")

6. Signed messages (BIP137)

msg, _ := bsv.NewMessage("hello, world")
sig, _ := msg.Sign(priv)                    // base64 compact signature
ok, _ := msg.Verify(addr.ToString(), sig)   // true

7. ECIES encryption

// Alice encrypts to Bob's public key
enc := bsv.NewECIES(nil)
enc.SetPrivateKey(alicePriv)
enc.SetPublicKey(bobPriv.ToPublicKey())
ciphertext, _ := enc.Encrypt("top secret", nil)

// Bob decrypts with his private key
dec := bsv.NewECIES(nil)
dec.SetPrivateKey(bobPriv)
plaintext, _ := dec.Decrypt(ciphertext)

8. Blocks and MerkleBlocks (BIP37)

// parse a block header from its 80-byte hex form
header, _ := bsv.BlockHeaderFromString(headerHex)
fmt.Println(header.Hash()) // 000000000019d6689c08... (genesis)

// build a MerkleBlock from its JSON object form (as sent by BIP37 peers)
mb, _ := bsv.NewMerkleBlock(mbJSONObject)
mb.ValidMerkleTree()             // true
filtered, _ := mb.FilteredTxsHash()  // txids matching the bloom filter

// parse a full raw block (magic + size prefix, as stored in blk*.dat)
block, _ := bsv.BlockFromRawBlock(rawBlockData)
block.Header.Hash()
len(block.Transactions)

9. Encoding helpers

bsv.Base58Encode([]byte("hello world"))      // StV1DL6CwTryKyV
bsv.Base58CheckEncode(dataWithChecksum)      // bitcoin base58check
bsv.NewVarintFromNumber(300).Buf             // CompactSize encoding

10. Script interpreter (VerifyScript)

The full BSV script interpreter is exposed through VerifyScript: it runs scriptSig + scriptPubKey on an interpreter stack and reports whether the spend is valid. Two usage modes:

// (a) standalone evaluation: pass a nil transaction for scripts that do not
// sign (no OP_CHECKSIG family) - Magnetic/Monolith opcodes work too
script, _ := bsv.ScriptFromHex("5152935387") // OP_1 OP_2 OP_ADD OP_3 OP_EQUAL
ok, errstr := bsv.VerifyScript(nil, script, nil, 0,
    bsv.SCRIPT_ENABLE_MAGNETIC_OPCODES|bsv.SCRIPT_ENABLE_MONOLITH_OPCODES, nil, nil)
// ok == true, errstr == ""

// (b) full spend verification: the interpreter validates a real P2PKH spend
ok, errstr = bsv.VerifyScript(tx.Inputs[0].GetScript(), scriptPubkey, tx, 0,
    bsv.DEFAULT_FLAGS, bsv.NewBNFromNumber(100000), nil)

A complete, runnable walkthrough - arithmetic, a failing script, OP_CAT, OP_FALSE OP_RETURN, and a correct/wrong-key P2PKH spend - lives in examples/interpreter/main.go:

go run ./examples/interpreter

Testing

The test suite is self-contained: all official bitcoind test vectors are vendored into the repository under testdata/, so the project builds and tests anywhere without the original JS sources. Every vector runs as an individual go test sub-test:

$ go test -v ./...   # 2650+ tests

The vendored data (testdata/) was copied from the original JS project's test/data/ and test/mnemonic/data/ directories:

testdata/
├── base58_keys_valid.json      # bitcoind base58check address/key vectors
├── base58_keys_invalid.json
├── script_tests.json           # script interpreter evaluation vectors
├── tx_valid.json               # full-transaction validity vectors
├── tx_invalid.json
├── tx_creation.json            # end-to-end build/sign/change/serialize vectors
├── sighash.json                # forkid sighash vectors
├── ecdsa.json                  # RFC 6979 ECDSA signature vectors
├── bip69.json                  # BIP69 input/output ordering vectors
├── fixtures.json               # BIP39 mnemonic vectors
├── merkleblocks.json           # BIP37 merkleblock filter vectors
├── blk86756-testnet.dat        # real testnet block (wire format)
└── blk86756-testnet.json       # expected block contents

Coverage highlights:

  • script_tests.json — 1324 interpreter vectors (all pass, 5 witness-format vectors skipped)
  • tx_valid.json / tx_invalid.json — 50 valid + 40 invalid full-transaction vectors
  • tx_creation.json — 6 end-to-end build/sign/change/serialize vectors (byte-exact)
  • sighash.json — 1000 forkid sighash vectors
  • ecdsa.json — RFC 6979 signature vectors (byte-exact r/s)
  • base58_keys_valid/invalid.json — 100 address/key vectors
  • BIP39 fixtures — 25 entropy→mnemonic→seed vectors
  • BIP32 — derivation vectors with byte-exact xprv/xpub
  • BIP69 — input/output sorting vectors
  • MerkleBlock (BIP37) — official filter vectors
  • Real block — 22-transaction testnet block parsed and verified
  • Behavior tests — Script API, keys, addresses, transactions, locktimes
  • Cross-library — ECIES ciphertext and Message signatures byte-identical to the JS library

Dependencies

Everything else uses the Go standard library.

项目介绍

可用于在 Go 项目中构建、签名、验证 Bitcoin SV 交易,处理密钥、地址、脚本和区块等。项目从 JavaScript 版 BSV 库移植,提供与官方 bitcoind 测试向量和 JS 库交叉验证的完整测试套件,涵盖加密、编码、HD 钱包、脚本解释器等核心功能。【此简介由AI生成】

定制我的领域