package main
import (
"encoding/hex"
"encoding/json"
"fmt"
bsv "gitcode.com/Youyi-Labs/bitcoin-go"
)
func must(err error) {
if err != nil {
panic(err)
}
}
func main() {
fmt.Println("== 1. Keys and Addresses ==")
priv, err := bsv.PrivateKeyFromWIF("cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY")
must(err)
fmt.Println("private key (WIF):", priv.ToString())
fmt.Println("private key (hex):", priv.ToHex())
pub := priv.ToPublicKey()
fmt.Println("public key:", pub.ToString())
fmt.Println("compressed:", pub.Compressed)
addr, err := priv.ToAddress(bsv.Testnet)
must(err)
fmt.Println("address (testnet):", addr.ToString())
fmt.Println("is P2PKH:", addr.IsPayToPublicKeyHash())
addr2, err := bsv.AddressFromString("mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1", nil, "")
must(err)
fmt.Println("parsed address:", addr2.ToString(), "network:", addr2.Network)
randomPriv, err := bsv.PrivateKeyFromRandom("testnet")
must(err)
fmt.Println("random key:", randomPriv.ToWIF())
fmt.Println("\n== 2. HD Keys (BIP32) ==")
seed, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f")
master, err := bsv.HDPrivateKeyFromSeed(seed, nil)
must(err)
fmt.Println("master xprv:", master.Xprivkey)
fmt.Println("master xpub:", master.Xpubkey())
child, err := master.DeriveChild("m/0'/1/2'", false)
must(err)
fmt.Println("child m/0'/1/2':", child.Xprivkey)
xpub, err := bsv.NewHDPublicKey(master.Xpubkey())
must(err)
grandchild, err := xpub.DeriveChild("m/0/1", false)
must(err)
fmt.Println("public m/0/1:", grandchild.Xpubkey)
fmt.Println("\n== 3. Mnemonic (BIP39) ==")
mnemonic, err := bsv.MnemonicFromRandom(nil)
must(err)
fmt.Println("random phrase:", mnemonic.ToString())
fixed, err := bsv.MnemonicFromString(
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", nil)
must(err)
seedBytes := fixed.ToSeed("TREZOR")
fmt.Println("known seed:", hex.EncodeToString(seedBytes)[:32], "...")
hdFromMnemonic, err := fixed.ToHDPrivateKey("", nil)
must(err)
fmt.Println("HD key from mnemonic:", hdFromMnemonic.Xprivkey[:20], "...")
fmt.Println("\n== 4. Scripts ==")
p2pkh, err := bsv.BuildPublicKeyHashOut(addr)
must(err)
fmt.Println("P2PKH output:", p2pkh.ToASM())
dataOut, err := bsv.BuildDataOut("hello bsv", "")
must(err)
fmt.Println("OP_RETURN:", dataOut.ToASM())
safeOut, err := bsv.BuildSafeDataOut([]byte{1, 2, 3}, "")
must(err)
fmt.Println("safe OP_RETURN:", safeOut.ToASM())
parsed, err := bsv.ScriptFromHex("76a914f4c03610e60ad15100929cc23da2f3a799af172588ac")
must(err)
fmt.Println("parsed script:", parsed.ToASM())
fmt.Println("is P2PKH out:", parsed.IsPublicKeyHashOut())
scriptAddr, err := parsed.ToAddress(bsv.Livenet)
must(err)
fmt.Println("script pays to:", scriptAddr.ToString())
k1, _ := bsv.PublicKeyFromHex("020483ebb834d91d494a3b649cf0e8f5c9c4fcec5f194ab94341cc99bb440007f2")
k2, _ := bsv.PublicKeyFromHex("0271ebaeef1c2bf0c1a4772d1391eab03e4d96a6e9b48551ab4e4b0d2983eb452b")
multisig, err := bsv.BuildMultisigOut([]*bsv.PublicKey{k1, k2}, 2, false)
must(err)
fmt.Println("2-of-2 multisig:", multisig.ToASM())
fmt.Println("\n== 5. Transactions ==")
fromAddr, err := priv.ToAddress(bsv.Testnet)
must(err)
scriptPubkey, err := bsv.BuildPublicKeyHashOut(fromAddr)
must(err)
utxo := map[string]interface{}{
"txId": "a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458",
"outputIndex": 0,
"script": scriptPubkey,
"satoshis": 100000,
}
tx, err := bsv.NewTransaction(nil)
must(err)
_, err = tx.From(utxo, nil, 0)
must(err)
_, err = tx.To("mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc", 40000)
must(err)
_, err = tx.To("n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X", 30000)
must(err)
_, err = tx.Sign(priv, 0)
must(err)
fmt.Println("fully signed:", tx.IsFullySigned())
fmt.Println("txid:", tx.GetID())
fmt.Println("serialized tx:", tx.ToHex())
scriptSig := tx.Inputs[0].GetScript()
verified, errstr := bsv.VerifyScript(scriptSig, scriptPubkey, tx, 0,
bsv.SCRIPT_VERIFY_P2SH|bsv.SCRIPT_VERIFY_STRICTENC|bsv.SCRIPT_ENABLE_SIGHASH_FORKID,
bsv.NewBNFromNumber(100000), nil)
fmt.Println("script verified:", verified, "err:", errstr)
tx2, err := bsv.TransactionFromString(tx.ToHex())
must(err)
fmt.Println("roundtrip equal:", tx2.ToHex() == tx.ToHex())
tx.Sort()
_, err = tx.AddData("genesis is coming")
must(err)
fmt.Println("\n== 6. Signed Messages ==")
msg, err := bsv.NewMessage("hello, world")
must(err)
sig, err := msg.Sign(priv)
must(err)
fmt.Println("signature:", sig)
ok, err := msg.Verify(fromAddr.ToString(), sig)
must(err)
fmt.Println("verified:", ok)
fmt.Println("\n== 7. ECIES ==")
bobPriv, err := bsv.PrivateKeyFromRandom(nil)
must(err)
enc := bsv.NewECIES(nil)
enc.SetPrivateKey(priv)
enc.SetPublicKey(bobPriv.ToPublicKey())
ciphertext, err := enc.Encrypt("top secret", nil)
must(err)
fmt.Println("ciphertext:", hex.EncodeToString(ciphertext)[:32], "...")
dec := bsv.NewECIES(nil)
dec.SetPrivateKey(bobPriv)
plaintext, err := dec.Decrypt(ciphertext)
must(err)
fmt.Println("decrypted:", string(plaintext))
fmt.Println("\n== 8. Blocks ==")
headerHex := "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c"
header, err := bsv.BlockHeaderFromString(headerHex)
must(err)
fmt.Println("genesis header hash:", header.Hash())
mbJSON := `{
"header": {
"hash": "0000000000000000011b04bc9f4f3856e299b53a335eb1c42be906237c860bb8",
"version": 4,
"prevHash": "0000000000000000015373947aa93c7cb16a308fb0a59644d4123072ad24ce5b",
"merkleRoot": "ac1841eb3b7d380ee114270e3b1c7df349f1e27e2f0f7891138199bc07e006f8",
"time": 1456274787,
"bits": 403093919,
"nonce": 73707849
},
"numTransactions": 3309,
"hashes": [
"adaf1e41a5349a7e2b27e6f2b5fc1186d576d21b47531a410a654439f49bd5a9",
"0f64562b6d361757bfdc5926d28cafb7c45e4822b4ad5a14e65530d0c9d44cd2",
"c34dec8d5954d8c151c3a594a5a6d1f3a1ec8a1a6c470b27aea879b7757328fb",
"c044e5d998fe29cdbe88f87c97c3547f142f5b491cb909d9b0a8e9d3ab7fc984",
"51ecd2d2b02b0ca1a3b439eae3adf87ab37dd87f7be0c5b3437cd22350079101",
"684ebe37c6eaae2879249ff20b3769d5f2f7ad853a5363a4baee68c0c85777a5",
"e561fbeb0faff42f95f2dc8d57d432d4d1a9f84483597a0602e1edc3390f1e33",
"02c070afc743c885a6c8d94d15d6e9c3b991c636b4284258dd37686c8792fe44",
"6f64fd5aa9dd01f74c03656d376625cf80328d83d9afebe60cc68b8f0e245bd9",
"a296fef97b3da0825bac00c794ea234913421b7c1cbb8571978d8d5ba3b16de2",
"691c6855c5da434a06cb39a7e47d9337da0e39112ad975cc70cecc882233920a",
"6a9e7f8e6d1d8c326a774ff691bdf424252cee710f8e5d9da2c094e999c15efc",
"0723ffc695fef989e86784fa2b47097d55f6aac244631536d8d901f5cd9bf170"
],
"flags": [171, 86, 23, 0]
}`
var mbObj map[string]interface{}
must(json.Unmarshal([]byte(mbJSON), &mbObj))
mb, err := bsv.NewMerkleBlock(mbObj)
must(err)
fmt.Println("merkle tree valid:", mb.ValidMerkleTree())
filtered, err := mb.FilteredTxsHash()
must(err)
fmt.Println("matching txs:", filtered)
fmt.Println("\n== 9. Encoding ==")
fmt.Println("base58(hello world):", bsv.Base58Encode([]byte("hello world")))
fmt.Println("base58check of 33 bytes:", bsv.Base58CheckEncode(make([]byte, 33)))
}