Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F10615296
wallet.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
24 KB
Subscribers
None
wallet.h
View Options
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_WALLET_H
#define BITCOIN_WALLET_H
#include
<string>
#include
<vector>
#include
<stdlib.h>
#include
"main.h"
#include
"key.h"
#include
"keystore.h"
#include
"script.h"
#include
"ui_interface.h"
#include
"util.h"
#include
"walletdb.h"
class
CAccountingEntry
;
class
CWalletTx
;
class
CReserveKey
;
class
COutput
;
/** (client) version numbers for particular wallet features */
enum
WalletFeature
{
FEATURE_BASE
=
10500
,
// the earliest version new wallets supports (only useful for getinfo's clientversion output)
FEATURE_WALLETCRYPT
=
40000
,
// wallet encryption
FEATURE_COMPRPUBKEY
=
60000
,
// compressed public keys
FEATURE_LATEST
=
60000
};
/** A key pool entry */
class
CKeyPool
{
public
:
int64
nTime
;
CPubKey
vchPubKey
;
CKeyPool
()
{
nTime
=
GetTime
();
}
CKeyPool
(
const
CPubKey
&
vchPubKeyIn
)
{
nTime
=
GetTime
();
vchPubKey
=
vchPubKeyIn
;
}
IMPLEMENT_SERIALIZE
(
if
(
!
(
nType
&
SER_GETHASH
))
READWRITE
(
nVersion
);
READWRITE
(
nTime
);
READWRITE
(
vchPubKey
);
)
};
/** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
* and provides the ability to create new transactions.
*/
class
CWallet
:
public
CCryptoKeyStore
{
private
:
bool
SelectCoins
(
int64
nTargetValue
,
std
::
set
<
std
::
pair
<
const
CWalletTx
*
,
unsigned
int
>
>&
setCoinsRet
,
int64
&
nValueRet
)
const
;
CWalletDB
*
pwalletdbEncryption
;
// the current wallet version: clients below this version are not able to load the wallet
int
nWalletVersion
;
// the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
int
nWalletMaxVersion
;
public
:
mutable
CCriticalSection
cs_wallet
;
bool
fFileBacked
;
std
::
string
strWalletFile
;
std
::
set
<
int64
>
setKeyPool
;
typedef
std
::
map
<
unsigned
int
,
CMasterKey
>
MasterKeyMap
;
MasterKeyMap
mapMasterKeys
;
unsigned
int
nMasterKeyMaxID
;
CWallet
()
{
nWalletVersion
=
FEATURE_BASE
;
nWalletMaxVersion
=
FEATURE_BASE
;
fFileBacked
=
false
;
nMasterKeyMaxID
=
0
;
pwalletdbEncryption
=
NULL
;
nOrderPosNext
=
0
;
}
CWallet
(
std
::
string
strWalletFileIn
)
{
nWalletVersion
=
FEATURE_BASE
;
nWalletMaxVersion
=
FEATURE_BASE
;
strWalletFile
=
strWalletFileIn
;
fFileBacked
=
true
;
nMasterKeyMaxID
=
0
;
pwalletdbEncryption
=
NULL
;
nOrderPosNext
=
0
;
}
std
::
map
<
uint256
,
CWalletTx
>
mapWallet
;
int64
nOrderPosNext
;
std
::
map
<
uint256
,
int
>
mapRequestCount
;
std
::
map
<
CTxDestination
,
std
::
string
>
mapAddressBook
;
CPubKey
vchDefaultKey
;
std
::
set
<
COutPoint
>
setLockedCoins
;
// check whether we are allowed to upgrade (or already support) to the named feature
bool
CanSupportFeature
(
enum
WalletFeature
wf
)
{
return
nWalletMaxVersion
>=
wf
;
}
void
AvailableCoins
(
std
::
vector
<
COutput
>&
vCoins
,
bool
fOnlyConfirmed
=
true
)
const
;
bool
SelectCoinsMinConf
(
int64
nTargetValue
,
int
nConfMine
,
int
nConfTheirs
,
std
::
vector
<
COutput
>
vCoins
,
std
::
set
<
std
::
pair
<
const
CWalletTx
*
,
unsigned
int
>
>&
setCoinsRet
,
int64
&
nValueRet
)
const
;
bool
IsLockedCoin
(
uint256
hash
,
unsigned
int
n
)
const
;
void
LockCoin
(
COutPoint
&
output
);
void
UnlockCoin
(
COutPoint
&
output
);
void
UnlockAllCoins
();
void
ListLockedCoins
(
std
::
vector
<
COutPoint
>&
vOutpts
);
// keystore implementation
// Generate a new key
CPubKey
GenerateNewKey
();
// Adds a key to the store, and saves it to disk.
bool
AddKey
(
const
CKey
&
key
);
// Adds a key to the store, without saving it to disk (used by LoadWallet)
bool
LoadKey
(
const
CKey
&
key
)
{
return
CCryptoKeyStore
::
AddKey
(
key
);
}
bool
LoadMinVersion
(
int
nVersion
)
{
nWalletVersion
=
nVersion
;
nWalletMaxVersion
=
std
::
max
(
nWalletMaxVersion
,
nVersion
);
return
true
;
}
// Adds an encrypted key to the store, and saves it to disk.
bool
AddCryptedKey
(
const
CPubKey
&
vchPubKey
,
const
std
::
vector
<
unsigned
char
>
&
vchCryptedSecret
);
// Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
bool
LoadCryptedKey
(
const
CPubKey
&
vchPubKey
,
const
std
::
vector
<
unsigned
char
>
&
vchCryptedSecret
)
{
SetMinVersion
(
FEATURE_WALLETCRYPT
);
return
CCryptoKeyStore
::
AddCryptedKey
(
vchPubKey
,
vchCryptedSecret
);
}
bool
AddCScript
(
const
CScript
&
redeemScript
);
bool
LoadCScript
(
const
CScript
&
redeemScript
)
{
return
CCryptoKeyStore
::
AddCScript
(
redeemScript
);
}
bool
Unlock
(
const
SecureString
&
strWalletPassphrase
);
bool
ChangeWalletPassphrase
(
const
SecureString
&
strOldWalletPassphrase
,
const
SecureString
&
strNewWalletPassphrase
);
bool
EncryptWallet
(
const
SecureString
&
strWalletPassphrase
);
/** Increment the next transaction order id
@return next transaction order id
*/
int64
IncOrderPosNext
(
CWalletDB
*
pwalletdb
=
NULL
);
typedef
std
::
pair
<
CWalletTx
*
,
CAccountingEntry
*>
TxPair
;
typedef
std
::
multimap
<
int64
,
TxPair
>
TxItems
;
/** Get the wallet's activity log
@return multimap of ordered transactions and accounting entries
@warning Returned pointers are *only* valid within the scope of passed acentries
*/
TxItems
OrderedTxItems
(
std
::
list
<
CAccountingEntry
>&
acentries
,
std
::
string
strAccount
=
""
);
void
MarkDirty
();
bool
AddToWallet
(
const
CWalletTx
&
wtxIn
);
bool
AddToWalletIfInvolvingMe
(
const
uint256
&
hash
,
const
CTransaction
&
tx
,
const
CBlock
*
pblock
,
bool
fUpdate
=
false
,
bool
fFindBlock
=
false
);
bool
EraseFromWallet
(
uint256
hash
);
void
WalletUpdateSpent
(
const
CTransaction
&
prevout
);
int
ScanForWalletTransactions
(
CBlockIndex
*
pindexStart
,
bool
fUpdate
=
false
);
void
ReacceptWalletTransactions
();
void
ResendWalletTransactions
();
int64
GetBalance
()
const
;
int64
GetUnconfirmedBalance
()
const
;
int64
GetImmatureBalance
()
const
;
bool
CreateTransaction
(
const
std
::
vector
<
std
::
pair
<
CScript
,
int64
>
>&
vecSend
,
CWalletTx
&
wtxNew
,
CReserveKey
&
reservekey
,
int64
&
nFeeRet
);
bool
CreateTransaction
(
CScript
scriptPubKey
,
int64
nValue
,
CWalletTx
&
wtxNew
,
CReserveKey
&
reservekey
,
int64
&
nFeeRet
);
bool
CommitTransaction
(
CWalletTx
&
wtxNew
,
CReserveKey
&
reservekey
);
std
::
string
SendMoney
(
CScript
scriptPubKey
,
int64
nValue
,
CWalletTx
&
wtxNew
,
bool
fAskFee
=
false
);
std
::
string
SendMoneyToDestination
(
const
CTxDestination
&
address
,
int64
nValue
,
CWalletTx
&
wtxNew
,
bool
fAskFee
=
false
);
bool
NewKeyPool
();
bool
TopUpKeyPool
();
int64
AddReserveKey
(
const
CKeyPool
&
keypool
);
void
ReserveKeyFromKeyPool
(
int64
&
nIndex
,
CKeyPool
&
keypool
);
void
KeepKey
(
int64
nIndex
);
void
ReturnKey
(
int64
nIndex
);
bool
GetKeyFromPool
(
CPubKey
&
key
,
bool
fAllowReuse
=
true
);
int64
GetOldestKeyPoolTime
();
void
GetAllReserveKeys
(
std
::
set
<
CKeyID
>&
setAddress
);
std
::
set
<
std
::
set
<
CTxDestination
>
>
GetAddressGroupings
();
std
::
map
<
CTxDestination
,
int64
>
GetAddressBalances
();
bool
IsMine
(
const
CTxIn
&
txin
)
const
;
int64
GetDebit
(
const
CTxIn
&
txin
)
const
;
bool
IsMine
(
const
CTxOut
&
txout
)
const
{
return
::
IsMine
(
*
this
,
txout
.
scriptPubKey
);
}
int64
GetCredit
(
const
CTxOut
&
txout
)
const
{
if
(
!
MoneyRange
(
txout
.
nValue
))
throw
std
::
runtime_error
(
"CWallet::GetCredit() : value out of range"
);
return
(
IsMine
(
txout
)
?
txout
.
nValue
:
0
);
}
bool
IsChange
(
const
CTxOut
&
txout
)
const
;
int64
GetChange
(
const
CTxOut
&
txout
)
const
{
if
(
!
MoneyRange
(
txout
.
nValue
))
throw
std
::
runtime_error
(
"CWallet::GetChange() : value out of range"
);
return
(
IsChange
(
txout
)
?
txout
.
nValue
:
0
);
}
bool
IsMine
(
const
CTransaction
&
tx
)
const
{
BOOST_FOREACH
(
const
CTxOut
&
txout
,
tx
.
vout
)
if
(
IsMine
(
txout
))
return
true
;
return
false
;
}
bool
IsFromMe
(
const
CTransaction
&
tx
)
const
{
return
(
GetDebit
(
tx
)
>
0
);
}
int64
GetDebit
(
const
CTransaction
&
tx
)
const
{
int64
nDebit
=
0
;
BOOST_FOREACH
(
const
CTxIn
&
txin
,
tx
.
vin
)
{
nDebit
+=
GetDebit
(
txin
);
if
(
!
MoneyRange
(
nDebit
))
throw
std
::
runtime_error
(
"CWallet::GetDebit() : value out of range"
);
}
return
nDebit
;
}
int64
GetCredit
(
const
CTransaction
&
tx
)
const
{
int64
nCredit
=
0
;
BOOST_FOREACH
(
const
CTxOut
&
txout
,
tx
.
vout
)
{
nCredit
+=
GetCredit
(
txout
);
if
(
!
MoneyRange
(
nCredit
))
throw
std
::
runtime_error
(
"CWallet::GetCredit() : value out of range"
);
}
return
nCredit
;
}
int64
GetChange
(
const
CTransaction
&
tx
)
const
{
int64
nChange
=
0
;
BOOST_FOREACH
(
const
CTxOut
&
txout
,
tx
.
vout
)
{
nChange
+=
GetChange
(
txout
);
if
(
!
MoneyRange
(
nChange
))
throw
std
::
runtime_error
(
"CWallet::GetChange() : value out of range"
);
}
return
nChange
;
}
void
SetBestChain
(
const
CBlockLocator
&
loc
);
DBErrors
LoadWallet
(
bool
&
fFirstRunRet
);
bool
SetAddressBookName
(
const
CTxDestination
&
address
,
const
std
::
string
&
strName
);
bool
DelAddressBookName
(
const
CTxDestination
&
address
);
void
UpdatedTransaction
(
const
uint256
&
hashTx
);
void
PrintWallet
(
const
CBlock
&
block
);
void
Inventory
(
const
uint256
&
hash
)
{
{
LOCK
(
cs_wallet
);
std
::
map
<
uint256
,
int
>::
iterator
mi
=
mapRequestCount
.
find
(
hash
);
if
(
mi
!=
mapRequestCount
.
end
())
(
*
mi
).
second
++
;
}
}
int
GetKeyPoolSize
()
{
return
setKeyPool
.
size
();
}
bool
GetTransaction
(
const
uint256
&
hashTx
,
CWalletTx
&
wtx
);
bool
SetDefaultKey
(
const
CPubKey
&
vchPubKey
);
// signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
bool
SetMinVersion
(
enum
WalletFeature
,
CWalletDB
*
pwalletdbIn
=
NULL
,
bool
fExplicit
=
false
);
// change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
bool
SetMaxVersion
(
int
nVersion
);
// get the current wallet format (the oldest client version guaranteed to understand this wallet)
int
GetVersion
()
{
return
nWalletVersion
;
}
/** Address book entry changed.
* @note called with lock cs_wallet held.
*/
boost
::
signals2
::
signal
<
void
(
CWallet
*
wallet
,
const
CTxDestination
&
address
,
const
std
::
string
&
label
,
bool
isMine
,
ChangeType
status
)
>
NotifyAddressBookChanged
;
/** Wallet transaction added, removed or updated.
* @note called with lock cs_wallet held.
*/
boost
::
signals2
::
signal
<
void
(
CWallet
*
wallet
,
const
uint256
&
hashTx
,
ChangeType
status
)
>
NotifyTransactionChanged
;
};
/** A key allocated from the key pool. */
class
CReserveKey
{
protected
:
CWallet
*
pwallet
;
int64
nIndex
;
CPubKey
vchPubKey
;
public
:
CReserveKey
(
CWallet
*
pwalletIn
)
{
nIndex
=
-1
;
pwallet
=
pwalletIn
;
}
~
CReserveKey
()
{
ReturnKey
();
}
void
ReturnKey
();
CPubKey
GetReservedKey
();
void
KeepKey
();
};
typedef
std
::
map
<
std
::
string
,
std
::
string
>
mapValue_t
;
static
void
ReadOrderPos
(
int64
&
nOrderPos
,
mapValue_t
&
mapValue
)
{
if
(
!
mapValue
.
count
(
"n"
))
{
nOrderPos
=
-1
;
// TODO: calculate elsewhere
return
;
}
nOrderPos
=
atoi64
(
mapValue
[
"n"
].
c_str
());
}
static
void
WriteOrderPos
(
const
int64
&
nOrderPos
,
mapValue_t
&
mapValue
)
{
if
(
nOrderPos
==
-1
)
return
;
mapValue
[
"n"
]
=
i64tostr
(
nOrderPos
);
}
/** A transaction with a bunch of additional info that only the owner cares about.
* It includes any unrecorded transactions needed to link it back to the block chain.
*/
class
CWalletTx
:
public
CMerkleTx
{
private
:
const
CWallet
*
pwallet
;
public
:
std
::
vector
<
CMerkleTx
>
vtxPrev
;
mapValue_t
mapValue
;
std
::
vector
<
std
::
pair
<
std
::
string
,
std
::
string
>
>
vOrderForm
;
unsigned
int
fTimeReceivedIsTxTime
;
unsigned
int
nTimeReceived
;
// time received by this node
unsigned
int
nTimeSmart
;
char
fFromMe
;
std
::
string
strFromAccount
;
std
::
vector
<
char
>
vfSpent
;
// which outputs are already spent
int64
nOrderPos
;
// position in ordered transaction list
// memory only
mutable
bool
fDebitCached
;
mutable
bool
fCreditCached
;
mutable
bool
fImmatureCreditCached
;
mutable
bool
fAvailableCreditCached
;
mutable
bool
fChangeCached
;
mutable
int64
nDebitCached
;
mutable
int64
nCreditCached
;
mutable
int64
nImmatureCreditCached
;
mutable
int64
nAvailableCreditCached
;
mutable
int64
nChangeCached
;
CWalletTx
()
{
Init
(
NULL
);
}
CWalletTx
(
const
CWallet
*
pwalletIn
)
{
Init
(
pwalletIn
);
}
CWalletTx
(
const
CWallet
*
pwalletIn
,
const
CMerkleTx
&
txIn
)
:
CMerkleTx
(
txIn
)
{
Init
(
pwalletIn
);
}
CWalletTx
(
const
CWallet
*
pwalletIn
,
const
CTransaction
&
txIn
)
:
CMerkleTx
(
txIn
)
{
Init
(
pwalletIn
);
}
void
Init
(
const
CWallet
*
pwalletIn
)
{
pwallet
=
pwalletIn
;
vtxPrev
.
clear
();
mapValue
.
clear
();
vOrderForm
.
clear
();
fTimeReceivedIsTxTime
=
false
;
nTimeReceived
=
0
;
nTimeSmart
=
0
;
fFromMe
=
false
;
strFromAccount
.
clear
();
vfSpent
.
clear
();
fDebitCached
=
false
;
fCreditCached
=
false
;
fImmatureCreditCached
=
false
;
fAvailableCreditCached
=
false
;
fChangeCached
=
false
;
nDebitCached
=
0
;
nCreditCached
=
0
;
nImmatureCreditCached
=
0
;
nAvailableCreditCached
=
0
;
nChangeCached
=
0
;
nOrderPos
=
-1
;
}
IMPLEMENT_SERIALIZE
(
CWalletTx
*
pthis
=
const_cast
<
CWalletTx
*>
(
this
);
if
(
fRead
)
pthis
->
Init
(
NULL
);
char
fSpent
=
false
;
if
(
!
fRead
)
{
pthis
->
mapValue
[
"fromaccount"
]
=
pthis
->
strFromAccount
;
std
::
string
str
;
BOOST_FOREACH
(
char
f
,
vfSpent
)
{
str
+=
(
f
?
'1'
:
'0'
);
if
(
f
)
fSpent
=
true
;
}
pthis
->
mapValue
[
"spent"
]
=
str
;
WriteOrderPos
(
pthis
->
nOrderPos
,
pthis
->
mapValue
);
if
(
nTimeSmart
)
pthis
->
mapValue
[
"timesmart"
]
=
strprintf
(
"%u"
,
nTimeSmart
);
}
nSerSize
+=
SerReadWrite
(
s
,
*
(
CMerkleTx
*
)
this
,
nType
,
nVersion
,
ser_action
);
READWRITE
(
vtxPrev
);
READWRITE
(
mapValue
);
READWRITE
(
vOrderForm
);
READWRITE
(
fTimeReceivedIsTxTime
);
READWRITE
(
nTimeReceived
);
READWRITE
(
fFromMe
);
READWRITE
(
fSpent
);
if
(
fRead
)
{
pthis
->
strFromAccount
=
pthis
->
mapValue
[
"fromaccount"
];
if
(
mapValue
.
count
(
"spent"
))
BOOST_FOREACH
(
char
c
,
pthis
->
mapValue
[
"spent"
])
pthis
->
vfSpent
.
push_back
(
c
!=
'0'
);
else
pthis
->
vfSpent
.
assign
(
vout
.
size
(),
fSpent
);
ReadOrderPos
(
pthis
->
nOrderPos
,
pthis
->
mapValue
);
pthis
->
nTimeSmart
=
mapValue
.
count
(
"timesmart"
)
?
(
unsigned
int
)
atoi64
(
pthis
->
mapValue
[
"timesmart"
])
:
0
;
}
pthis
->
mapValue
.
erase
(
"fromaccount"
);
pthis
->
mapValue
.
erase
(
"version"
);
pthis
->
mapValue
.
erase
(
"spent"
);
pthis
->
mapValue
.
erase
(
"n"
);
pthis
->
mapValue
.
erase
(
"timesmart"
);
)
// marks certain txout's as spent
// returns true if any update took place
bool
UpdateSpent
(
const
std
::
vector
<
char
>&
vfNewSpent
)
{
bool
fReturn
=
false
;
for
(
unsigned
int
i
=
0
;
i
<
vfNewSpent
.
size
();
i
++
)
{
if
(
i
==
vfSpent
.
size
())
break
;
if
(
vfNewSpent
[
i
]
&&
!
vfSpent
[
i
])
{
vfSpent
[
i
]
=
true
;
fReturn
=
true
;
fAvailableCreditCached
=
false
;
}
}
return
fReturn
;
}
// make sure balances are recalculated
void
MarkDirty
()
{
fCreditCached
=
false
;
fAvailableCreditCached
=
false
;
fDebitCached
=
false
;
fChangeCached
=
false
;
}
void
BindWallet
(
CWallet
*
pwalletIn
)
{
pwallet
=
pwalletIn
;
MarkDirty
();
}
void
MarkSpent
(
unsigned
int
nOut
)
{
if
(
nOut
>=
vout
.
size
())
throw
std
::
runtime_error
(
"CWalletTx::MarkSpent() : nOut out of range"
);
vfSpent
.
resize
(
vout
.
size
());
if
(
!
vfSpent
[
nOut
])
{
vfSpent
[
nOut
]
=
true
;
fAvailableCreditCached
=
false
;
}
}
bool
IsSpent
(
unsigned
int
nOut
)
const
{
if
(
nOut
>=
vout
.
size
())
throw
std
::
runtime_error
(
"CWalletTx::IsSpent() : nOut out of range"
);
if
(
nOut
>=
vfSpent
.
size
())
return
false
;
return
(
!!
vfSpent
[
nOut
]);
}
int64
GetDebit
()
const
{
if
(
vin
.
empty
())
return
0
;
if
(
fDebitCached
)
return
nDebitCached
;
nDebitCached
=
pwallet
->
GetDebit
(
*
this
);
fDebitCached
=
true
;
return
nDebitCached
;
}
int64
GetCredit
(
bool
fUseCache
=
true
)
const
{
// Must wait until coinbase is safely deep enough in the chain before valuing it
if
(
IsCoinBase
()
&&
GetBlocksToMaturity
()
>
0
)
return
0
;
// GetBalance can assume transactions in mapWallet won't change
if
(
fUseCache
&&
fCreditCached
)
return
nCreditCached
;
nCreditCached
=
pwallet
->
GetCredit
(
*
this
);
fCreditCached
=
true
;
return
nCreditCached
;
}
int64
GetImmatureCredit
(
bool
fUseCache
=
true
)
const
{
if
(
IsCoinBase
()
&&
GetBlocksToMaturity
()
>
0
&&
IsInMainChain
())
{
if
(
fUseCache
&&
fImmatureCreditCached
)
return
nImmatureCreditCached
;
nImmatureCreditCached
=
pwallet
->
GetCredit
(
*
this
);
fImmatureCreditCached
=
true
;
return
nImmatureCreditCached
;
}
return
0
;
}
int64
GetAvailableCredit
(
bool
fUseCache
=
true
)
const
{
// Must wait until coinbase is safely deep enough in the chain before valuing it
if
(
IsCoinBase
()
&&
GetBlocksToMaturity
()
>
0
)
return
0
;
if
(
fUseCache
&&
fAvailableCreditCached
)
return
nAvailableCreditCached
;
int64
nCredit
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
vout
.
size
();
i
++
)
{
if
(
!
IsSpent
(
i
))
{
const
CTxOut
&
txout
=
vout
[
i
];
nCredit
+=
pwallet
->
GetCredit
(
txout
);
if
(
!
MoneyRange
(
nCredit
))
throw
std
::
runtime_error
(
"CWalletTx::GetAvailableCredit() : value out of range"
);
}
}
nAvailableCreditCached
=
nCredit
;
fAvailableCreditCached
=
true
;
return
nCredit
;
}
int64
GetChange
()
const
{
if
(
fChangeCached
)
return
nChangeCached
;
nChangeCached
=
pwallet
->
GetChange
(
*
this
);
fChangeCached
=
true
;
return
nChangeCached
;
}
void
GetAmounts
(
std
::
list
<
std
::
pair
<
CTxDestination
,
int64
>
>&
listReceived
,
std
::
list
<
std
::
pair
<
CTxDestination
,
int64
>
>&
listSent
,
int64
&
nFee
,
std
::
string
&
strSentAccount
)
const
;
void
GetAccountAmounts
(
const
std
::
string
&
strAccount
,
int64
&
nReceived
,
int64
&
nSent
,
int64
&
nFee
)
const
;
bool
IsFromMe
()
const
{
return
(
GetDebit
()
>
0
);
}
bool
IsConfirmed
()
const
{
// Quick answer in most cases
if
(
!
IsFinal
())
return
false
;
if
(
GetDepthInMainChain
()
>=
1
)
return
true
;
if
(
!
IsFromMe
())
// using wtx's cached debit
return
false
;
// If no confirmations but it's from us, we can still
// consider it confirmed if all dependencies are confirmed
std
::
map
<
uint256
,
const
CMerkleTx
*>
mapPrev
;
std
::
vector
<
const
CMerkleTx
*>
vWorkQueue
;
vWorkQueue
.
reserve
(
vtxPrev
.
size
()
+
1
);
vWorkQueue
.
push_back
(
this
);
for
(
unsigned
int
i
=
0
;
i
<
vWorkQueue
.
size
();
i
++
)
{
const
CMerkleTx
*
ptx
=
vWorkQueue
[
i
];
if
(
!
ptx
->
IsFinal
())
return
false
;
if
(
ptx
->
GetDepthInMainChain
()
>=
1
)
continue
;
if
(
!
pwallet
->
IsFromMe
(
*
ptx
))
return
false
;
if
(
mapPrev
.
empty
())
{
BOOST_FOREACH
(
const
CMerkleTx
&
tx
,
vtxPrev
)
mapPrev
[
tx
.
GetHash
()]
=
&
tx
;
}
BOOST_FOREACH
(
const
CTxIn
&
txin
,
ptx
->
vin
)
{
if
(
!
mapPrev
.
count
(
txin
.
prevout
.
hash
))
return
false
;
vWorkQueue
.
push_back
(
mapPrev
[
txin
.
prevout
.
hash
]);
}
}
return
true
;
}
bool
WriteToDisk
();
int64
GetTxTime
()
const
;
int
GetRequestCount
()
const
;
void
AddSupportingTransactions
();
bool
AcceptWalletTransaction
(
bool
fCheckInputs
=
true
);
void
RelayWalletTransaction
();
};
class
COutput
{
public
:
const
CWalletTx
*
tx
;
int
i
;
int
nDepth
;
COutput
(
const
CWalletTx
*
txIn
,
int
iIn
,
int
nDepthIn
)
{
tx
=
txIn
;
i
=
iIn
;
nDepth
=
nDepthIn
;
}
std
::
string
ToString
()
const
{
return
strprintf
(
"COutput(%s, %d, %d)
[
%
s
]
", tx->GetHash().ToString().c_str(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str())
;
}
void
print
()
const
{
printf
(
"%s
\n
"
,
ToString
().
c_str
());
}
};
/** Private key that includes an expiration date in case it never gets used. */
class
CWalletKey
{
public
:
CPrivKey
vchPrivKey
;
int64
nTimeCreated
;
int64
nTimeExpires
;
std
::
string
strComment
;
//// todo: add something to note what created it (user, getnewaddress, change)
//// maybe should have a map<string, string> property map
CWalletKey
(
int64
nExpires
=
0
)
{
nTimeCreated
=
(
nExpires
?
GetTime
()
:
0
);
nTimeExpires
=
nExpires
;
}
IMPLEMENT_SERIALIZE
(
if
(
!
(
nType
&
SER_GETHASH
))
READWRITE
(
nVersion
);
READWRITE
(
vchPrivKey
);
READWRITE
(
nTimeCreated
);
READWRITE
(
nTimeExpires
);
READWRITE
(
strComment
);
)
};
/** Account information.
* Stored in wallet with key "acc"+string account name.
*/
class
CAccount
{
public
:
CPubKey
vchPubKey
;
CAccount
()
{
SetNull
();
}
void
SetNull
()
{
vchPubKey
=
CPubKey
();
}
IMPLEMENT_SERIALIZE
(
if
(
!
(
nType
&
SER_GETHASH
))
READWRITE
(
nVersion
);
READWRITE
(
vchPubKey
);
)
};
/** Internal transfers.
* Database key is acentry<account><counter>.
*/
class
CAccountingEntry
{
public
:
std
::
string
strAccount
;
int64
nCreditDebit
;
int64
nTime
;
std
::
string
strOtherAccount
;
std
::
string
strComment
;
mapValue_t
mapValue
;
int64
nOrderPos
;
// position in ordered transaction list
uint64
nEntryNo
;
CAccountingEntry
()
{
SetNull
();
}
void
SetNull
()
{
nCreditDebit
=
0
;
nTime
=
0
;
strAccount
.
clear
();
strOtherAccount
.
clear
();
strComment
.
clear
();
nOrderPos
=
-1
;
}
IMPLEMENT_SERIALIZE
(
CAccountingEntry
&
me
=
*
const_cast
<
CAccountingEntry
*>
(
this
);
if
(
!
(
nType
&
SER_GETHASH
))
READWRITE
(
nVersion
);
// Note: strAccount is serialized as part of the key, not here.
READWRITE
(
nCreditDebit
);
READWRITE
(
nTime
);
READWRITE
(
strOtherAccount
);
if
(
!
fRead
)
{
WriteOrderPos
(
nOrderPos
,
me
.
mapValue
);
if
(
!
(
mapValue
.
empty
()
&&
_ssExtra
.
empty
()))
{
CDataStream
ss
(
nType
,
nVersion
);
ss
.
insert
(
ss
.
begin
(),
'\0'
);
ss
<<
mapValue
;
ss
.
insert
(
ss
.
end
(),
_ssExtra
.
begin
(),
_ssExtra
.
end
());
me
.
strComment
.
append
(
ss
.
str
());
}
}
READWRITE
(
strComment
);
size_t
nSepPos
=
strComment
.
find
(
"
\0
"
,
0
,
1
);
if
(
fRead
)
{
me
.
mapValue
.
clear
();
if
(
std
::
string
::
npos
!=
nSepPos
)
{
CDataStream
ss
(
std
::
vector
<
char
>
(
strComment
.
begin
()
+
nSepPos
+
1
,
strComment
.
end
()),
nType
,
nVersion
);
ss
>>
me
.
mapValue
;
me
.
_ssExtra
=
std
::
vector
<
char
>
(
ss
.
begin
(),
ss
.
end
());
}
ReadOrderPos
(
me
.
nOrderPos
,
me
.
mapValue
);
}
if
(
std
::
string
::
npos
!=
nSepPos
)
me
.
strComment
.
erase
(
nSepPos
);
me
.
mapValue
.
erase
(
"n"
);
)
private
:
std
::
vector
<
char
>
_ssExtra
;
};
bool
GetWalletFile
(
CWallet
*
pwallet
,
std
::
string
&
strWalletFileOut
);
#endif
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sat, Nov 23, 10:04 (22 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4520001
Default Alt Text
wallet.h (24 KB)
Attached To
rSTAGING Bitcoin ABC staging
Event Timeline
Log In to Comment