Address format is set in configuration instead of RPC options
This commit is contained in:
parent
9147781772
commit
ea3cfd2d6a
@ -3,7 +3,6 @@ package bchain
|
|||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
"github.com/juju/errors"
|
"github.com/juju/errors"
|
||||||
@ -215,15 +214,12 @@ func (a baseAddress) String() string {
|
|||||||
return a.addr
|
return a.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a baseAddress) EncodeAddress(format AddressFormat) (string, error) {
|
func (a baseAddress) EncodeAddress() (string, error) {
|
||||||
if format != DefaultAddress {
|
|
||||||
return "", fmt.Errorf("Unknown address format: %d", format)
|
|
||||||
}
|
|
||||||
return a.addr, nil
|
return a.addr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a baseAddress) AreEqual(addr string) (bool, error) {
|
func (a baseAddress) AreEqual(addr string) (bool, error) {
|
||||||
ea, err := a.EncodeAddress(0)
|
ea, err := a.EncodeAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -231,12 +227,12 @@ func (a baseAddress) AreEqual(addr string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a baseAddress) InSlice(addrs []string) (bool, error) {
|
func (a baseAddress) InSlice(addrs []string) (bool, error) {
|
||||||
|
ea, err := a.EncodeAddress()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
eq, err := a.AreEqual(addr)
|
if ea == addr {
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if eq {
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,23 +12,45 @@ import (
|
|||||||
"github.com/cpacia/bchutil"
|
"github.com/cpacia/bchutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AddressFormat = uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
Legacy AddressFormat = iota
|
||||||
|
CashAddr
|
||||||
|
)
|
||||||
|
|
||||||
var prefixes = []string{"bitcoincash", "bchtest", "bchreg"}
|
var prefixes = []string{"bitcoincash", "bchtest", "bchreg"}
|
||||||
|
|
||||||
// BCashParser handle
|
// BCashParser handle
|
||||||
type BCashParser struct {
|
type BCashParser struct {
|
||||||
*btc.BitcoinParser
|
*btc.BitcoinParser
|
||||||
|
AddressFormat AddressFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBCashParser returns new BCashParser instance
|
// NewBCashParser returns new BCashParser instance
|
||||||
func NewBCashParser(params *chaincfg.Params, c *btc.Configuration) *BCashParser {
|
func NewBCashParser(params *chaincfg.Params, c *btc.Configuration) *BCashParser {
|
||||||
|
var format AddressFormat
|
||||||
|
switch c.AddressFormat {
|
||||||
|
case "":
|
||||||
|
fallthrough
|
||||||
|
case "cashaddr":
|
||||||
|
format = CashAddr
|
||||||
|
case "legacy":
|
||||||
|
format = Legacy
|
||||||
|
default:
|
||||||
|
// XXX
|
||||||
|
e := fmt.Errorf("Unknown address format: %s", c.AddressFormat)
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
return &BCashParser{
|
return &BCashParser{
|
||||||
BitcoinParser: &btc.BitcoinParser{
|
BitcoinParser: &btc.BitcoinParser{
|
||||||
BaseParser: &bchain.BaseParser{
|
BaseParser: &bchain.BaseParser{
|
||||||
AddressFactory: func(addr string) (bchain.Address, error) { return newBCashAddress(addr, params) },
|
AddressFactory: func(addr string) (bchain.Address, error) { return newBCashAddress(addr, params, format) },
|
||||||
BlockAddressesToKeep: c.BlockAddressesToKeep,
|
BlockAddressesToKeep: c.BlockAddressesToKeep,
|
||||||
},
|
},
|
||||||
Params: params,
|
Params: params,
|
||||||
},
|
},
|
||||||
|
AddressFormat: format,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +125,7 @@ func (p *BCashParser) UnpackTx(buf []byte) (tx *bchain.Tx, height uint32, err er
|
|||||||
|
|
||||||
for i, vout := range tx.Vout {
|
for i, vout := range tx.Vout {
|
||||||
if len(vout.ScriptPubKey.Addresses) == 1 {
|
if len(vout.ScriptPubKey.Addresses) == 1 {
|
||||||
a, err := newBCashAddress(vout.ScriptPubKey.Addresses[0], p.Params)
|
a, err := newBCashAddress(vout.ScriptPubKey.Addresses[0], p.Params, p.AddressFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
@ -115,11 +137,12 @@ func (p *BCashParser) UnpackTx(buf []byte) (tx *bchain.Tx, height uint32, err er
|
|||||||
}
|
}
|
||||||
|
|
||||||
type bcashAddress struct {
|
type bcashAddress struct {
|
||||||
addr btcutil.Address
|
addr btcutil.Address
|
||||||
net *chaincfg.Params
|
net *chaincfg.Params
|
||||||
|
format AddressFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBCashAddress(addr string, net *chaincfg.Params) (*bcashAddress, error) {
|
func newBCashAddress(addr string, net *chaincfg.Params, format AddressFormat) (*bcashAddress, error) {
|
||||||
var (
|
var (
|
||||||
da btcutil.Address
|
da btcutil.Address
|
||||||
err error
|
err error
|
||||||
@ -148,18 +171,23 @@ func newBCashAddress(addr string, net *chaincfg.Params) (*bcashAddress, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &bcashAddress{addr: da, net: net}, nil
|
switch format {
|
||||||
|
case Legacy, CashAddr:
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Unknown address format: %d", format)
|
||||||
|
}
|
||||||
|
return &bcashAddress{addr: da, net: net, format: format}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *bcashAddress) String() string {
|
func (a *bcashAddress) String() string {
|
||||||
return a.addr.String()
|
return a.addr.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *bcashAddress) EncodeAddress(format bchain.AddressFormat) (string, error) {
|
func (a *bcashAddress) EncodeAddress() (string, error) {
|
||||||
switch format {
|
switch a.format {
|
||||||
case bchain.DefaultAddress:
|
case Legacy:
|
||||||
return a.String(), nil
|
return a.String(), nil
|
||||||
case bchain.BCashAddress:
|
case CashAddr:
|
||||||
var (
|
var (
|
||||||
ca btcutil.Address
|
ca btcutil.Address
|
||||||
err error
|
err error
|
||||||
@ -178,18 +206,12 @@ func (a *bcashAddress) EncodeAddress(format bchain.AddressFormat) (string, error
|
|||||||
return ca.String(), nil
|
return ca.String(), nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("Unknown address format: %d", format)
|
return "", fmt.Errorf("Unknown address format: %d", a.format)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *bcashAddress) AreEqual(addr string) (bool, error) {
|
func (a *bcashAddress) AreEqual(addr string) (bool, error) {
|
||||||
var format bchain.AddressFormat
|
ea, err := a.EncodeAddress()
|
||||||
if isCashAddr(addr) {
|
|
||||||
format = bchain.BCashAddress
|
|
||||||
} else {
|
|
||||||
format = bchain.DefaultAddress
|
|
||||||
}
|
|
||||||
ea, err := a.EncodeAddress(format)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -197,12 +219,12 @@ func (a *bcashAddress) AreEqual(addr string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *bcashAddress) InSlice(addrs []string) (bool, error) {
|
func (a *bcashAddress) InSlice(addrs []string) (bool, error) {
|
||||||
|
ea, err := a.EncodeAddress()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
eq, err := a.AreEqual(addr)
|
if ea == addr {
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if eq {
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,12 +10,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestBcashAddressEncodeAddress(t *testing.T) {
|
func TestBcashAddressEncodeAddress(t *testing.T) {
|
||||||
addr, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", GetChainParams("main"))
|
addr1, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", GetChainParams("main"), Legacy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("newBCashAddress() error = %v", err)
|
t.Errorf("newBCashAddress() error = %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
got1, err := addr.EncodeAddress(bchain.DefaultAddress)
|
got1, err := addr1.EncodeAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("EncodeAddress() error = %v", err)
|
t.Errorf("EncodeAddress() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -23,7 +23,12 @@ func TestBcashAddressEncodeAddress(t *testing.T) {
|
|||||||
if got1 != "13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji" {
|
if got1 != "13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji" {
|
||||||
t.Errorf("EncodeAddress() got1 = %v, want %v", got1, "13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji")
|
t.Errorf("EncodeAddress() got1 = %v, want %v", got1, "13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji")
|
||||||
}
|
}
|
||||||
got2, err := addr.EncodeAddress(bchain.BCashAddress)
|
addr2, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", GetChainParams("main"), CashAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("newBCashAddress() error = %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
got2, err := addr2.EncodeAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("EncodeAddress() error = %v", err)
|
t.Errorf("EncodeAddress() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -34,12 +39,17 @@ func TestBcashAddressEncodeAddress(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBcashAddressAreEqual(t *testing.T) {
|
func TestBcashAddressAreEqual(t *testing.T) {
|
||||||
addr, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", GetChainParams("main"))
|
addr1, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", GetChainParams("main"), Legacy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("newBCashAddress() error = %v", err)
|
t.Errorf("newBCashAddress() error = %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
got1, err := addr.AreEqual("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji")
|
addr2, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", GetChainParams("main"), CashAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("newBCashAddress() error = %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
got1, err := addr1.AreEqual("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("AreEqual() error = %v", err)
|
t.Errorf("AreEqual() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -47,7 +57,7 @@ func TestBcashAddressAreEqual(t *testing.T) {
|
|||||||
if got1 != true {
|
if got1 != true {
|
||||||
t.Errorf("AreEqual() got1 = %v, want %v", got1, true)
|
t.Errorf("AreEqual() got1 = %v, want %v", got1, true)
|
||||||
}
|
}
|
||||||
got2, err := addr.AreEqual("bitcoincash:qqsvjuqqwgyzvz7zz9xcvxent0ul2xjs6y4d9qvsrf")
|
got2, err := addr2.AreEqual("bitcoincash:qqsvjuqqwgyzvz7zz9xcvxent0ul2xjs6y4d9qvsrf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("AreEqual() error = %v", err)
|
t.Errorf("AreEqual() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -55,7 +65,7 @@ func TestBcashAddressAreEqual(t *testing.T) {
|
|||||||
if got2 != true {
|
if got2 != true {
|
||||||
t.Errorf("AreEqual() got2 = %v, want %v", got2, true)
|
t.Errorf("AreEqual() got2 = %v, want %v", got2, true)
|
||||||
}
|
}
|
||||||
got3, err := addr.AreEqual("1HoKgKQh7ZNomWURmS9Tk3z8JM2MWm7S1w")
|
got3, err := addr1.AreEqual("1HoKgKQh7ZNomWURmS9Tk3z8JM2MWm7S1w")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("AreEqual() error = %v", err)
|
t.Errorf("AreEqual() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -63,7 +73,7 @@ func TestBcashAddressAreEqual(t *testing.T) {
|
|||||||
if got3 != false {
|
if got3 != false {
|
||||||
t.Errorf("AreEqual() got3 = %v, want %v", got3, false)
|
t.Errorf("AreEqual() got3 = %v, want %v", got3, false)
|
||||||
}
|
}
|
||||||
got4, err := addr.AreEqual("bitcoincash:qzuyf0gpqj7q5wfck3nyghhklju7r0k3ksmq6d0vch")
|
got4, err := addr2.AreEqual("bitcoincash:qzuyf0gpqj7q5wfck3nyghhklju7r0k3ksmq6d0vch")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("AreEqual() error = %v", err)
|
t.Errorf("AreEqual() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -74,12 +84,17 @@ func TestBcashAddressAreEqual(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBcashAddressInSlice(t *testing.T) {
|
func TestBcashAddressInSlice(t *testing.T) {
|
||||||
addr, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", GetChainParams("main"))
|
addr1, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", GetChainParams("main"), Legacy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("newBCashAddress() error = %v", err)
|
t.Errorf("newBCashAddress() error = %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
got1, err := addr.InSlice([]string{"13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", "bitcoincash:qzuyf0gpqj7q5wfck3nyghhklju7r0k3ksmq6d0vch"})
|
addr2, err := newBCashAddress("13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", GetChainParams("main"), CashAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("newBCashAddress() error = %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
got1, err := addr1.InSlice([]string{"13zMwGC5bxRn9ckJ1mgxf7UR8qbbNe2iji", "1HoKgKQh7ZNomWURmS9Tk3z8JM2MWm7S1w"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("InSlice() error = %v", err)
|
t.Errorf("InSlice() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -87,7 +102,7 @@ func TestBcashAddressInSlice(t *testing.T) {
|
|||||||
if got1 != true {
|
if got1 != true {
|
||||||
t.Errorf("InSlice() got1 = %v, want %v", got1, true)
|
t.Errorf("InSlice() got1 = %v, want %v", got1, true)
|
||||||
}
|
}
|
||||||
got2, err := addr.InSlice([]string{"1HoKgKQh7ZNomWURmS9Tk3z8JM2MWm7S1w", "bitcoincash:qqsvjuqqwgyzvz7zz9xcvxent0ul2xjs6y4d9qvsrf"})
|
got2, err := addr2.InSlice([]string{"bitcoincash:qzuyf0gpqj7q5wfck3nyghhklju7r0k3ksmq6d0vch", "bitcoincash:qqsvjuqqwgyzvz7zz9xcvxent0ul2xjs6y4d9qvsrf"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("InSlice() error = %v", err)
|
t.Errorf("InSlice() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -95,7 +110,7 @@ func TestBcashAddressInSlice(t *testing.T) {
|
|||||||
if got2 != true {
|
if got2 != true {
|
||||||
t.Errorf("InSlice() got2 = %v, want %v", got2, true)
|
t.Errorf("InSlice() got2 = %v, want %v", got2, true)
|
||||||
}
|
}
|
||||||
got3, err := addr.InSlice([]string{"1HoKgKQh7ZNomWURmS9Tk3z8JM2MWm7S1w", "1E6Np6dUPYpBSdLMLuwBF8sRQ3cngdaRRY"})
|
got3, err := addr1.InSlice([]string{"1HoKgKQh7ZNomWURmS9Tk3z8JM2MWm7S1w", "1E6Np6dUPYpBSdLMLuwBF8sRQ3cngdaRRY"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("InSlice() error = %v", err)
|
t.Errorf("InSlice() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -103,7 +118,7 @@ func TestBcashAddressInSlice(t *testing.T) {
|
|||||||
if got3 != false {
|
if got3 != false {
|
||||||
t.Errorf("InSlice() got3 = %v, want %v", got3, false)
|
t.Errorf("InSlice() got3 = %v, want %v", got3, false)
|
||||||
}
|
}
|
||||||
got4, err := addr.InSlice([]string{"bitcoincash:qzuyf0gpqj7q5wfck3nyghhklju7r0k3ksmq6d0vch", "bitcoincash:qz8emmpenqgeg7et8xsz8prvhy6cqcalyyjcamt7e9"})
|
got4, err := addr2.InSlice([]string{"bitcoincash:qzuyf0gpqj7q5wfck3nyghhklju7r0k3ksmq6d0vch", "bitcoincash:qz8emmpenqgeg7et8xsz8prvhy6cqcalyyjcamt7e9"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("InSlice() error = %v", err)
|
t.Errorf("InSlice() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -149,12 +164,12 @@ func init() {
|
|||||||
addr1, addr2, addr3 bchain.Address
|
addr1, addr2, addr3 bchain.Address
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
addr1, err = newBCashAddress("3AZKvpKhSh1o8t1QrX3UeXG9d2BhCRnbcK", GetChainParams("main"))
|
addr1, err = newBCashAddress("3AZKvpKhSh1o8t1QrX3UeXG9d2BhCRnbcK", GetChainParams("main"), Legacy)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
addr2, err = newBCashAddress("2NByHN6A8QYkBATzxf4pRGbCSHD5CEN2TRu", GetChainParams("test"))
|
addr2, err = newBCashAddress("2NByHN6A8QYkBATzxf4pRGbCSHD5CEN2TRu", GetChainParams("test"), Legacy)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
addr3, err = newBCashAddress("2MvZguYaGjM7JihBgNqgLF2Ca2Enb76Hj9D", GetChainParams("test"))
|
addr3, err = newBCashAddress("2MvZguYaGjM7JihBgNqgLF2Ca2Enb76Hj9D", GetChainParams("test"), Legacy)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -248,7 +263,7 @@ func Test_UnpackTx(t *testing.T) {
|
|||||||
name: "btc-1",
|
name: "btc-1",
|
||||||
args: args{
|
args: args{
|
||||||
packedTx: testTxPacked1,
|
packedTx: testTxPacked1,
|
||||||
parser: NewBCashParser(GetChainParams("main"), &btc.Configuration{}),
|
parser: NewBCashParser(GetChainParams("main"), &btc.Configuration{AddressFormat: "legacy"}),
|
||||||
},
|
},
|
||||||
want: &testTx1,
|
want: &testTx1,
|
||||||
want1: 123456,
|
want1: 123456,
|
||||||
@ -258,7 +273,7 @@ func Test_UnpackTx(t *testing.T) {
|
|||||||
name: "testnet-1",
|
name: "testnet-1",
|
||||||
args: args{
|
args: args{
|
||||||
packedTx: testTxPacked2,
|
packedTx: testTxPacked2,
|
||||||
parser: NewBCashParser(GetChainParams("test"), &btc.Configuration{}),
|
parser: NewBCashParser(GetChainParams("test"), &btc.Configuration{AddressFormat: "legacy"}),
|
||||||
},
|
},
|
||||||
want: &testTx2,
|
want: &testTx2,
|
||||||
want1: 510234,
|
want1: 510234,
|
||||||
|
|||||||
@ -44,6 +44,7 @@ type Configuration struct {
|
|||||||
BlockAddressesToKeep int `json:"blockAddressesToKeep"`
|
BlockAddressesToKeep int `json:"blockAddressesToKeep"`
|
||||||
MempoolWorkers int `json:"mempoolWorkers"`
|
MempoolWorkers int `json:"mempoolWorkers"`
|
||||||
MempoolSubWorkers int `json:"mempoolSubWorkers"`
|
MempoolSubWorkers int `json:"mempoolSubWorkers"`
|
||||||
|
AddressFormat string `json:"addressFormat"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBitcoinRPC returns new BitcoinRPC instance.
|
// NewBitcoinRPC returns new BitcoinRPC instance.
|
||||||
|
|||||||
@ -41,16 +41,9 @@ type ScriptPubKey struct {
|
|||||||
Addresses []string `json:"addresses,omitempty"`
|
Addresses []string `json:"addresses,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddressFormat = uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
DefaultAddress AddressFormat = iota
|
|
||||||
BCashAddress
|
|
||||||
)
|
|
||||||
|
|
||||||
type Address interface {
|
type Address interface {
|
||||||
String() string
|
String() string
|
||||||
EncodeAddress(format AddressFormat) (string, error)
|
EncodeAddress() (string, error)
|
||||||
AreEqual(addr string) (bool, error)
|
AreEqual(addr string) (bool, error)
|
||||||
InSlice(addrs []string) (bool, error)
|
InSlice(addrs []string) (bool, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,5 +8,6 @@
|
|||||||
"subversion": "/Bitcoin ABC:0.17.1/",
|
"subversion": "/Bitcoin ABC:0.17.1/",
|
||||||
"mempoolWorkers": 8,
|
"mempoolWorkers": 8,
|
||||||
"mempoolSubWorkers": 2,
|
"mempoolSubWorkers": 2,
|
||||||
"blockAddressesToKeep": 300
|
"blockAddressesToKeep": 300,
|
||||||
|
"addressFormat": "legacy"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,5 +8,6 @@
|
|||||||
"subversion": "/Bitcoin ABC:0.17.1/",
|
"subversion": "/Bitcoin ABC:0.17.1/",
|
||||||
"mempoolWorkers": 8,
|
"mempoolWorkers": 8,
|
||||||
"mempoolSubWorkers": 2,
|
"mempoolSubWorkers": 2,
|
||||||
"blockAddressesToKeep": 300
|
"blockAddressesToKeep": 300,
|
||||||
|
"addressFormat": "legacy"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -208,16 +208,11 @@ func (s *SocketIoServer) apiBlockIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type addrOpts struct {
|
type addrOpts struct {
|
||||||
Start int `json:"start"`
|
Start int `json:"start"`
|
||||||
End int `json:"end"`
|
End int `json:"end"`
|
||||||
QueryMempoolOnly bool `json:"queryMempoolOnly"`
|
QueryMempoolOnly bool `json:"queryMempoolOnly"`
|
||||||
From int `json:"from"`
|
From int `json:"from"`
|
||||||
To int `json:"to"`
|
To int `json:"to"`
|
||||||
AddressFormat uint8 `json:"addressFormat"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type txOpts struct {
|
|
||||||
AddressFormat uint8 `json:"addressFormat"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var onMessageHandlers = map[string]func(*SocketIoServer, json.RawMessage) (interface{}, error){
|
var onMessageHandlers = map[string]func(*SocketIoServer, json.RawMessage) (interface{}, error){
|
||||||
@ -260,9 +255,9 @@ var onMessageHandlers = map[string]func(*SocketIoServer, json.RawMessage) (inter
|
|||||||
return s.getInfo()
|
return s.getInfo()
|
||||||
},
|
},
|
||||||
"getDetailedTransaction": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) {
|
"getDetailedTransaction": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) {
|
||||||
txid, opts, err := unmarshalGetDetailedTransaction(params)
|
txid, err := unmarshalGetDetailedTransaction(params)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rv, err = s.getDetailedTransaction(txid, opts)
|
rv, err = s.getDetailedTransaction(txid)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
@ -483,7 +478,7 @@ func (s *SocketIoServer) getAddressHistory(addr []string, opts *addrOpts) (res r
|
|||||||
Script: &aoh,
|
Script: &aoh,
|
||||||
}
|
}
|
||||||
if vout.Address != nil {
|
if vout.Address != nil {
|
||||||
a, err := vout.Address.EncodeAddress(opts.AddressFormat)
|
a, err := vout.Address.EncodeAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -693,13 +688,13 @@ func unmarshalStringParameter(params []byte) (s string, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalGetDetailedTransaction(params []byte) (txid string, opts txOpts, err error) {
|
func unmarshalGetDetailedTransaction(params []byte) (txid string, err error) {
|
||||||
var p []json.RawMessage
|
var p []json.RawMessage
|
||||||
err = json.Unmarshal(params, &p)
|
err = json.Unmarshal(params, &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(p) < 1 || len(p) > 2 {
|
if len(p) != 1 {
|
||||||
err = errors.New("incorrect number of parameters")
|
err = errors.New("incorrect number of parameters")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -707,9 +702,6 @@ func unmarshalGetDetailedTransaction(params []byte) (txid string, opts txOpts, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(p) > 1 {
|
|
||||||
err = json.Unmarshal(p[1], &opts)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,7 +709,7 @@ type resultGetDetailedTransaction struct {
|
|||||||
Result resTx `json:"result"`
|
Result resTx `json:"result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SocketIoServer) getDetailedTransaction(txid string, opts txOpts) (res resultGetDetailedTransaction, err error) {
|
func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetailedTransaction, err error) {
|
||||||
bestheight, _, err := s.db.GetBestBlock()
|
bestheight, _, err := s.db.GetBestBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -743,7 +735,7 @@ func (s *SocketIoServer) getDetailedTransaction(txid string, opts txOpts) (res r
|
|||||||
if len(otx.Vout) > int(vin.Vout) {
|
if len(otx.Vout) > int(vin.Vout) {
|
||||||
vout := otx.Vout[vin.Vout]
|
vout := otx.Vout[vin.Vout]
|
||||||
if vout.Address != nil {
|
if vout.Address != nil {
|
||||||
a, err := vout.Address.EncodeAddress(opts.AddressFormat)
|
a, err := vout.Address.EncodeAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -761,7 +753,7 @@ func (s *SocketIoServer) getDetailedTransaction(txid string, opts txOpts) (res r
|
|||||||
Script: &aos,
|
Script: &aos,
|
||||||
}
|
}
|
||||||
if vout.Address != nil {
|
if vout.Address != nil {
|
||||||
a, err := vout.Address.EncodeAddress(opts.AddressFormat)
|
a, err := vout.Address.EncodeAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,15 +56,14 @@
|
|||||||
var addresses = document.getElementById('getAddressHistoryAddresses').value.split(",");
|
var addresses = document.getElementById('getAddressHistoryAddresses').value.split(",");
|
||||||
addresses = addresses.map(s => s.trim());
|
addresses = addresses.map(s => s.trim());
|
||||||
var mempool = document.getElementById("getAddressHistoryMempool").checked;
|
var mempool = document.getElementById("getAddressHistoryMempool").checked;
|
||||||
var format = document.getElementById("getAddressHistoryFormat").value;
|
lookupAddressHistories(addresses, 0, 5, mempool, 20000000, 0, function (result) {
|
||||||
lookupAddressHistories(addresses, 0, 5, mempool, 20000000, 0, format, function (result) {
|
|
||||||
console.log('getAddressHistory sent successfully');
|
console.log('getAddressHistory sent successfully');
|
||||||
console.log(result);
|
console.log(result);
|
||||||
document.getElementById('getAddressHistoryResult').innerText = JSON.stringify(result).replace(/,/g, ", ");
|
document.getElementById('getAddressHistoryResult').innerText = JSON.stringify(result).replace(/,/g, ", ");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function lookupAddressHistories(addresses, from, to, mempool, start, end, format, f) {
|
function lookupAddressHistories(addresses, from, to, mempool, start, end, f) {
|
||||||
const method = 'getAddressHistory';
|
const method = 'getAddressHistory';
|
||||||
const opts = mempool ? {
|
const opts = mempool ? {
|
||||||
start, // needed for older bitcores (so we don't load all history if bitcore-node < 3.1.3)
|
start, // needed for older bitcores (so we don't load all history if bitcore-node < 3.1.3)
|
||||||
@ -81,7 +80,6 @@
|
|||||||
...opts,
|
...opts,
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
addressFormat: parseInt(format),
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
return socket.send({ method, params }, f);
|
return socket.send({ method, params }, f);
|
||||||
@ -172,28 +170,18 @@
|
|||||||
|
|
||||||
function getDetailedTransaction() {
|
function getDetailedTransaction() {
|
||||||
var hash = document.getElementById('getDetailedTransactionHash').value.trim();
|
var hash = document.getElementById('getDetailedTransactionHash').value.trim();
|
||||||
var format = document.getElementById("getDetailedTransactionFormat").value;
|
lookupDetailedTransaction(hash, function (result) {
|
||||||
lookupDetailedTransaction(hash, format, function (result) {
|
|
||||||
console.log('getDetailedTransaction sent successfully');
|
console.log('getDetailedTransaction sent successfully');
|
||||||
console.log(result);
|
console.log(result);
|
||||||
document.getElementById('getDetailedTransactionResult').innerText = JSON.stringify(result).replace(/,/g, ", ");
|
document.getElementById('getDetailedTransactionResult').innerText = JSON.stringify(result).replace(/,/g, ", ");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function lookupDetailedTransaction(hash, format, f) {
|
function lookupDetailedTransaction(hash, f) {
|
||||||
const method = 'getDetailedTransaction';
|
const method = 'getDetailedTransaction';
|
||||||
const af = parseInt(format)
|
|
||||||
var params = [
|
var params = [
|
||||||
hash,
|
hash,
|
||||||
];
|
];
|
||||||
if (af !== 0) {
|
|
||||||
params = [
|
|
||||||
hash,
|
|
||||||
{
|
|
||||||
addressFormat: af,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return socket.send({ method, params }, f);
|
return socket.send({ method, params }, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,14 +290,6 @@
|
|||||||
<input type="checkbox" id="getAddressHistoryMempool">
|
<input type="checkbox" id="getAddressHistoryMempool">
|
||||||
<label>only mempool</label>
|
<label>only mempool</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-9"></div>
|
|
||||||
<div class="col form-inline">
|
|
||||||
<label>address format</label>
|
|
||||||
<select id="getAddressHistoryFormat" value="0">
|
|
||||||
<option value="0">default</option>
|
|
||||||
<option value="1">bitcoincash</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col" id="getAddressHistoryResult">
|
<div class="col" id="getAddressHistoryResult">
|
||||||
@ -373,14 +353,6 @@
|
|||||||
<input type="text" class="form-control" id="getDetailedTransactionHash" value="474e6795760ebe81cb4023dc227e5a0efe340e1771c89a0035276361ed733de7">
|
<input type="text" class="form-control" id="getDetailedTransactionHash" value="474e6795760ebe81cb4023dc227e5a0efe340e1771c89a0035276361ed733de7">
|
||||||
</div>
|
</div>
|
||||||
<div class="col"></div>
|
<div class="col"></div>
|
||||||
<div class="col-9"></div>
|
|
||||||
<div class="col form-inline">
|
|
||||||
<label>address format</label>
|
|
||||||
<select id="getDetailedTransactionFormat" value="0">
|
|
||||||
<option value="0">default</option>
|
|
||||||
<option value="1">bitcoincash</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col" id="getDetailedTransactionResult">
|
<div class="col" id="getDetailedTransactionResult">
|
||||||
@ -443,4 +415,4 @@
|
|||||||
document.getElementById('serverAddress').value = window.location.protocol.replace("http", "ws") + "//" + window.location.host;
|
document.getElementById('serverAddress').value = window.location.protocol.replace("http", "ws") + "//" + window.location.host;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user