[{"data":1,"prerenderedAt":510},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fcore-tech\u002Fbeam-wallet-database":3,"docs-surround-\u002Fdocs\u002Fcore-tech\u002Fbeam-wallet-database":500},{"id":4,"title":5,"body":6,"description":12,"extension":493,"image":494,"meta":495,"navTitle":494,"navigation":76,"path":496,"seo":497,"stem":498,"__hash__":499},"docs\u002Fdocs\u002Fcore-tech\u002FBeam-Wallet-Database.md","Beam Wallet Database",{"type":7,"value":8,"toc":489},"minimark",[9,13,16,32,43,46,50,59,346,351,362,470,474,485],[10,11,12],"p",{},"Since in Mimblewimble only UTXO related information is available on chain, most of the Wallet state should be maintained locally and store in the Wallet Database, which is described in this chapter.",[10,14,15],{},"Beam Wallet stores and tracks information about four key entities:",[17,18,19,23,26,29],"ol",{},[20,21,22],"li",{},"Coins",[20,24,25],{},"Addresses",[20,27,28],{},"Transactions",[20,30,31],{},"Blockchain State",[10,33,34,35,42],{},"The interface for the database is specified in the ",[36,37,41],"a",{"href":38,"rel":39},"https:\u002F\u002Fgithub.com\u002FBeamMW\u002Fbeam\u002Fblob\u002F56e9cdd7be211649a576fa15d3f0a97922ae2acd\u002Fwallet\u002Fwallet_db.h#L164",[40],"nofollow","wallet_db.h"," file",[10,44,45],{},"Beam currently uses sqlite relational database in the implementation",[47,48,22],"h1",{"id":49},"coins",[10,51,52,53,58],{},"We will start with the ",[36,54,57],{"href":55,"rel":56},"https:\u002F\u002Fgithub.com\u002FBeamMW\u002Fbeam\u002Fblob\u002F56e9cdd7be211649a576fa15d3f0a97922ae2acd\u002Fwallet\u002Fwallet_db.h#L41",[40],"definition"," of a Coin structure, which represents a UTXO as it is seen by the wallet.",[60,61,66],"pre",{"className":62,"code":63,"language":64,"meta":65,"style":65},"language-c++ shiki shiki-themes github-dark","\n    \u002F\u002F Describes a UTXO in the context of the Wallet\n    struct Coin\n    {\n        \u002F\u002F Status is not stored in the database but can be\n        \u002F\u002F deduced from the current blockchain state\n        enum Status\n        {\n            Unavailable, \u002F\u002F initial status of a new UTXO\n            Available,   \u002F\u002F UTXO is currently present in the chain and can be spent\n            Maturing,    \u002F\u002F UTXO is present in the chain has maturity higher than current height (i.e coinbase or treasury)\n            Outgoing,    \u002F\u002F Available and participates in outgoing transaction\n            Incoming,    \u002F\u002F Outputs of incoming transaction, currently unavailable\n            ChangeV0,    \u002F\u002F deprecated.\n            Spent,       \u002F\u002F UTXO that was spent. Stored in wallet database until reset or restore\n\n            count\n        };\n\n        Coin(Amount amount = 0, Key::Type keyType = Key::Type::Regular);\n        bool operator==(const Coin&) const;\n        bool operator!=(const Coin&) const;\n        bool isReward() const;\n        std::string toStringID() const;\n        Amount getAmount() const;\n\n        typedef Key::IDV ID; \u002F\u002F unique identifier for the coin (including value), can be used to create blinding factor \n        ID m_ID;\n\n        Status m_status;        \u002F\u002F current status of the coin\n        Height m_maturity;      \u002F\u002F coin can be spent only when chain is >= this value. Valid for confirmed coins (Available, Outgoing, Incoming, Change, Spent, Maturing).\n\n                                \u002F\u002F The following fields are used to derive the status of the transaction\n        Height m_confirmHeight; \u002F\u002F height at which the coin was confirmed (appeared in the chain)\n        Height m_spentHeight;   \u002F\u002F height at which the coin was spent\n\n        boost::optional\u003CTxID> m_createTxId;  \u002F\u002F id of the transaction which created the UTXO\n        boost::optional\u003CTxID> m_spentTxId;   \u002F\u002F id of the transaction which spernt the UTXO\n        \n        uint64_t m_sessionId;   \u002F\u002F Used in the API to lock coins for specific session (see https:\u002F\u002Fgithub.com\u002FBeamMW\u002Fbeam\u002Fwiki\u002FBeam-wallet-protocol-API#tx_split)\n\n        bool IsMaturityValid() const; \u002F\u002F is\u002Fwas the UTXO confirmed?\n        Height get_Maturity() const; \u002F\u002F would return MaxHeight unless the UTXO was confirmed\n        \n        std::string getStatusString() const;\n        static boost::optional\u003CCoin::ID> FromString(const std::string& str);\n    };\n","c++","",[67,68,69,78,84,90,96,102,108,114,120,126,132,138,144,150,156,162,167,173,179,184,190,196,202,208,214,220,225,231,237,242,248,254,259,265,271,277,282,288,294,300,306,311,317,323,328,334,340],"code",{"__ignoreMap":65},[70,71,74],"span",{"class":72,"line":73},"line",1,[70,75,77],{"emptyLinePlaceholder":76},true,"\n",[70,79,81],{"class":72,"line":80},2,[70,82,83],{},"    \u002F\u002F Describes a UTXO in the context of the Wallet\n",[70,85,87],{"class":72,"line":86},3,[70,88,89],{},"    struct Coin\n",[70,91,93],{"class":72,"line":92},4,[70,94,95],{},"    {\n",[70,97,99],{"class":72,"line":98},5,[70,100,101],{},"        \u002F\u002F Status is not stored in the database but can be\n",[70,103,105],{"class":72,"line":104},6,[70,106,107],{},"        \u002F\u002F deduced from the current blockchain state\n",[70,109,111],{"class":72,"line":110},7,[70,112,113],{},"        enum Status\n",[70,115,117],{"class":72,"line":116},8,[70,118,119],{},"        {\n",[70,121,123],{"class":72,"line":122},9,[70,124,125],{},"            Unavailable, \u002F\u002F initial status of a new UTXO\n",[70,127,129],{"class":72,"line":128},10,[70,130,131],{},"            Available,   \u002F\u002F UTXO is currently present in the chain and can be spent\n",[70,133,135],{"class":72,"line":134},11,[70,136,137],{},"            Maturing,    \u002F\u002F UTXO is present in the chain has maturity higher than current height (i.e coinbase or treasury)\n",[70,139,141],{"class":72,"line":140},12,[70,142,143],{},"            Outgoing,    \u002F\u002F Available and participates in outgoing transaction\n",[70,145,147],{"class":72,"line":146},13,[70,148,149],{},"            Incoming,    \u002F\u002F Outputs of incoming transaction, currently unavailable\n",[70,151,153],{"class":72,"line":152},14,[70,154,155],{},"            ChangeV0,    \u002F\u002F deprecated.\n",[70,157,159],{"class":72,"line":158},15,[70,160,161],{},"            Spent,       \u002F\u002F UTXO that was spent. Stored in wallet database until reset or restore\n",[70,163,165],{"class":72,"line":164},16,[70,166,77],{"emptyLinePlaceholder":76},[70,168,170],{"class":72,"line":169},17,[70,171,172],{},"            count\n",[70,174,176],{"class":72,"line":175},18,[70,177,178],{},"        };\n",[70,180,182],{"class":72,"line":181},19,[70,183,77],{"emptyLinePlaceholder":76},[70,185,187],{"class":72,"line":186},20,[70,188,189],{},"        Coin(Amount amount = 0, Key::Type keyType = Key::Type::Regular);\n",[70,191,193],{"class":72,"line":192},21,[70,194,195],{},"        bool operator==(const Coin&) const;\n",[70,197,199],{"class":72,"line":198},22,[70,200,201],{},"        bool operator!=(const Coin&) const;\n",[70,203,205],{"class":72,"line":204},23,[70,206,207],{},"        bool isReward() const;\n",[70,209,211],{"class":72,"line":210},24,[70,212,213],{},"        std::string toStringID() const;\n",[70,215,217],{"class":72,"line":216},25,[70,218,219],{},"        Amount getAmount() const;\n",[70,221,223],{"class":72,"line":222},26,[70,224,77],{"emptyLinePlaceholder":76},[70,226,228],{"class":72,"line":227},27,[70,229,230],{},"        typedef Key::IDV ID; \u002F\u002F unique identifier for the coin (including value), can be used to create blinding factor \n",[70,232,234],{"class":72,"line":233},28,[70,235,236],{},"        ID m_ID;\n",[70,238,240],{"class":72,"line":239},29,[70,241,77],{"emptyLinePlaceholder":76},[70,243,245],{"class":72,"line":244},30,[70,246,247],{},"        Status m_status;        \u002F\u002F current status of the coin\n",[70,249,251],{"class":72,"line":250},31,[70,252,253],{},"        Height m_maturity;      \u002F\u002F coin can be spent only when chain is >= this value. Valid for confirmed coins (Available, Outgoing, Incoming, Change, Spent, Maturing).\n",[70,255,257],{"class":72,"line":256},32,[70,258,77],{"emptyLinePlaceholder":76},[70,260,262],{"class":72,"line":261},33,[70,263,264],{},"                                \u002F\u002F The following fields are used to derive the status of the transaction\n",[70,266,268],{"class":72,"line":267},34,[70,269,270],{},"        Height m_confirmHeight; \u002F\u002F height at which the coin was confirmed (appeared in the chain)\n",[70,272,274],{"class":72,"line":273},35,[70,275,276],{},"        Height m_spentHeight;   \u002F\u002F height at which the coin was spent\n",[70,278,280],{"class":72,"line":279},36,[70,281,77],{"emptyLinePlaceholder":76},[70,283,285],{"class":72,"line":284},37,[70,286,287],{},"        boost::optional\u003CTxID> m_createTxId;  \u002F\u002F id of the transaction which created the UTXO\n",[70,289,291],{"class":72,"line":290},38,[70,292,293],{},"        boost::optional\u003CTxID> m_spentTxId;   \u002F\u002F id of the transaction which spernt the UTXO\n",[70,295,297],{"class":72,"line":296},39,[70,298,299],{},"        \n",[70,301,303],{"class":72,"line":302},40,[70,304,305],{},"        uint64_t m_sessionId;   \u002F\u002F Used in the API to lock coins for specific session (see https:\u002F\u002Fgithub.com\u002FBeamMW\u002Fbeam\u002Fwiki\u002FBeam-wallet-protocol-API#tx_split)\n",[70,307,309],{"class":72,"line":308},41,[70,310,77],{"emptyLinePlaceholder":76},[70,312,314],{"class":72,"line":313},42,[70,315,316],{},"        bool IsMaturityValid() const; \u002F\u002F is\u002Fwas the UTXO confirmed?\n",[70,318,320],{"class":72,"line":319},43,[70,321,322],{},"        Height get_Maturity() const; \u002F\u002F would return MaxHeight unless the UTXO was confirmed\n",[70,324,326],{"class":72,"line":325},44,[70,327,299],{},[70,329,331],{"class":72,"line":330},45,[70,332,333],{},"        std::string getStatusString() const;\n",[70,335,337],{"class":72,"line":336},46,[70,338,339],{},"        static boost::optional\u003CCoin::ID> FromString(const std::string& str);\n",[70,341,343],{"class":72,"line":342},47,[70,344,345],{},"    };\n",[347,348,350],"h2",{"id":349},"deducing-coin-status","Deducing Coin Status",[10,352,353,354,357,358,361],{},"By monitoring the state of the blockchain, the wallet can always deduce the current status of each coin by tracking the m_confirmHeight height and m_spentHeight. This is done in the ",[67,355,356],{},"void DeduceStatus(const IWalletDB&, Coin&, Height hTop);"," method which calls the ",[67,359,360],{},"Coin::Status GetCoinStatus(const IWalletDB&, const Coin&, Height hTop);"," method that in turn returns the current status of the coin.",[60,363,365],{"className":62,"code":364,"language":64,"meta":65,"style":65},"\nCoin::Status GetCoinStatus(const IWalletDB& walletDB, const Coin& c, Height hTop)\n{\n    if (c.m_spentHeight != MaxHeight)\n        return Coin::Status::Spent;\n\n    if (c.m_confirmHeight != MaxHeight)\n    {\n        if (c.m_maturity > hTop)\n            return Coin::Status::Maturing;\n\n        if (IsOngoingTx(walletDB, c.m_spentTxId))\n            return Coin::Status::Outgoing;\n\n        return Coin::Status::Available;\n    }\n\n    if (IsOngoingTx(walletDB, c.m_createTxId))\n        return Coin::Status::Incoming;\n\n    return Coin::Status::Unavailable;\n}\n",[67,366,367,371,376,381,386,391,395,400,404,409,414,418,423,428,432,437,442,446,451,456,460,465],{"__ignoreMap":65},[70,368,369],{"class":72,"line":73},[70,370,77],{"emptyLinePlaceholder":76},[70,372,373],{"class":72,"line":80},[70,374,375],{},"Coin::Status GetCoinStatus(const IWalletDB& walletDB, const Coin& c, Height hTop)\n",[70,377,378],{"class":72,"line":86},[70,379,380],{},"{\n",[70,382,383],{"class":72,"line":92},[70,384,385],{},"    if (c.m_spentHeight != MaxHeight)\n",[70,387,388],{"class":72,"line":98},[70,389,390],{},"        return Coin::Status::Spent;\n",[70,392,393],{"class":72,"line":104},[70,394,77],{"emptyLinePlaceholder":76},[70,396,397],{"class":72,"line":110},[70,398,399],{},"    if (c.m_confirmHeight != MaxHeight)\n",[70,401,402],{"class":72,"line":116},[70,403,95],{},[70,405,406],{"class":72,"line":122},[70,407,408],{},"        if (c.m_maturity > hTop)\n",[70,410,411],{"class":72,"line":128},[70,412,413],{},"            return Coin::Status::Maturing;\n",[70,415,416],{"class":72,"line":134},[70,417,77],{"emptyLinePlaceholder":76},[70,419,420],{"class":72,"line":140},[70,421,422],{},"        if (IsOngoingTx(walletDB, c.m_spentTxId))\n",[70,424,425],{"class":72,"line":146},[70,426,427],{},"            return Coin::Status::Outgoing;\n",[70,429,430],{"class":72,"line":152},[70,431,77],{"emptyLinePlaceholder":76},[70,433,434],{"class":72,"line":158},[70,435,436],{},"        return Coin::Status::Available;\n",[70,438,439],{"class":72,"line":164},[70,440,441],{},"    }\n",[70,443,444],{"class":72,"line":169},[70,445,77],{"emptyLinePlaceholder":76},[70,447,448],{"class":72,"line":175},[70,449,450],{},"    if (IsOngoingTx(walletDB, c.m_createTxId))\n",[70,452,453],{"class":72,"line":181},[70,454,455],{},"        return Coin::Status::Incoming;\n",[70,457,458],{"class":72,"line":186},[70,459,77],{"emptyLinePlaceholder":76},[70,461,462],{"class":72,"line":192},[70,463,464],{},"    return Coin::Status::Unavailable;\n",[70,466,467],{"class":72,"line":198},[70,468,469],{},"}\n",[347,471,473],{"id":472},"selecting-coins-for-a-specified-amount","Selecting coins for a specified amount",[10,475,476,477,480,481,484],{},"Implemented in the ",[67,478,479],{},"std::vector\u003CCoin> selectCoins(Amount amount) override;"," method. The purpose of the function is to select Coins matching a specific amount (for example in sending scenario). Selection method should minimize number of Coins and the change outputs and hence use greedy strategy with some additional heuristics. Specific strategies for coin selection are implemented in the ",[67,482,483],{},"struct CoinSelector3"," in honor of three attempts to write an effective selector for large amount of coins.",[486,487,488],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":65,"searchDepth":80,"depth":80,"links":490},[491,492],{"id":349,"depth":80,"text":350},{"id":472,"depth":80,"text":473},"md",null,{},"\u002Fdocs\u002Fcore-tech\u002Fbeam-wallet-database",{"description":12},"docs\u002Fcore-tech\u002FBeam-Wallet-Database","NlujWYZpS2jqu09pGsVuBuy1TLnSEHHRseTedqin3DY",[501,505],{"title":502,"path":503,"stem":504,"description":65,"children":-1},"Beam URI scheme","\u002Fdocs\u002Fcore-tech\u002Fbeam-uri-scheme","docs\u002Fcore-tech\u002FBeam-URI-scheme",{"title":506,"path":507,"stem":508,"description":509,"children":-1},"Beam Web Wallet Starter Kit working draft","\u002Fdocs\u002Fcore-tech\u002Fbeam-web-wallet-starter-kit","docs\u002Fcore-tech\u002FBeam-Web-Wallet-Starter-Kit","Web wallet starter allows you easily integrate Beam with your service, create a bunch of wallets and manage them... (TODO)",1783006060371]