cosmos-sdk/x/supply/types/account.go

157 lines
4.2 KiB
Go

package types
import (
"encoding/json"
"errors"
"fmt"
"strings"
yaml "gopkg.in/yaml.v2"
"github.com/tendermint/tendermint/crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/supply/exported"
)
var (
_ authexported.GenesisAccount = (*ModuleAccount)(nil)
_ exported.ModuleAccountI = (*ModuleAccount)(nil)
)
// NewModuleAddress creates an AccAddress from the hash of the module's name
func NewModuleAddress(name string) sdk.AccAddress {
return sdk.AccAddress(crypto.AddressHash([]byte(name)))
}
// NewEmptyModuleAccount creates a empty ModuleAccount from a string
func NewEmptyModuleAccount(name string, permissions ...string) *ModuleAccount {
moduleAddress := NewModuleAddress(name)
baseAcc := authtypes.NewBaseAccountWithAddress(moduleAddress)
if err := validatePermissions(permissions...); err != nil {
panic(err)
}
return &ModuleAccount{
BaseAccount: baseAcc,
Name: name,
Permissions: permissions,
}
}
// NewModuleAccount creates a new ModuleAccount instance
func NewModuleAccount(ba *authtypes.BaseAccount, name string, permissions ...string) *ModuleAccount {
if err := validatePermissions(permissions...); err != nil {
panic(err)
}
return &ModuleAccount{
BaseAccount: ba,
Name: name,
Permissions: permissions,
}
}
// HasPermission returns whether or not the module account has permission.
func (ma ModuleAccount) HasPermission(permission string) bool {
for _, perm := range ma.Permissions {
if perm == permission {
return true
}
}
return false
}
// GetName returns the the name of the holder's module
func (ma ModuleAccount) GetName() string {
return ma.Name
}
// GetPermissions returns permissions granted to the module account
func (ma ModuleAccount) GetPermissions() []string {
return ma.Permissions
}
// SetPubKey - Implements Account
func (ma ModuleAccount) SetPubKey(pubKey crypto.PubKey) error {
return fmt.Errorf("not supported for module accounts")
}
// SetSequence - Implements Account
func (ma ModuleAccount) SetSequence(seq uint64) error {
return fmt.Errorf("not supported for module accounts")
}
// Validate checks for errors on the account fields
func (ma ModuleAccount) Validate() error {
if strings.TrimSpace(ma.Name) == "" {
return errors.New("module account name cannot be blank")
}
if !ma.Address.Equals(sdk.AccAddress(crypto.AddressHash([]byte(ma.Name)))) {
return fmt.Errorf("address %s cannot be derived from the module name '%s'", ma.Address, ma.Name)
}
return ma.BaseAccount.Validate()
}
type moduleAccountPretty struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
PubKey string `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
Name string `json:"name" yaml:"name"`
Permissions []string `json:"permissions" yaml:"permissions"`
}
func (ma ModuleAccount) String() string {
out, _ := ma.MarshalYAML()
return out.(string)
}
// MarshalYAML returns the YAML representation of a ModuleAccount.
func (ma ModuleAccount) MarshalYAML() (interface{}, error) {
bs, err := yaml.Marshal(moduleAccountPretty{
Address: ma.Address,
PubKey: "",
AccountNumber: ma.AccountNumber,
Sequence: ma.Sequence,
Name: ma.Name,
Permissions: ma.Permissions,
})
if err != nil {
return nil, err
}
return string(bs), nil
}
// MarshalJSON returns the JSON representation of a ModuleAccount.
func (ma ModuleAccount) MarshalJSON() ([]byte, error) {
return json.Marshal(moduleAccountPretty{
Address: ma.Address,
PubKey: "",
AccountNumber: ma.AccountNumber,
Sequence: ma.Sequence,
Name: ma.Name,
Permissions: ma.Permissions,
})
}
// UnmarshalJSON unmarshals raw JSON bytes into a ModuleAccount.
func (ma *ModuleAccount) UnmarshalJSON(bz []byte) error {
var alias moduleAccountPretty
if err := json.Unmarshal(bz, &alias); err != nil {
return err
}
ma.BaseAccount = authtypes.NewBaseAccount(alias.Address, nil, alias.AccountNumber, alias.Sequence)
ma.Name = alias.Name
ma.Permissions = alias.Permissions
return nil
}