---
# System prepended metadata

title: State and Keeper

---

# State and Keeper


The module `Custom_Asset`  keeps state of 
- All custom tokens created 
- All tokens/addresses that are frozen  

### State  (types.go) 

```go
type FreezeList struct {
	map[string][]sdk.AccAddress
}
```
```go
type CustomToken struct {
	denom string
	minter sdk.AccAddress
	supply sdk.Int
}
```
----
````go
type CustomToken struct {
  denom string
  minter sdk.AccAddress
  supply sdk.Int
  frozen_addresses []sdk.AccAddress
}
````  
- - Optionally we can also maintain the same state using just one struct,but the first implementation provides faster lookups at the cost of slightly higher storage
- Also note I used the type `sdk.AccAddress` to make things clear, it would be better to use strings,because after 0.42 all addresses are treated as strings in the sdk.This is true for all documents .


### Keeper (keeper.go)
- The keeper provides the state transitions and queries for the state 

#### State Transitions
```go
func (keeper)CreateCustomToken (ctx sdk.Context,c types.CustomToken){}
func (keeper)AddToFreezeList  (ctx sdk.Context,denom string,freezingAddress sdk.AccAddress){}
func (keeper)RemoveFromFreezeList  (ctx sdk.Context,denom string,unFreezingAddress sdk.AccAddress){}
```
#### Helpers / Queries 
```go
func (keeper)IsFrozen (ctx sdk.Context,denom string,checkingAddress string){
	- Convert string to address
	- Get freezelist for denom
	- Iterate list , if a value matches the checkingAddress return true
	- return false after loop
}
func (keeper)IsCustomAsset(ctx sdk.Context,checkingDenom string) bool {
	- Get Prefixed iterator
	- Iterate all records 
	- if record.denom == checkingDenom return true
	- return false at the end of the loop
}
```

- It would also have queries , but I am not going into those details

The `bank_wrapper` module does not have any state of its own.