钱包 -> 账户、交易,存储。

架构设计:

钱包主要功能有两个:

  • 存储数据。举例:

    • 和“链”无关的数据 。如账户信息,地址、密钥、助记词等。
    • 和“链”有关的数据 。如交易信息,历史交易记录,入账、出账等。
  • 处理用户行为。举例:

    • 核心功能 。创建账户,转账、查账,签名,导入、导出数据,查看交易汇总信息,查看单笔交易相关信息等。
    • 非核心功能 。获取部分“链”相关数据,钱包的创建、恢复、修改密码,钱包设置,查看当前手续费,调用挖矿程序等。

根据上述“猜测”,我们来检查“钱包”所提供的各个方法,进行验证,就会发现实际情况和我们的预期“基本符合”。

数据需要存储,Wallet ORM,连接数据库 db Wallet 与软件其它模块的桥梁。

数据结构:

  • 钱包相关
  • 账户相关
  • 交易相关

对外接口:

  • 钱包模块 - 模块方法,数量少
  • 钱包实例 - 实例方法,数量多

钱包

Wallet

// this is stored in disk in encrypted form
type Wallet struct {
    Version semver.Version `json:"version"` // database version
    Secret  []byte         `json:"secret"`  // actual unlocker to the DB, depends on password from user, stored encrypted
    // secret key used to encrypt all DB data ( both keys and values )
    // this is always in encrypted form

    KDF KDF `json:"kdf"`

    account           *Account //`json:"-"` // not serialized, we store an encrypted version  // keys, seed language etc settings
    Account_Encrypted []byte   `json:"account_encrypted"`

    pbkdf2_password []byte // used to encrypt metadata on updates
    master_password []byte // single password which never changes

    Daemon_Endpoint   string `json:"-"` // endpoint used to communicate with daemon
    Daemon_Height     uint64 `json:"-"` // used to track  daemon height  ony if wallet in online
    Daemon_TopoHeight int64  `json:"-"` // used to track  daemon topo height  ony if wallet in online

    wallet_online_mode bool // set whether the mode is online or offline
    // an offline wallet can be converted to online mode, calling.
    // SetOffline() and vice versa using SetOnline
    // used to create transaction with this fee rate,
    //if this is lower than network, then created transaction will be rejected by network
    dynamic_fees_per_kb uint64
    quit                chan bool // channel to quit any processing go routines

    db *bolt.DB // access to DB

    rpcserver *RPCServer // reference to RPCserver

    id string // first 8 bytes of wallet address , to put into logs to identify different wallets in case many are active

    transfer_mutex sync.Mutex // to avoid races within the transfer
    //sync.Mutex  // used to syncronise access
    sync.RWMutex
}

涉及账户(安全,余额、转账等)、RPC服务、存储服务等。

KDF

// see this https://godoc.org/golang.org/x/crypto/pbkdf2
type KDF struct {
    Hashfunction string `json:"hash"` //"SHA1" currently only sha1 is supported
    Keylen       int    `json:"keylen"`
    Iterations   int    `json:"iterations"`
    Salt         []byte `json:"salt"`
}

账户

Account

type Account struct {
    Keys           _Keys   `json:"keys"`
    SeedLanguage   string  `json:"seedlanguage"`
    FeesMultiplier float32 `json:"feesmultiplier"` // fees multiplier accurate to 2 decimals
    Mixin          int     `json:"mixin"`          // default mixn to use for txs

    ViewOnly bool `json:"viewonly"` // is this viewonly wallet

    Index_Global uint64 `json:"index_global"` // till where the indexes have been processed, it must only increase and never decrease
    Height       uint64 `json:"height"`       // block height till where blockchain has been scanned
    TopoHeight   int64  `json:"topoheight"`   // block height till where blockchain has been scanned

    //Wallet_Height    uint64    `json:"wallet_height"`// used to track height till which we have scanned the inputs

    balance_stale  bool   // whether the balance  is stale
    Balance_Mature uint64 `json:"balance_mature"` // total balance of account
    Balance_Locked uint64 `json:"balance_locked"` // balance locked

    random_percent uint64 // number of outputs to store within the db, for mixing, default is 10%

    key_image_checklist map[crypto.Key]bool // key images which need to be monitored, this is updated when new funds arrive

    //Outputs_Array []TX_Wallet_Data // all outputs found in the chain belonging to us, as found in chain

    // uint64 si the Index_Global which is the unique number
    //Outputs_Index    map[uint64]bool               // all outputs which  are ours for deduplication
    //Outputs_Ready    map[uint64]TX_Wallet_Data     // these outputs are ready for consumption ( maturity needs to be checked)
    //Keyimages_Ready  map[crypto.Key]bool           // keyimages which are ready to get consumed, // we monitor them to find which
    //Outputs_Consumed map[crypto.Key]TX_Wallet_Data // the key is the keyimage

    //Random_Outputs  map[uint64]TX_Wallet_Data  // random ring members
    //Random_Outputs_Recent map[uint64]TX_Wallet_Data  // random ring members from recent blocks
    //Ring_Members    map[uint64]bool // ring members

    sync.Mutex // syncronise modifications to this structure
}

_Keys

type _Keys struct {
    Spendkey_Secret crypto.Key `json:"spendkey_secret"`
    Spendkey_Public crypto.Key `json:"spendkey_public"`
    Viewkey_Secret  crypto.Key `json:"viewkey_secret"`
    Viewkey_Public  crypto.Key `json:"viewkey_public"`
}

交易

Ring_Member

// all random outputs are stored within wallet in this form
// to be used as ring members
type Ring_Member struct { // structure size is around 74 bytes
    InKey         ringct.CtKey `msgpack:"K"`
    Index_Global  uint64       `msgpack:"I"`
    Height        uint64       `msgpack:"H"`
    Unlock_Height uint64       `msgpack:"U,omitempty"` // this is mostly empty
    Sigtype       uint64       `msgpack:"S,omitempty"` // this is empty for miner tx
}

TX_Wallet_Data

// this structure is kept by wallet
type TX_Wallet_Data struct {
    TXdata globals.TX_Output_Data `msgpack:"txdata"` // all the fields of output data

    WAmount      uint64       `msgpack:"wamount"` // actual amount, in case of miner it is verbatim, for other cases it decrypted
    WKey         ringct.CtKey `msgpack:"wkey"`    // key which is used to later send this specific output
    WKimage      crypto.Key   `msgpack:"wkimage"` // key image which gets consumed when this output is spent
    WSpent       bool         `msgpack:"wspent"`  // whether this output has been spent
    WSpentPool   bool         //`msgpack:""`// we built and send out a tx , but it has not been mined
    WPaymentID   []byte       `msgpack:"wpaymentid"`   // payment if if present and decrypted if required
    WSecretTXkey crypto.Key   `msgpack:"wsecrettxkey"` // tx secret which can be be used to prove that the funds have been spent
}

Entry

// 本地存储的转账记录
// Show_Transfers 时用到

type Entry struct {
    Index_Global uint64 `json:"index_global"`
    Height       uint64 `json:"height"` 
    TopoHeight   int64  `json:"topoheight"` 
    TXID         crypto.Hash `json:"txid"` 
    Amount       uint64  `json:"amount"`
    PaymentID    []byte `json:"payment_id"`
    Status       byte  `json:"status"`
     Unlock_Time  uint64 `json:"unlock_time"`
    Time         time.Time `json:"time"`
    Secret_TX_Key string `json:"secret_tx_key"`  // can be used to prove if available
    Details structures.Outgoing_Transfer_Details `json:"details"`  // actual details if available
}

results matching ""

    No results matching ""