func (wallet *ERC20Wallet) DecodeAddress(addr string) (btcutil.Address, error) {
	ethAddr := common.HexToAddress(addr)
	return EthAddress{&ethAddr}, nil
}
DecodeAddress - Parse the address string and return an address interface
package wallet
import (
	"bytes"
	"context"
	"crypto/ecdsa"
	"encoding/binary"
	"errors"
	"fmt"
	"math/big"
	"time"
	"github.com/OpenBazaar/multiwallet/config"
	wi "github.com/OpenBazaar/wallet-interface"
	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcutil"
	hd "github.com/btcsuite/btcutil/hdkeychain"
	"github.com/davecgh/go-spew/spew"
	ethereum "github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/common/hexutil"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
	"golang.org/x/net/proxy"
	"github.com/OpenBazaar/go-ethwallet/util"
)
type ERC20Wallet struct {
	client               *EthClient
	account              *Account
	address              *EthAddress
	service              *Service
	registry             *Registry
	ppsct                *Escrow
	db                   wi.Datastore
	exchangeRates        wi.ExchangeRates
	symbol               string
	name                 string
	deployAddressMain    common.Address
	deployAddressRopsten common.Address
	deployAddressRinkeby common.Address
	token                *Token
	listeners            []func(wi.TransactionCallback)
}
func GenTokenScriptHash(script EthRedeemScript) ([32]byte, string, error) {
	a := make([]byte, 4)
	binary.BigEndian.PutUint32(a, script.Timeout)
	arr := append(script.TxnID.Bytes(), append([]byte{script.Threshold},
		append(a[:], append(script.Buyer.Bytes(),
			append(script.Seller.Bytes(), append(script.Moderator.Bytes(),
				append(script.MultisigAddress.Bytes(),
					script.TokenAddress.Bytes()...)...)...)...)...)...)...)
	var retHash [32]byte
	copy(retHash[:], crypto.Keccak256(arr))
	ahashStr := hexutil.Encode(retHash[:])
	return retHash, ahashStr, nil
}
type TokenDetail struct {
	name                 string
	symbol               string
	deployAddressMain    common.Address
	deployAddressRopsten common.Address
	deployAddressRinkeby common.Address
}
func NewERC20Wallet(cfg config.CoinConfig, params *chaincfg.Params, mnemonic string, proxy proxy.Dialer) (*ERC20Wallet, error) {
	client, err := NewEthClient(cfg.ClientAPIs[0] + "/" + InfuraAPIKey)
	if err != nil {
		log.Errorf("error initializing wallet: %v", err)
		return nil, err
	}
	var myAccount *Account
	myAccount, err = NewAccountFromMnemonic(mnemonic, "", params)
	if err != nil {
		log.Errorf("mnemonic based pk generation failed: %s", err.Error())
		return nil, err
	}
	addr := myAccount.Address()
	ethConfig := EthConfiguration{}
	var regAddr interface{}
	var ok bool
	if regAddr, ok = cfg.Options["RegistryAddress"]; !ok {
		log.Errorf("ethereum registry not found: %s", cfg.Options["RegistryAddress"])
		return nil, err
	}
	ethConfig.RegistryAddress = regAddr.(string)
	reg, err := NewRegistry(common.HexToAddress(ethConfig.RegistryAddress), client)
	if err != nil {
		log.Errorf("error initilaizing contract failed: %s", err.Error())
		return nil, err
	}
	er := NewEthereumPriceFetcher(proxy)
	token := TokenDetail{}
	var name, symbol, deployAddrMain, deployAddrRopsten, deployAddrRinkeby interface{}
	if name, ok = cfg.Options["Name"]; !ok {
		log.Errorf("erc20 token name not found: %s", cfg.Options["Name"])
		return nil, err
	}
	token.name = name.(string)
	if symbol, ok = cfg.Options["Symbol"]; !ok {
		log.Errorf("erc20 token symbol not found: %s", cfg.Options["Symbol"])
		return nil, err
	}
	token.symbol = symbol.(string)
	if deployAddrMain, ok = cfg.Options["MainNetAddress"]; !ok {
		log.Errorf("erc20 token address not found: %s", cfg.Options["MainNetAddress"])
		return nil, err
	}
	token.deployAddressMain = common.HexToAddress(deployAddrMain.(string))
	if deployAddrRopsten, ok = cfg.Options["RopstenAddress"]; ok {
		token.deployAddressMain = common.HexToAddress(deployAddrRopsten.(string))
	}
	if deployAddrRinkeby, ok = cfg.Options["RinkebyAddress"]; ok {
		token.deployAddressRinkeby = common.HexToAddress(deployAddrRinkeby.(string))
	}
	erc20Token, err := NewToken(token.deployAddressMain, client)
	if err != nil {
		log.Errorf("error initilaizing erc20 token failed: %s", err.Error())
		return nil, err
	}
	return &ERC20Wallet{
		client:               client,
		account:              myAccount,
		address:              &EthAddress{&addr},
		service:              &Service{},
		registry:             reg,
		ppsct:                nil,
		db:                   cfg.DB,
		exchangeRates:        er,
		symbol:               token.symbol,
		name:                 token.name,
		deployAddressMain:    token.deployAddressMain,
		deployAddressRopsten: token.deployAddressRopsten,
		deployAddressRinkeby: token.deployAddressRinkeby,
		token:                erc20Token,
		listeners:            []func(wi.TransactionCallback){},
	}, nil
}
func (wallet *ERC20Wallet) Params() *chaincfg.Params {
	return nil
}
func (wallet *ERC20Wallet) GetBalance() (*big.Int, error) {
	return wallet.client.GetTokenBalance(wallet.account.Address(), wallet.deployAddressMain)
}
func (wallet *ERC20Wallet) GetUnconfirmedBalance() (*big.Int, error) {
	return big.NewInt(0), nil
}
func (wallet *ERC20Wallet) Transfer(to string, value *big.Int) (common.Hash, error) {
	toAddress := common.HexToAddress(to)
	return wallet.client.TransferToken(wallet.account, toAddress, wallet.deployAddressMain, value)
}
func (wallet *ERC20Wallet) Start() {
}
func (wallet *ERC20Wallet) CurrencyCode() string {
	return wallet.symbol
}
func (wallet *ERC20Wallet) IsDust(amount int64) bool {
	return amount < 10000
}
func (wallet *ERC20Wallet) MasterPrivateKey() *hd.ExtendedKey {
	return hd.NewExtendedKey([]byte{0x00, 0x00, 0x00, 0x00}, wallet.account.privateKey.D.Bytes(),
		wallet.account.address.Bytes(), wallet.account.address.Bytes(), 0, 0, true)
}
func (wallet *ERC20Wallet) MasterPublicKey() *hd.ExtendedKey {
	publicKey := wallet.account.privateKey.Public()
	publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
	if !ok {
		log.Fatal("error casting public key to ECDSA")
	}
	publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
	return hd.NewExtendedKey([]byte{0x00, 0x00, 0x00, 0x00}, publicKeyBytes,
		wallet.account.address.Bytes(), wallet.account.address.Bytes(), 0, 0, false)
}
func (wallet *ERC20Wallet) ChildKey(keyBytes []byte, chaincode []byte, isPrivateKey bool) (*hd.ExtendedKey, error) {
	if isPrivateKey {
		return wallet.MasterPrivateKey(), nil
	}
	return wallet.MasterPublicKey(), nil
}
func (wallet *ERC20Wallet) CurrentAddress(purpose wi.KeyPurpose) btcutil.Address {
	return *wallet.address
}
func (wallet *ERC20Wallet) NewAddress(purpose wi.KeyPurpose) btcutil.Address {
	return *wallet.address
}