Initial commit.

This commit is contained in:
Josh Rickmar 2014-05-22 12:45:08 -05:00 committed by Josh Rickmar
commit 55ef07ca61
3 changed files with 318 additions and 0 deletions

92
README.md Normal file
View file

@ -0,0 +1,92 @@
btcnet
======
Package btcnet defines the network parameters for the three standard Bitcoin
networks and provides the ability for callers to define their own custom
Bitcoin networks.
This package is one of the core packages from btcd, an alternative full-node
implementation of Bitcoin which is under active development by Conformal.
Although it was primarily written for btcd, this package has intentionally been
designed so it can be used as a standalone package for any projects needing to
use parameters for the standard Bitcoin networks or for projects needing to
define their own network.
## Sample Use
```Go
package main
import (
"flag"
"fmt"
"github.com/conformal/btcnet"
"github.com/conformal/btcutil"
)
var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network")
// By default (without -testnet), use mainnet.
var netParams = &btcnet.MainNetParams
func main() {
flag.Parse()
// Modify active network parameters if operating on testnet.
if *testnet {
netParams = &btcnet.TestNet3Params
}
// later...
// Create and print new payment address, specific to the active network.
pubKeyHash := make([]byte, 20)
addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, netParams.Net)
if err != nil {
// badness
return
}
fmt.Println(addr)
}
```
## Documentation
Full `go doc` style documentation for the project can be viewed online without
installing this package by using the GoDoc site
[here](http://godoc.org/github.com/conformal/btcnet).
You can also view the documentation locally once the package is installed with
the `godoc` tool by running `godoc -http=":6060"` and pointing your browser to
http://localhost:6060/pkg/github.com/conformal/btcnet
## Installation
```bash
$ go get github.com/conformal/btcnet
```
## GPG Verification Key
All official release tags are signed by Conformal so users can ensure the code
has not been tampered with and is coming from Conformal. To verify the
signature perform the following:
- Download the public key from the Conformal website at
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
- Import the public key into your GPG keyring:
```bash
gpg --import GIT-GPG-KEY-conformal.txt
```
- Verify the release tag with the following command where `TAG_NAME` is a
placeholder for the specific tag:
```bash
git tag -v TAG_NAME
```
## License
Package btcnet is licensed under the liberal ISC License.

63
doc.go Normal file
View file

@ -0,0 +1,63 @@
// Package btcnet defines the network parameters for the three standard Bitcoin
// networks and provides the ability for callers to define their own custom
// Bitcoin networks.
//
// In addition to the main Bitcoin network, which is intended for the transfer
// of monetary value, there also exists two currently active standard networks:
// regression test and testnet (version 3). These networks are incompatible
// with each other (each sharing a different genesis block) and software should
// handle errors where input intended for one network is used on an application
// instance running on a different network.
//
// For library packages, btcnet provides the ability to lookup chain parameters
// and encoding magics when passed a *Params. Older APIs not updated to the new
// convention of passing a *Params may lookup the parameters for a
// btcwire.BitcoinNet using ParamsForNet, but be aware that this usage is
// deprecated and will be removed from btcnet in the future.
//
// For main packages, a (typically global) var may be assigned the address of
// one of the standard Param vars for use as the application's "active" network.
// When a network parameter is needed, it may then be looked up through this
// variable (either directly, or hidden in a library call).
//
// package main
//
// import (
// "flag"
// "fmt"
// "log"
//
// "github.com/conformal/btcnet"
// "github.com/conformal/btcutil"
// )
//
// var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network")
//
// // By default (without -testnet), use mainnet.
// var netParams = &btcnet.MainNetParams
//
// func main() {
// flag.Parse()
//
// // Modify active network parameters if operating on testnet.
// if *testnet {
// netParams = &btcnet.TestNet3Params
// }
//
// // later...
//
// // Create and print new payment address, specific to the active network.
// pubKeyHash := make([]byte, 20)
// addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, netParams.Net)
// if err != nil {
// log.Fatal(err)
// }
// fmt.Println(addr)
// }
//
// If an application does not use one of the three standard Bitcoin networks,
// a new Params struct may be created which defines the parameters for the
// non-standard network. As a general rule of thumb, all network parameters
// should be unique to the network, but parameter collisions can still occur
// (unfortunately, this is the case with regtest and testnet3 sharing magics).
package btcnet

163
params.go Normal file
View file

@ -0,0 +1,163 @@
package btcnet
import (
"errors"
"math/big"
"github.com/conformal/btcwire"
)
// These variables are the chain proof-of-work limit parameters for each default
// network.
var (
// bigOne is 1 represented as a big.Int. It is defined here to avoid
// the overhead of creating it multiple times.
bigOne = big.NewInt(1)
// mainPowLimit is the highest proof of work value a Bitcoin block can
// have for the main network. It is the value 2^224 - 1.
mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne)
// regressionPowLimit is the highest proof of work value a Bitcoin block
// can have for the regression test network. It is the value 2^255 - 1.
regressionPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne)
// testNet3PowLimit is the highest proof of work value a Bitcoin block
// can have for the test network (version 3). It is the value
// 2^224 - 1.
testNet3PowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne)
)
// Params defines a Bitcoin network by its parameters. These parameters may be
// used by Bitcoin applications to differentiate networks as well as addresses
// and keys for one network from those intended for use on another network.
type Params struct {
Name string
Net btcwire.BitcoinNet
// Chain parameters
GenesisBlock *btcwire.MsgBlock
GenesisHash *btcwire.ShaHash
PowLimit *big.Int
PowLimitBits uint32
SubsidyHalvingInterval int32
// Encoding magics
PubKeyHashAddrID byte // First byte of a P2PKH address
ScriptHashAddrID byte // First byte of a P2SH address
PrivateKeyID byte // First byte of a WIF private key
}
// MainNetParams defines the network parameters for the main Bitcoin network.
var MainNetParams = Params{
Name: "mainnet",
Net: btcwire.MainNet,
// Chain parameters
GenesisBlock: &btcwire.GenesisBlock,
GenesisHash: &btcwire.GenesisHash,
PowLimit: mainPowLimit,
PowLimitBits: 0x1d00ffff,
SubsidyHalvingInterval: 210000,
// Encoding magics
PubKeyHashAddrID: 0x00,
ScriptHashAddrID: 0x05,
PrivateKeyID: 0x80,
}
// RegressionNetParams defines the network parameters for the regression test
// Bitcoin network. Not to be confused with the test Bitcoin network (version
// 3), this network is sometimes simply called "testnet".
var RegressionNetParams = Params{
Name: "regtest",
Net: btcwire.TestNet,
// Chain parameters
GenesisBlock: &btcwire.TestNetGenesisBlock,
GenesisHash: &btcwire.TestNetGenesisHash,
PowLimit: regressionPowLimit,
PowLimitBits: 0x207fffff,
SubsidyHalvingInterval: 150,
// Encoding magics
PubKeyHashAddrID: 0x6f,
ScriptHashAddrID: 0xc4,
PrivateKeyID: 0xef,
}
// TestNet3Params defines the network parameters for the test Bitcoin network
// (version 3). Not to be confused with the regression test network, this
// network is sometimes simply called "testnet".
var TestNet3Params = Params{
Name: "testnet",
Net: btcwire.TestNet3,
// Chain parameters
GenesisBlock: &btcwire.TestNet3GenesisBlock,
GenesisHash: &btcwire.TestNet3GenesisHash,
PowLimit: testNet3PowLimit,
PowLimitBits: 0x1d00ffff,
SubsidyHalvingInterval: 210000,
// Encoding magics
PubKeyHashAddrID: 0x6f,
ScriptHashAddrID: 0xc4,
PrivateKeyID: 0xef,
}
var (
// ErrUnknownNet describes an error where the network parameters for a
// network cannot be looked up because the network is non-standard and
// is not registered into this package.
//
// This will be removed when ParamsForNet is eventually removed.
ErrUnknownNet = errors.New("unknown Bitcoin network")
// ErrDuplicateNet describes an error where the parameters for a Bitcoin
// network could not be set due to the network already being a standard
// network or previously-registered into this package.
//
// This will be removed when Register is eventually removed.
ErrDuplicateNet = errors.New("duplicate Bitcoin network")
)
var nets = map[btcwire.BitcoinNet]*Params{
btcwire.MainNet: &MainNetParams,
btcwire.TestNet: &RegressionNetParams,
btcwire.TestNet3: &TestNet3Params,
}
// ParamsForNet returns the network parameters for a Bitcoin network, or
// ErrUnknownNet if the network is not a default network (mainnet, regtest,
// or testnet3) and not registered into the package with Register.
//
// This should be considered an unstable API and will be removed when all other
// Conformal btc* packages (btcwire not included) are updated from using
// btcwire.BitcoinNet to *Params.
func ParamsForNet(net btcwire.BitcoinNet) (*Params, error) {
params, ok := nets[net]
if !ok {
return nil, ErrUnknownNet
}
return params, nil
}
// Register registers the network parameters for a Bitcoin network. This may
// error with ErrDuplicateNet if the network is already registered.
//
// Network parameters should be registered into this package by a main package
// as early as possible. Then, library packages may lookup networks or network
// parameters based on inputs and work regardless of the network being standard
// or not.
//
// This should be considered an unstable API and will be removed when all other
// Conformal btc* packages (btcwire not included) are updated from using
// btcwire.BitcoinNet to *Params.
func Register(params *Params) error {
if _, ok := nets[params.Net]; ok {
return ErrDuplicateNet
}
nets[params.Net] = params
return nil
}