-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
915 additions
and
136 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package btc | ||
|
||
import ( | ||
"github.com/btcsuite/btcd/btcjson" | ||
"github.com/btcsuite/btcd/chaincfg/chainhash" | ||
"github.com/btcsuite/btcd/rpcclient" | ||
"github.com/btcsuite/btcd/wire" | ||
"github.com/btcsuite/btcutil" | ||
) | ||
|
||
type Client struct { | ||
rpc *rpcclient.Client | ||
} | ||
|
||
func NewClient(host, user, pass string) (*Client, error) { | ||
client, err := rpcclient.New(&rpcclient.ConnConfig{ | ||
HTTPPostMode: true, | ||
DisableTLS: true, | ||
Host: host, | ||
User: user, | ||
Pass: pass, | ||
}, nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &Client{ | ||
rpc: client, | ||
}, nil | ||
} | ||
|
||
// GetBlockCount 获取区块数量,调用返回本地最优链中的区块数量。 | ||
func (c *Client) GetBlockCount() (int64, error) { | ||
return c.rpc.GetBlockCount() | ||
} | ||
|
||
// GetBlockHash 获取指定高度区块的哈希。 | ||
func (c *Client) GetBlockHash(blockNumber int64) (*chainhash.Hash, error) { | ||
return c.rpc.GetBlockHash(blockNumber) | ||
} | ||
|
||
// ImportAddress 导入地址 | ||
func (c *Client) ImportAddress(address string) error { | ||
return c.rpc.ImportAddress(address) | ||
} | ||
|
||
// ListUnspent 获取未交易的UTX | ||
func (c *Client) ListUnspent(address btcutil.Address) (listUnSpent []btcjson.ListUnspentResult, err error) { | ||
adds := [1]btcutil.Address{address} | ||
listUnSpent, err = c.rpc.ListUnspentMinMaxAddresses(1, 999999, adds[:]) | ||
if err != nil { | ||
return | ||
} | ||
return | ||
} | ||
|
||
// SendRawTransaction 发送裸交易 | ||
func (c *Client) SendRawTransaction(tx *wire.MsgTx) (*chainhash.Hash, error) { | ||
|
||
return c.rpc.SendRawTransaction(tx, false) | ||
|
||
} | ||
|
||
// ListSinceBlock 查询指定区块后发生的钱包交易 | ||
func (c *Client) ListSinceBlock(blockHash *chainhash.Hash) (*btcjson.ListSinceBlockResult, error) { | ||
return c.rpc.ListSinceBlock(blockHash) | ||
} | ||
|
||
// ListTransactions 查询最近发生的钱包交易 | ||
func (c *Client) ListTransactions(account string) ([]btcjson.ListTransactionsResult, error) { | ||
return c.rpc.ListTransactions(account) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package btc | ||
|
||
import ( | ||
"fmt" | ||
"github.com/btcsuite/btcutil" | ||
"testing" | ||
) | ||
|
||
func TestClient_ListUnspent(t *testing.T) { | ||
|
||
var ( | ||
//host = "47.243.189.44:30000" | ||
//user = "BTCuser" | ||
//pass = "BTCpassword" | ||
//network = "MainNet" | ||
|
||
host = "127.0.0.1:18332" | ||
user = "admin" | ||
pass = "123456" | ||
network = "TestNet3" | ||
defaultNet = getNetwork(network) | ||
) | ||
//address := "2N8Ah8xiqrfb37aktkkwYmMqpDGQJMSDAWY" | ||
address := "2NGU5d9Y3uKLJXZa6GgYm2bf4wNK33GcAwJ" | ||
client, err := NewClient(host, user, pass) | ||
if err != nil { | ||
t.Error("创建client失败:", err) | ||
} | ||
fromAddress, err := btcutil.DecodeAddress(address, defaultNet) | ||
if err != nil { | ||
t.Error("地址错误:", err) | ||
} | ||
|
||
list, err := client.ListUnspent(fromAddress) | ||
if err != nil { | ||
t.Error("获取未交易的UTXO失败:", err) | ||
} | ||
|
||
fmt.Println(list) | ||
|
||
} | ||
|
||
func TestClient_GetBlockHash(t *testing.T) { | ||
|
||
var ( | ||
host = "127.0.0.1:18332" | ||
user = "admin" | ||
pass = "123456" | ||
) | ||
client, err := NewClient(host, user, pass) | ||
if err != nil { | ||
t.Error("创建client失败:", err) | ||
} | ||
|
||
blockNumber := int64(2000000) | ||
hash, err := client.GetBlockHash(blockNumber) | ||
if err != nil { | ||
t.Error("获取区块哈希失败:", err) | ||
} | ||
|
||
fmt.Println(hash) | ||
|
||
} | ||
|
||
func TestClient_ListSinceBlock(t *testing.T) { | ||
|
||
var ( | ||
//host = "47.243.189.44:30000" | ||
//user = "BTCuser" | ||
//pass = "BTCpassword" | ||
|
||
host = "127.0.0.1:18332" | ||
user = "admin" | ||
pass = "123456" | ||
) | ||
client, err := NewClient(host, user, pass) | ||
if err != nil { | ||
t.Error("创建client失败:", err) | ||
} | ||
|
||
blockNumber := int64(600000) | ||
hash, err := client.GetBlockHash(blockNumber) | ||
if err != nil { | ||
t.Error("获取区块哈希失败:", err) | ||
} | ||
|
||
fmt.Println(hash) | ||
|
||
list, err := client.ListSinceBlock(hash) | ||
if err != nil { | ||
t.Error("获取交易列表失败:", err) | ||
} | ||
|
||
fmt.Println(list) | ||
|
||
} | ||
|
||
func TestClient_ListTransactions(t *testing.T) { | ||
|
||
var ( | ||
//host = "47.243.189.44:30000" | ||
//user = "BTCuser" | ||
//pass = "BTCpassword" | ||
host = "127.0.0.1:18332" | ||
user = "admin" | ||
pass = "123456" | ||
) | ||
client, err := NewClient(host, user, pass) | ||
if err != nil { | ||
t.Error("创建client失败:", err) | ||
} | ||
|
||
address := "2N8Ah8xiqrfb37aktkkwYmMqpDGQJMSDAWY" | ||
list, err := client.ListTransactions(address) | ||
if err != nil { | ||
t.Error("获取最近发生的钱包交易失败:", err) | ||
} | ||
|
||
fmt.Println(list) | ||
|
||
} | ||
|
||
func TestClient_ImportAddress(t *testing.T) { | ||
|
||
var ( | ||
host = "127.0.0.1:18332" | ||
user = "admin" | ||
pass = "123456" | ||
) | ||
client, err := NewClient(host, user, pass) | ||
if err != nil { | ||
t.Error("创建client失败:", err) | ||
} | ||
|
||
//address := "2N8Ah8xiqrfb37aktkkwYmMqpDGQJMSDAWY" | ||
address := "2NGU5d9Y3uKLJXZa6GgYm2bf4wNK33GcAwJ" | ||
err = client.ImportAddress(address) | ||
if err != nil { | ||
t.Error("导入地址失败:", err) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package btc | ||
|
||
import ( | ||
"github.com/btcsuite/btcd/chaincfg" | ||
"strings" | ||
) | ||
|
||
func getNetwork(network string) *chaincfg.Params { | ||
var defaultNet *chaincfg.Params | ||
|
||
//指定网络 {MainNet:主网,TestNet:测试网,TestNet3:测试网3,SimNet:测试网} | ||
switch strings.ToLower(network) { | ||
case "mainnet": | ||
defaultNet = &chaincfg.MainNetParams | ||
case "testnet": | ||
defaultNet = &chaincfg.RegressionNetParams | ||
case "testnet3": | ||
defaultNet = &chaincfg.TestNet3Params | ||
case "simnet": | ||
defaultNet = &chaincfg.SimNetParams | ||
} | ||
return defaultNet | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package btc | ||
|
||
import ( | ||
"github.com/btcsuite/btcd/btcec" | ||
"github.com/btcsuite/btcd/chaincfg" | ||
"github.com/btcsuite/btcd/txscript" | ||
"github.com/btcsuite/btcutil" | ||
) | ||
|
||
type Wallet struct { | ||
LegacyAddress string // (P2PKH)格式,普通非隔离验证地址(由1开头)| 普及度:较高 | 矿工费:较低 | ||
NestedSegWitAddress string // (P2SH)格式,隔离验证(兼容)地址(由3开头)| 普及度:较高 | 矿工费:较低 | ||
NativeSegWitAddress string // (Bech32)格式,隔离验证(原生)地址(由bc1开头)| 普及度:较低 | 矿工费:最低 | ||
PublicKey string | ||
PrivateKey string | ||
} | ||
|
||
// CreateWallet 创建钱包 | ||
func CreateWallet(defaultNet *chaincfg.Params) (*Wallet, error) { | ||
|
||
//1.生成私钥,参数:Secp256k1 | ||
privateKey, err := btcec.NewPrivateKey(btcec.S256()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
//2.转成wif格式 | ||
privateKeyWif, err := btcutil.NewWIF(privateKey, defaultNet, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return getWalletByPrivateKey(defaultNet, privateKeyWif) | ||
|
||
} | ||
|
||
// GetWalletByPrivateKey 获取钱包通过私钥,返回地址和公钥 | ||
func GetWalletByPrivateKey(defaultNet *chaincfg.Params, privateKeyStr string) (*Wallet, error) { | ||
|
||
// 转成wif格式 | ||
privateKeyWif, err := btcutil.DecodeWIF(privateKeyStr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return getWalletByPrivateKey(defaultNet, privateKeyWif) | ||
} | ||
|
||
// getWalletByPrivateKey 根据网络和 私钥的 wif 获取地址 | ||
func getWalletByPrivateKey(defaultNet *chaincfg.Params, wif *btcutil.WIF) (*Wallet, error) { | ||
|
||
// 获取publicKey | ||
publicKeySerial := wif.PrivKey.PubKey().SerializeCompressed() | ||
|
||
publicKey, err := btcutil.NewAddressPubKey(publicKeySerial, defaultNet) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
pkHash := btcutil.Hash160(publicKeySerial) | ||
nativeSegWitAddressHash, err := btcutil.NewAddressWitnessPubKeyHash(pkHash, defaultNet) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
nestedSegWitAddressWitnessProg, err := txscript.PayToAddrScript(nativeSegWitAddressHash) | ||
if err != nil { | ||
return nil, err | ||
} | ||
nestedSegWitAddressHash, err := btcutil.NewAddressScriptHash(nestedSegWitAddressWitnessProg, defaultNet) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &Wallet{ | ||
LegacyAddress: publicKey.EncodeAddress(), | ||
NestedSegWitAddress: nestedSegWitAddressHash.EncodeAddress(), | ||
NativeSegWitAddress: nativeSegWitAddressHash.EncodeAddress(), | ||
PublicKey: publicKey.String(), | ||
PrivateKey: wif.String(), | ||
}, nil | ||
} |
Oops, something went wrong.