func (account *NothingAccount) String() string {
	buffer := account.Bytes()
	checksum := sha3.Sum256(buffer)
	buffer = append(buffer, checksum[:checksumLength]...)
	return util.ToBase58(buffer)
}
String - base58 encoding of encoded key
package account
import (
	"bytes"
	"golang.org/x/crypto/ed25519"
	"golang.org/x/crypto/sha3"
	"github.com/bitmark-inc/bitmarkd/fault"
	"github.com/bitmark-inc/bitmarkd/util"
)
const (
	Nothing = iota  
	ED25519 = iota
	algorithmLimit = iota
)
const checksumLength = 4
const (
	publicKeyCode = 0x01  
	testKeyCode   = 0x02  
	_             = 0x04  
	_             = 0x08  
)
const algorithmShift = 4
type Account struct {
	AccountInterface
}
type AccountInterface interface {
	KeyType() int
	PublicKeyBytes() []byte
	CheckSignature(message []byte, signature Signature) error
	Bytes() []byte
	String() string
	MarshalText() ([]byte, error)
	IsTesting() bool
	IsZero() bool
}
type ED25519Account struct {
	Test      bool
	PublicKey []byte
}
type NothingAccount struct {
	Test      bool
	PublicKey []byte
}
func AccountFromBase58(accountBase58Encoded string) (*Account, error) {
	accountDecoded := util.FromBase58(accountBase58Encoded)
	if 0 == len(accountDecoded) {
		return nil, fault.CannotDecodeAccount
	}
	keyVariant, keyVariantLength := util.FromVarint64(accountDecoded)
	if 0 == keyVariantLength || keyVariant&publicKeyCode != publicKeyCode {
		return nil, fault.NotPublicKey
	}
	keyAlgorithm := keyVariant >> algorithmShift
	if keyAlgorithm >= algorithmLimit {
		return nil, fault.InvalidKeyType
	}
	isTest := 0 != keyVariant&testKeyCode
	keyLength := len(accountDecoded) - keyVariantLength - checksumLength
	if keyLength <= 0 {
		return nil, fault.InvalidKeyLength
	}
	checksumStart := len(accountDecoded) - checksumLength
	checksum := sha3.Sum256(accountDecoded[:checksumStart])
	if !bytes.Equal(checksum[:checksumLength], accountDecoded[checksumStart:]) {
		return nil, fault.ChecksumMismatch
	}
	switch keyAlgorithm {
	case ED25519:
		if keyLength != ed25519.PublicKeySize {
			return nil, fault.InvalidKeyLength
		}
		publicKey := accountDecoded[keyVariantLength:checksumStart]
		account := &Account{
			AccountInterface: &ED25519Account{
				Test:      isTest,
				PublicKey: publicKey,
			},
		}
		return account, nil
	case Nothing:
		if 2 != keyLength {
			return nil, fault.InvalidKeyLength
		}
		publicKey := accountDecoded[keyVariantLength:checksumStart]
		account := &Account{
			AccountInterface: &NothingAccount{
				Test:      isTest,
				PublicKey: publicKey,
			},
		}
		return account, nil
	default:
		return nil, fault.InvalidKeyType
	}
}
func AccountFromBytes(accountBytes []byte) (*Account, error) {
	keyVariant, keyVariantLength := util.FromVarint64(accountBytes)
	if 0 == keyVariantLength || keyVariant&publicKeyCode != publicKeyCode {
		return nil, fault.NotPublicKey
	}
	keyAlgorithm := keyVariant >> algorithmShift
	if keyAlgorithm >= algorithmLimit {
		return nil, fault.InvalidKeyType
	}
	isTest := 0 != keyVariant&testKeyCode
	keyLength := len(accountBytes) - keyVariantLength
	if keyLength <= 0 {
		return nil, fault.InvalidKeyLength
	}
	switch keyAlgorithm {
	case ED25519:
		if keyLength != ed25519.PublicKeySize {
			return nil, fault.InvalidKeyLength
		}
		publicKey := accountBytes[keyVariantLength:]
		account := &Account{
			AccountInterface: &ED25519Account{
				Test:      isTest,
				PublicKey: publicKey,
			},
		}
		return account, nil
	case Nothing:
		if 2 != keyLength {
			return nil, fault.InvalidKeyLength
		}
		publicKey := accountBytes[keyVariantLength:]
		account := &Account{
			AccountInterface: &NothingAccount{
				Test:      isTest,
				PublicKey: publicKey,
			},
		}
		return account, nil
	default:
		return nil, fault.InvalidKeyType
	}
}
func (account *Account) UnmarshalText(s []byte) error {
	a, err := AccountFromBase58(string(s))
	if nil != err {
		return err
	}
	account.AccountInterface = a.AccountInterface
	return nil
}
func (account *ED25519Account) KeyType() int {
	return ED25519
}
func (account *ED25519Account) PublicKeyBytes() []byte {
	return account.PublicKey[:]
}
func (account *ED25519Account) CheckSignature(message []byte, signature Signature) error {
	if ed25519.SignatureSize != len(signature) {
		return fault.InvalidSignature
	}
	if !ed25519.Verify(account.PublicKey[:], message, signature) {
		return fault.InvalidSignature
	}
	return nil
}
func (account *ED25519Account) Bytes() []byte {
	keyVariant := byte(ED25519<<algorithmShift) | publicKeyCode
	if account.Test {
		keyVariant |= testKeyCode
	}
	return append([]byte{keyVariant}, account.PublicKey[:]...)
}
func (account *ED25519Account) String() string {
	buffer := account.Bytes()
	checksum := sha3.Sum256(buffer)
	buffer = append(buffer, checksum[:checksumLength]...)
	return util.ToBase58(buffer)
}
func (account ED25519Account) MarshalText() ([]byte, error) {
	return []byte(account.String()), nil
}
func (account ED25519Account) IsTesting() bool {
	return account.Test
}
func (account ED25519Account) IsZero() bool {
	for _, b := range account.PublicKey {
		if 0 != b {
			return false
		}
	}
	return true
}
func (account *NothingAccount) KeyType() int {
	return Nothing
}
func (account *NothingAccount) PublicKeyBytes() []byte {
	return account.PublicKey[:]
}
func (account *NothingAccount) CheckSignature(message []byte, signature Signature) error {
	return fault.InvalidSignature
}
func (account *NothingAccount) Bytes() []byte {
	keyVariant := byte(Nothing<<algorithmShift) | publicKeyCode
	if account.Test {
		keyVariant |= testKeyCode
	}
	return append([]byte{keyVariant}, account.PublicKey[:]...)
}