Merge branch 'master' into async-ipv6-rpc
Conflicts: src/bitcoinrpc.cpp Signed-off-by: Giel van Schijndel <me@mortis.eu>
This commit is contained in:
commit
07368a9e3c
123 changed files with 41314 additions and 24934 deletions
|
@ -234,7 +234,8 @@ FORMS += \
|
|||
src/qt/forms/sendcoinsentry.ui \
|
||||
src/qt/forms/askpassphrasedialog.ui \
|
||||
src/qt/forms/rpcconsole.ui \
|
||||
src/qt/forms/verifymessagedialog.ui
|
||||
src/qt/forms/verifymessagedialog.ui \
|
||||
src/qt/forms/optionsdialog.ui
|
||||
|
||||
contains(USE_QRCODE, 1) {
|
||||
HEADERS += src/qt/qrcodedialog.h
|
||||
|
|
115
contrib/bitcoind.bash-completion
Normal file
115
contrib/bitcoind.bash-completion
Normal file
|
@ -0,0 +1,115 @@
|
|||
# bash programmable completion for bitcoind(1)
|
||||
# Copyright (c) 2012 Christian von Roques <roques@mti.ag>
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
have bitcoind && {
|
||||
|
||||
# call $bitcoind for RPC
|
||||
_bitcoin_rpc() {
|
||||
# determine already specified args necessary for RPC
|
||||
local rpcargs=()
|
||||
for i in ${COMP_LINE}; do
|
||||
case "$i" in
|
||||
-conf=*|-proxy*|-rpc*)
|
||||
rpcargs=( "${rpcargs[@]}" "$i" )
|
||||
;;
|
||||
esac
|
||||
done
|
||||
$bitcoind "${rpcargs[@]}" "$@"
|
||||
}
|
||||
|
||||
# Add bitcoin accounts to COMPREPLY
|
||||
_bitcoin_accounts() {
|
||||
local accounts
|
||||
accounts=$(_bitcoin_rpc listaccounts | awk '/".*"/ { a=$1; gsub(/"/, "", a); print a}')
|
||||
COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) )
|
||||
}
|
||||
|
||||
_bitcoind() {
|
||||
local cur prev words=() cword
|
||||
local bitcoind
|
||||
|
||||
# save and use original argument to invoke bitcoind
|
||||
# bitcoind might not be in $PATH
|
||||
bitcoind="$1"
|
||||
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref -n = cur prev words cword
|
||||
|
||||
if ((cword > 2)); then
|
||||
case ${words[cword-2]} in
|
||||
listreceivedbyaccount|listreceivedbyaddress)
|
||||
COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
|
||||
return 0
|
||||
;;
|
||||
move|setaccount)
|
||||
_bitcoin_accounts
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case "$prev" in
|
||||
backupwallet)
|
||||
_filedir
|
||||
return 0
|
||||
;;
|
||||
setgenerate)
|
||||
COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
|
||||
return 0
|
||||
;;
|
||||
getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany)
|
||||
_bitcoin_accounts
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$cur" in
|
||||
-conf=*|-pid=*|-rpcsslcertificatechainfile=*|-rpcsslprivatekeyfile=*)
|
||||
cur="${cur#*=}"
|
||||
_filedir
|
||||
return 0
|
||||
;;
|
||||
-datadir=*)
|
||||
cur="${cur#*=}"
|
||||
_filedir -d
|
||||
return 0
|
||||
;;
|
||||
-*=*) # prevent nonsense completions
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
local helpopts commands
|
||||
|
||||
# only parse --help if senseful
|
||||
if [[ -z "$cur" || "$cur" =~ ^- ]]; then
|
||||
helpopts=$($bitcoind --help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' )
|
||||
fi
|
||||
|
||||
# only parse help if senseful
|
||||
if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then
|
||||
commands=$(_bitcoin_rpc help 2>/dev/null | awk '{ print $1; }')
|
||||
fi
|
||||
|
||||
COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) )
|
||||
|
||||
# Prevent space if an argument is desired
|
||||
if [[ $COMPREPLY == *= ]]; then
|
||||
compopt -o nospace
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
complete -F _bitcoind bitcoind
|
||||
}
|
||||
|
||||
# Local variables:
|
||||
# mode: shell-script
|
||||
# sh-basic-offset: 4
|
||||
# sh-indent-comment: t
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
# ex: ts=4 sw=4 et filetype=sh
|
|
@ -1,16 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
umask 077
|
||||
|
||||
basedir=~/.bitcoin
|
||||
dbfile="$basedir/DB_CONFIG"
|
||||
cfgfile="$basedir/bitcoin.conf"
|
||||
|
||||
[ -e "$basedir" ] || mkdir "$basedir"
|
||||
|
||||
# Bitcoin does not clean up DB log files by default
|
||||
[ -e "$dbfile" ] || echo 'set_flags DB_LOG_AUTOREMOVE' > "$dbfile"
|
||||
|
||||
exec /usr/lib/bitcoin/bitcoin-qt "$@"
|
|
@ -5,14 +5,10 @@ set -e
|
|||
umask 077
|
||||
|
||||
basedir=~/.bitcoin
|
||||
dbfile="$basedir/DB_CONFIG"
|
||||
cfgfile="$basedir/bitcoin.conf"
|
||||
|
||||
[ -e "$basedir" ] || mkdir "$basedir"
|
||||
|
||||
[ -e "$cfgfile" ] || perl -le 'print"rpcpassword=",map{(a..z,A..Z,0..9)[rand 62]}0..9' > "$cfgfile"
|
||||
|
||||
# Bitcoin does not clean up DB log files by default
|
||||
[ -e "$dbfile" ] || echo 'set_flags DB_LOG_AUTOREMOVE' > "$dbfile"
|
||||
|
||||
exec /usr/lib/bitcoin/bitcoind "$@"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
debian/bin/bitcoin-qt usr/bin
|
||||
bitcoin-qt usr/lib/bitcoin
|
||||
bitcoin-qt usr/bin
|
||||
share/pixmaps/bitcoin32.xpm usr/share/pixmaps
|
||||
share/pixmaps/bitcoin80.xpm usr/share/pixmaps
|
||||
debian/bitcoin-qt.desktop usr/share/applications
|
||||
|
|
1
contrib/debian/bitcoind.bash-completion
Normal file
1
contrib/debian/bitcoind.bash-completion
Normal file
|
@ -0,0 +1 @@
|
|||
contrib/bitcoind.bash-completion bitcoind
|
|
@ -1,3 +1,15 @@
|
|||
bitcoin (0.6.2-natty1) natty; urgency=low
|
||||
|
||||
* Update package description and launch scripts.
|
||||
|
||||
-- Matt Corallo <matt@bluematt.me> Sat, 2 Jun 2012 16:41:00 +0200
|
||||
|
||||
bitcoin (0.6.2-natty0) natty; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
||||
-- Matt Corallo <matt@bluematt.me> Tue, 8 May 2012 16:27:00 -0500
|
||||
|
||||
bitcoin (0.6.1-natty0) natty; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
|
|
|
@ -5,6 +5,7 @@ Maintainer: Jonas Smedegaard <dr@jones.dk>
|
|||
Uploaders: Micah Anderson <micah@debian.org>
|
||||
Build-Depends: debhelper,
|
||||
devscripts,
|
||||
bash-completion,
|
||||
libboost-system-dev (>> 1.35) | libboost-system1.35-dev,
|
||||
libdb4.8++-dev,
|
||||
libssl-dev,
|
||||
|
@ -35,7 +36,7 @@ Description: peer-to-peer network based digital currency - daemon
|
|||
By default connects to an IRC network to discover other peers.
|
||||
.
|
||||
Full transaction history is stored locally at each client. This
|
||||
requires 150+ MB of space, slowly growing.
|
||||
requires 2+ GB of space, slowly growing.
|
||||
.
|
||||
This package provides bitcoind, a combined daemon and CLI tool to
|
||||
interact with the daemon.
|
||||
|
@ -53,6 +54,6 @@ Description: peer-to-peer network based digital currency - QT GUI
|
|||
By default connects to an IRC network to discover other peers.
|
||||
.
|
||||
Full transaction history is stored locally at each client. This
|
||||
requires 150+ MB of space, slowly growing.
|
||||
requires 2+ GB of space, slowly growing.
|
||||
.
|
||||
This package provides bitcoin-qt, a GUI for Bitcoin based on QT.
|
||||
|
|
|
@ -9,7 +9,7 @@ DEB_INSTALL_EXAMPLES_bitcoind += debian/examples/*
|
|||
DEB_INSTALL_MANPAGES_bitcoind += debian/manpages/*
|
||||
|
||||
%:
|
||||
dh $@
|
||||
dh --with bash-completion $@
|
||||
|
||||
override_dh_auto_build:
|
||||
cd src; $(MAKE) -f makefile.unix bitcoind
|
||||
|
|
|
@ -31,7 +31,7 @@ signers:
|
|||
weight: 40
|
||||
name: "Gavin Andresen"
|
||||
key: gavinandresen
|
||||
71A3B16735405025D447E8F274810B012346C9A6
|
||||
71A3B16735405025D447E8F274810B012346C9A6:
|
||||
weight: 40
|
||||
name: "Wladimir J. van der Laan"
|
||||
key: laanwj
|
||||
|
|
|
@ -31,7 +31,7 @@ signers:
|
|||
weight: 40
|
||||
name: "Gavin Andresen"
|
||||
key: gavinandresen
|
||||
71A3B16735405025D447E8F274810B012346C9A6
|
||||
71A3B16735405025D447E8F274810B012346C9A6:
|
||||
weight: 40
|
||||
name: "Wladimir J. van der Laan"
|
||||
key: laanwj
|
||||
|
|
|
@ -24,7 +24,7 @@ Dependencies
|
|||
Libraries you need to download separately and build:
|
||||
|
||||
default path download
|
||||
OpenSSL \openssl-1.0.1b-mgw http://www.openssl.org/source/
|
||||
OpenSSL \openssl-1.0.1d-mgw http://www.openssl.org/source/
|
||||
Berkeley DB \db-4.8.30.NC-mgw http://www.oracle.com/technology/software/products/berkeley-db/index.html
|
||||
Boost \boost-1.47.0-mgw http://www.boost.org/users/download/
|
||||
miniupnpc \miniupnpc-1.6-mgw http://miniupnp.tuxfamily.org/files/
|
||||
|
@ -36,7 +36,7 @@ Boost MIT-like license
|
|||
miniupnpc New (3-clause) BSD license
|
||||
|
||||
Versions used in this release:
|
||||
OpenSSL 1.0.1b
|
||||
OpenSSL 1.0.1d
|
||||
Berkeley DB 4.8.30.NC
|
||||
Boost 1.47.0
|
||||
miniupnpc 1.6
|
||||
|
@ -48,7 +48,7 @@ MSYS shell:
|
|||
un-tar sources with MSYS 'tar xfz' to avoid issue with symlinks (OpenSSL ticket 2377)
|
||||
change 'MAKE' env. variable from 'C:\MinGW32\bin\mingw32-make.exe' to '/c/MinGW32/bin/mingw32-make.exe'
|
||||
|
||||
cd /c/openssl-1.0.1b-mgw
|
||||
cd /c/openssl-1.0.1d-mgw
|
||||
./config
|
||||
make
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ Dependencies
|
|||
miniupnpc may be used for UPnP port mapping. It can be downloaded from
|
||||
http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and
|
||||
turned off by default. Set USE_UPNP to a different value to control this:
|
||||
USE_UPNP= No UPnP support - miniupnp not required
|
||||
USE_UPNP=- No UPnP support - miniupnp not required
|
||||
USE_UPNP=0 (the default) UPnP support turned off by default at runtime
|
||||
USE_UPNP=1 UPnP support turned on by default at runtime
|
||||
|
||||
|
|
|
@ -99,6 +99,8 @@
|
|||
|
||||
* update wiki download links
|
||||
|
||||
* update wiki changelog: https://en.bitcoin.it/wiki/Changelog
|
||||
|
||||
* Commit your signature to gitian.sigs:
|
||||
pushd gitian.sigs
|
||||
git add ${VERSION}/${SIGNER}
|
||||
|
|
33
doc/unit-tests.txt
Normal file
33
doc/unit-tests.txt
Normal file
|
@ -0,0 +1,33 @@
|
|||
Compiling/runing bitcoind unit tests
|
||||
------------------------------------
|
||||
|
||||
bitcoind unit tests are in the src/test/ directory; they
|
||||
use the Boost::Test unit-testing framework.
|
||||
|
||||
To compile and run the tests:
|
||||
cd src
|
||||
make -f makefile.unix test_bitcoin # Replace makefile.unix if you're not on unix
|
||||
./test_bitcoin # Runs the unit tests
|
||||
|
||||
If all tests succeed the last line of output will be:
|
||||
*** No errors detected
|
||||
|
||||
To add more tests, add BOOST_AUTO_TEST_CASE's to the existing
|
||||
.cpp files in the test/ directory or add new .cpp files that
|
||||
implement new BOOST_AUTO_TEST_SUITE's (the makefiles are
|
||||
set up to add test/*.cpp to test_bitcoin automatically).
|
||||
|
||||
|
||||
Compiling/running Bitcoin-Qt unit tests
|
||||
---------------------------------------
|
||||
|
||||
Bitcoin-Qt unit tests are in the src/qt/test/ directory; they
|
||||
use the Qt unit-testing framework.
|
||||
|
||||
To compile and run the tests:
|
||||
qmake bitcoin-qt.pro BITCOIN_QT_TEST=1
|
||||
make
|
||||
./bitcoin-qt_test
|
||||
|
||||
To add more tests, add them to the src/qt/test/ directory,
|
||||
the src/qt/test/test_main.cpp file, and bitcoin-qt.pro.
|
|
@ -5,6 +5,7 @@ they can be picked up by Qt linguist.
|
|||
'''
|
||||
from subprocess import Popen, PIPE
|
||||
import glob
|
||||
import operator
|
||||
|
||||
OUT_CPP="src/qt/bitcoinstrings.cpp"
|
||||
EMPTY=['""']
|
||||
|
@ -62,7 +63,8 @@ f.write("""#include <QtGlobal>
|
|||
#define UNUSED
|
||||
#endif
|
||||
""")
|
||||
f.write('static const char UNUSED *bitcoin_strings[] = {')
|
||||
f.write('static const char UNUSED *bitcoin_strings[] = {\n')
|
||||
messages.sort(key=operator.itemgetter(0))
|
||||
for (msgid, msgstr) in messages:
|
||||
if msgid != EMPTY:
|
||||
f.write('QT_TRANSLATE_NOOP("bitcoin-core", %s),\n' % ('\n'.join(msgid)))
|
||||
|
|
|
@ -117,7 +117,6 @@ struct zero_after_free_allocator : public std::allocator<T>
|
|||
};
|
||||
|
||||
// This is exactly like std::string, but with a custom allocator.
|
||||
// (secure_allocator<> is defined in serialize.h)
|
||||
typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
|
||||
|
||||
#endif
|
||||
|
|
101
src/base58.h
101
src/base58.h
|
@ -19,6 +19,7 @@
|
|||
#include <vector>
|
||||
#include "bignum.h"
|
||||
#include "key.h"
|
||||
#include "script.h"
|
||||
|
||||
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
|
@ -258,6 +259,18 @@ public:
|
|||
* Script-hash-addresses have version 5 (or 196 testnet).
|
||||
* The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
|
||||
*/
|
||||
class CBitcoinAddress;
|
||||
class CBitcoinAddressVisitor : public boost::static_visitor<bool>
|
||||
{
|
||||
private:
|
||||
CBitcoinAddress *addr;
|
||||
public:
|
||||
CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { }
|
||||
bool operator()(const CKeyID &id) const;
|
||||
bool operator()(const CScriptID &id) const;
|
||||
bool operator()(const CNoDestination &no) const;
|
||||
};
|
||||
|
||||
class CBitcoinAddress : public CBase58Data
|
||||
{
|
||||
public:
|
||||
|
@ -269,21 +282,19 @@ public:
|
|||
SCRIPT_ADDRESS_TEST = 196,
|
||||
};
|
||||
|
||||
bool SetHash160(const uint160& hash160)
|
||||
{
|
||||
SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &hash160, 20);
|
||||
bool Set(const CKeyID &id) {
|
||||
SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &id, 20);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetPubKey(const std::vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
SetHash160(Hash160(vchPubKey));
|
||||
bool Set(const CScriptID &id) {
|
||||
SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &id, 20);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetScriptHash160(const uint160& hash160)
|
||||
bool Set(const CTxDestination &dest)
|
||||
{
|
||||
SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &hash160, 20);
|
||||
return true;
|
||||
return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
|
@ -315,27 +326,14 @@ public:
|
|||
}
|
||||
return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
|
||||
}
|
||||
bool IsScript() const
|
||||
{
|
||||
if (!IsValid())
|
||||
return false;
|
||||
if (fTestNet)
|
||||
return nVersion == SCRIPT_ADDRESS_TEST;
|
||||
return nVersion == SCRIPT_ADDRESS;
|
||||
}
|
||||
|
||||
CBitcoinAddress()
|
||||
{
|
||||
}
|
||||
|
||||
CBitcoinAddress(uint160 hash160In)
|
||||
CBitcoinAddress(const CTxDestination &dest)
|
||||
{
|
||||
SetHash160(hash160In);
|
||||
}
|
||||
|
||||
CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
SetPubKey(vchPubKey);
|
||||
Set(dest);
|
||||
}
|
||||
|
||||
CBitcoinAddress(const std::string& strAddress)
|
||||
|
@ -348,15 +346,58 @@ public:
|
|||
SetString(pszAddress);
|
||||
}
|
||||
|
||||
uint160 GetHash160() const
|
||||
{
|
||||
assert(vchData.size() == 20);
|
||||
uint160 hash160;
|
||||
memcpy(&hash160, &vchData[0], 20);
|
||||
return hash160;
|
||||
CTxDestination Get() const {
|
||||
if (!IsValid())
|
||||
return CNoDestination();
|
||||
switch (nVersion) {
|
||||
case PUBKEY_ADDRESS:
|
||||
case PUBKEY_ADDRESS_TEST: {
|
||||
uint160 id;
|
||||
memcpy(&id, &vchData[0], 20);
|
||||
return CKeyID(id);
|
||||
}
|
||||
case SCRIPT_ADDRESS:
|
||||
case SCRIPT_ADDRESS_TEST: {
|
||||
uint160 id;
|
||||
memcpy(&id, &vchData[0], 20);
|
||||
return CScriptID(id);
|
||||
}
|
||||
}
|
||||
return CNoDestination();
|
||||
}
|
||||
|
||||
bool GetKeyID(CKeyID &keyID) const {
|
||||
if (!IsValid())
|
||||
return false;
|
||||
switch (nVersion) {
|
||||
case PUBKEY_ADDRESS:
|
||||
case PUBKEY_ADDRESS_TEST: {
|
||||
uint160 id;
|
||||
memcpy(&id, &vchData[0], 20);
|
||||
keyID = CKeyID(id);
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsScript() const {
|
||||
if (!IsValid())
|
||||
return false;
|
||||
switch (nVersion) {
|
||||
case SCRIPT_ADDRESS:
|
||||
case SCRIPT_ADDRESS_TEST: {
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { return addr->Set(id); }
|
||||
bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); }
|
||||
bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; }
|
||||
|
||||
/** A base58-encoded secret key */
|
||||
class CBitcoinSecret : public CBase58Data
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "net.h"
|
||||
#include "init.h"
|
||||
#include "ui_interface.h"
|
||||
#include "base58.h"
|
||||
#include "bitcoinrpc.h"
|
||||
|
||||
#undef printf
|
||||
|
@ -188,10 +189,10 @@ ScriptSigToJSON(const CTxIn& txin, Object& out)
|
|||
return;
|
||||
|
||||
txnouttype type;
|
||||
vector<CBitcoinAddress> addresses;
|
||||
vector<CTxDestination> addresses;
|
||||
int nRequired;
|
||||
|
||||
if (!ExtractAddresses(txprev.vout[txin.prevout.n].scriptPubKey, type,
|
||||
if (!ExtractDestinations(txprev.vout[txin.prevout.n].scriptPubKey, type,
|
||||
addresses, nRequired))
|
||||
{
|
||||
out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
|
||||
|
@ -206,8 +207,8 @@ ScriptSigToJSON(const CTxIn& txin, Object& out)
|
|||
}
|
||||
|
||||
Array a;
|
||||
BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
|
||||
a.push_back(addr.ToString());
|
||||
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||
a.push_back(CBitcoinAddress(addr).ToString());
|
||||
out.push_back(Pair("addresses", a));
|
||||
}
|
||||
|
||||
|
@ -215,13 +216,13 @@ void
|
|||
ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
|
||||
{
|
||||
txnouttype type;
|
||||
vector<CBitcoinAddress> addresses;
|
||||
vector<CTxDestination> addresses;
|
||||
int nRequired;
|
||||
|
||||
out.push_back(Pair("asm", scriptPubKey.ToString()));
|
||||
out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
|
||||
|
||||
if (!ExtractAddresses(scriptPubKey, type, addresses, nRequired))
|
||||
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired))
|
||||
{
|
||||
out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
|
||||
return;
|
||||
|
@ -231,8 +232,8 @@ ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
|
|||
out.push_back(Pair("type", GetTxnOutputType(type)));
|
||||
|
||||
Array a;
|
||||
BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
|
||||
a.push_back(addr.ToString());
|
||||
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||
a.push_back(CBitcoinAddress(addr).ToString());
|
||||
out.push_back(Pair("addresses", a));
|
||||
}
|
||||
|
||||
|
@ -439,7 +440,7 @@ Value stop(const Array& params, bool fHelp)
|
|||
"stop\n"
|
||||
"Stop Bitcoin server.");
|
||||
// Shutdown will take long enough that the response should get back
|
||||
uiInterface.QueueShutdown();
|
||||
StartShutdown();
|
||||
return "Bitcoin server stopping";
|
||||
}
|
||||
|
||||
|
@ -534,6 +535,9 @@ Value getinfo(const Array& params, bool fHelp)
|
|||
"getinfo\n"
|
||||
"Returns an object containing various state info.");
|
||||
|
||||
CService addrProxy;
|
||||
GetProxy(NET_IPV4, addrProxy);
|
||||
|
||||
Object obj;
|
||||
obj.push_back(Pair("version", (int)CLIENT_VERSION));
|
||||
obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
|
||||
|
@ -541,7 +545,7 @@ Value getinfo(const Array& params, bool fHelp)
|
|||
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
|
||||
obj.push_back(Pair("blocks", (int)nBestHeight));
|
||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
|
||||
obj.push_back(Pair("proxy", (addrProxy.IsValid() ? addrProxy.ToStringIPPort() : string())));
|
||||
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
||||
obj.push_back(Pair("testnet", fTestNet));
|
||||
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
||||
|
@ -594,14 +598,14 @@ Value getnewaddress(const Array& params, bool fHelp)
|
|||
pwalletMain->TopUpKeyPool();
|
||||
|
||||
// Generate a new key that is added to wallet
|
||||
std::vector<unsigned char> newKey;
|
||||
CPubKey newKey;
|
||||
if (!pwalletMain->GetKeyFromPool(newKey, false))
|
||||
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
|
||||
CBitcoinAddress address(newKey);
|
||||
CKeyID keyID = newKey.GetID();
|
||||
|
||||
pwalletMain->SetAddressBookName(address, strAccount);
|
||||
pwalletMain->SetAddressBookName(keyID, strAccount);
|
||||
|
||||
return address.ToString();
|
||||
return CBitcoinAddress(keyID).ToString();
|
||||
}
|
||||
|
||||
|
||||
|
@ -615,12 +619,12 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
|
|||
bool bKeyUsed = false;
|
||||
|
||||
// Check if the current key has been used
|
||||
if (!account.vchPubKey.empty())
|
||||
if (account.vchPubKey.IsValid())
|
||||
{
|
||||
CScript scriptPubKey;
|
||||
scriptPubKey.SetBitcoinAddress(account.vchPubKey);
|
||||
scriptPubKey.SetDestination(account.vchPubKey.GetID());
|
||||
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
|
||||
it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
|
||||
it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
|
||||
++it)
|
||||
{
|
||||
const CWalletTx& wtx = (*it).second;
|
||||
|
@ -631,16 +635,16 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
|
|||
}
|
||||
|
||||
// Generate a new key
|
||||
if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
|
||||
if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
|
||||
{
|
||||
if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
|
||||
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
|
||||
|
||||
pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
|
||||
pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), strAccount);
|
||||
walletdb.WriteAccount(strAccount, account);
|
||||
}
|
||||
|
||||
return CBitcoinAddress(account.vchPubKey);
|
||||
return CBitcoinAddress(account.vchPubKey.GetID());
|
||||
}
|
||||
|
||||
Value getaccountaddress(const Array& params, bool fHelp)
|
||||
|
@ -679,14 +683,14 @@ Value setaccount(const Array& params, bool fHelp)
|
|||
strAccount = AccountFromValue(params[1]);
|
||||
|
||||
// Detect when changing the account of an address that is the 'unused current key' of another account:
|
||||
if (pwalletMain->mapAddressBook.count(address))
|
||||
if (pwalletMain->mapAddressBook.count(address.Get()))
|
||||
{
|
||||
string strOldAccount = pwalletMain->mapAddressBook[address];
|
||||
string strOldAccount = pwalletMain->mapAddressBook[address.Get()];
|
||||
if (address == GetAccountAddress(strOldAccount))
|
||||
GetAccountAddress(strOldAccount, true);
|
||||
}
|
||||
|
||||
pwalletMain->SetAddressBookName(address, strAccount);
|
||||
pwalletMain->SetAddressBookName(address.Get(), strAccount);
|
||||
|
||||
return Value::null;
|
||||
}
|
||||
|
@ -704,7 +708,7 @@ Value getaccount(const Array& params, bool fHelp)
|
|||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
||||
|
||||
string strAccount;
|
||||
map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
|
||||
map<CTxDestination, string>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
|
||||
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
|
||||
strAccount = (*mi).second;
|
||||
return strAccount;
|
||||
|
@ -773,7 +777,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
|
|||
if (pwalletMain->IsLocked())
|
||||
throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
|
||||
|
||||
string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
|
||||
string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
|
||||
if (strError != "")
|
||||
throw JSONRPCError(-4, strError);
|
||||
|
||||
|
@ -796,8 +800,12 @@ Value signmessage(const Array& params, bool fHelp)
|
|||
if (!addr.IsValid())
|
||||
throw JSONRPCError(-3, "Invalid address");
|
||||
|
||||
CKeyID keyID;
|
||||
if (!addr.GetKeyID(keyID))
|
||||
throw JSONRPCError(-3, "Address does not refer to key");
|
||||
|
||||
CKey key;
|
||||
if (!pwalletMain->GetKey(addr, key))
|
||||
if (!pwalletMain->GetKey(keyID, key))
|
||||
throw JSONRPCError(-4, "Private key not available");
|
||||
|
||||
CDataStream ss(SER_GETHASH, 0);
|
||||
|
@ -826,6 +834,10 @@ Value verifymessage(const Array& params, bool fHelp)
|
|||
if (!addr.IsValid())
|
||||
throw JSONRPCError(-3, "Invalid address");
|
||||
|
||||
CKeyID keyID;
|
||||
if (!addr.GetKeyID(keyID))
|
||||
throw JSONRPCError(-3, "Address does not refer to key");
|
||||
|
||||
bool fInvalid = false;
|
||||
vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
|
||||
|
||||
|
@ -840,7 +852,7 @@ Value verifymessage(const Array& params, bool fHelp)
|
|||
if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
|
||||
return false;
|
||||
|
||||
return (CBitcoinAddress(key.GetPubKey()) == addr);
|
||||
return (key.GetPubKey().GetID() == keyID);
|
||||
}
|
||||
|
||||
|
||||
|
@ -856,7 +868,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
|||
CScript scriptPubKey;
|
||||
if (!address.IsValid())
|
||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
||||
scriptPubKey.SetBitcoinAddress(address);
|
||||
scriptPubKey.SetDestination(address.Get());
|
||||
if (!IsMine(*pwalletMain,scriptPubKey))
|
||||
return (double)0.0;
|
||||
|
||||
|
@ -883,18 +895,17 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
|||
}
|
||||
|
||||
|
||||
void GetAccountAddresses(string strAccount, set<CBitcoinAddress>& setAddress)
|
||||
void GetAccountAddresses(string strAccount, set<CTxDestination>& setAddress)
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& item, pwalletMain->mapAddressBook)
|
||||
{
|
||||
const CBitcoinAddress& address = item.first;
|
||||
const CTxDestination& address = item.first;
|
||||
const string& strName = item.second;
|
||||
if (strName == strAccount)
|
||||
setAddress.insert(address);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Value getreceivedbyaccount(const Array& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
|
@ -909,7 +920,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
|
|||
|
||||
// Get the set of pub keys assigned to account
|
||||
string strAccount = AccountFromValue(params[0]);
|
||||
set<CBitcoinAddress> setAddress;
|
||||
set<CTxDestination> setAddress;
|
||||
GetAccountAddresses(strAccount, setAddress);
|
||||
|
||||
// Tally
|
||||
|
@ -922,8 +933,8 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
|
|||
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
{
|
||||
CBitcoinAddress address;
|
||||
if (ExtractAddress(txout.scriptPubKey, address) && pwalletMain->HaveKey(address) && setAddress.count(address))
|
||||
CTxDestination address;
|
||||
if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
nAmount += txout.nValue;
|
||||
}
|
||||
|
@ -994,15 +1005,15 @@ Value getbalance(const Array& params, bool fHelp)
|
|||
int64 allGeneratedImmature, allGeneratedMature, allFee;
|
||||
allGeneratedImmature = allGeneratedMature = allFee = 0;
|
||||
string strSentAccount;
|
||||
list<pair<CBitcoinAddress, int64> > listReceived;
|
||||
list<pair<CBitcoinAddress, int64> > listSent;
|
||||
list<pair<CTxDestination, int64> > listReceived;
|
||||
list<pair<CTxDestination, int64> > listSent;
|
||||
wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived)
|
||||
nBalance += r.second;
|
||||
}
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent)
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent)
|
||||
nBalance -= r.second;
|
||||
nBalance -= allFee;
|
||||
nBalance += allGeneratedMature;
|
||||
|
@ -1098,7 +1109,7 @@ Value sendfrom(const Array& params, bool fHelp)
|
|||
throw JSONRPCError(-6, "Account has insufficient funds");
|
||||
|
||||
// Send
|
||||
string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
|
||||
string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
|
||||
if (strError != "")
|
||||
throw JSONRPCError(-4, strError);
|
||||
|
||||
|
@ -1140,7 +1151,7 @@ Value sendmany(const Array& params, bool fHelp)
|
|||
setAddress.insert(address);
|
||||
|
||||
CScript scriptPubKey;
|
||||
scriptPubKey.SetBitcoinAddress(address);
|
||||
scriptPubKey.SetDestination(address.Get());
|
||||
int64 nAmount = AmountFromValue(s.value_);
|
||||
totalAmount += nAmount;
|
||||
|
||||
|
@ -1204,22 +1215,23 @@ Value addmultisigaddress(const Array& params, bool fHelp)
|
|||
CBitcoinAddress address(ks);
|
||||
if (address.IsValid())
|
||||
{
|
||||
if (address.IsScript())
|
||||
CKeyID keyID;
|
||||
if (!address.GetKeyID(keyID))
|
||||
throw runtime_error(
|
||||
strprintf("%s is a pay-to-script address",ks.c_str()));
|
||||
std::vector<unsigned char> vchPubKey;
|
||||
if (!pwalletMain->GetPubKey(address, vchPubKey))
|
||||
strprintf("%s does not refer to a key",ks.c_str()));
|
||||
CPubKey vchPubKey;
|
||||
if (!pwalletMain->GetPubKey(keyID, vchPubKey))
|
||||
throw runtime_error(
|
||||
strprintf("no full public key for address %s",ks.c_str()));
|
||||
if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey))
|
||||
if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
|
||||
throw runtime_error(" Invalid public key: "+ks);
|
||||
}
|
||||
|
||||
// Case 2: hex public key
|
||||
else if (IsHex(ks))
|
||||
{
|
||||
vector<unsigned char> vchPubKey = ParseHex(ks);
|
||||
if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey))
|
||||
CPubKey vchPubKey(ParseHex(ks));
|
||||
if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
|
||||
throw runtime_error(" Invalid public key: "+ks);
|
||||
}
|
||||
else
|
||||
|
@ -1231,16 +1243,11 @@ Value addmultisigaddress(const Array& params, bool fHelp)
|
|||
// Construct using pay-to-script-hash:
|
||||
CScript inner;
|
||||
inner.SetMultisig(nRequired, pubkeys);
|
||||
|
||||
uint160 scriptHash = Hash160(inner);
|
||||
CScript scriptPubKey;
|
||||
scriptPubKey.SetPayToScriptHash(inner);
|
||||
CScriptID innerID = inner.GetID();
|
||||
pwalletMain->AddCScript(inner);
|
||||
CBitcoinAddress address;
|
||||
address.SetScriptHash160(scriptHash);
|
||||
|
||||
pwalletMain->SetAddressBookName(address, strAccount);
|
||||
return address.ToString();
|
||||
pwalletMain->SetAddressBookName(innerID, strAccount);
|
||||
return CBitcoinAddress(innerID).ToString();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1282,8 +1289,8 @@ Value ListReceived(const Array& params, bool fByAccounts)
|
|||
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
{
|
||||
CBitcoinAddress address;
|
||||
if (!ExtractAddress(txout.scriptPubKey, address) || !pwalletMain->HaveKey(address) || !address.IsValid())
|
||||
CTxDestination address;
|
||||
if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address))
|
||||
continue;
|
||||
|
||||
tallyitem& item = mapTally[address];
|
||||
|
@ -1380,8 +1387,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
|||
{
|
||||
int64 nGeneratedImmature, nGeneratedMature, nFee;
|
||||
string strSentAccount;
|
||||
list<pair<CBitcoinAddress, int64> > listReceived;
|
||||
list<pair<CBitcoinAddress, int64> > listSent;
|
||||
list<pair<CTxDestination, int64> > listReceived;
|
||||
list<pair<CTxDestination, int64> > listSent;
|
||||
|
||||
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
|
||||
|
||||
|
@ -1410,11 +1417,11 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
|||
// Sent
|
||||
if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent)
|
||||
{
|
||||
Object entry;
|
||||
entry.push_back(Pair("account", strSentAccount));
|
||||
entry.push_back(Pair("address", s.first.ToString()));
|
||||
entry.push_back(Pair("address", CBitcoinAddress(s.first).ToString()));
|
||||
entry.push_back(Pair("category", "send"));
|
||||
entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
|
||||
entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
|
||||
|
@ -1427,7 +1434,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
|||
// Received
|
||||
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived)
|
||||
{
|
||||
string account;
|
||||
if (pwalletMain->mapAddressBook.count(r.first))
|
||||
|
@ -1436,7 +1443,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
|||
{
|
||||
Object entry;
|
||||
entry.push_back(Pair("account", account));
|
||||
entry.push_back(Pair("address", r.first.ToString()));
|
||||
entry.push_back(Pair("address", CBitcoinAddress(r.first).ToString()));
|
||||
entry.push_back(Pair("category", "receive"));
|
||||
entry.push_back(Pair("amount", ValueFromAmount(r.second)));
|
||||
if (fLong)
|
||||
|
@ -1551,8 +1558,8 @@ Value listaccounts(const Array& params, bool fHelp)
|
|||
nMinDepth = params[0].get_int();
|
||||
|
||||
map<string, int64> mapAccountBalances;
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
|
||||
if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) {
|
||||
if (IsMine(*pwalletMain, entry.first)) // This address belongs to me
|
||||
mapAccountBalances[entry.second] = 0;
|
||||
}
|
||||
|
||||
|
@ -1561,16 +1568,16 @@ Value listaccounts(const Array& params, bool fHelp)
|
|||
const CWalletTx& wtx = (*it).second;
|
||||
int64 nGeneratedImmature, nGeneratedMature, nFee;
|
||||
string strSentAccount;
|
||||
list<pair<CBitcoinAddress, int64> > listReceived;
|
||||
list<pair<CBitcoinAddress, int64> > listSent;
|
||||
list<pair<CTxDestination, int64> > listReceived;
|
||||
list<pair<CTxDestination, int64> > listSent;
|
||||
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
|
||||
mapAccountBalances[strSentAccount] -= nFee;
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent)
|
||||
mapAccountBalances[strSentAccount] -= s.second;
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
{
|
||||
mapAccountBalances[""] += nGeneratedMature;
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived)
|
||||
if (pwalletMain->mapAddressBook.count(r.first))
|
||||
mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
|
||||
else
|
||||
|
@ -1932,10 +1939,44 @@ Value encryptwallet(const Array& params, bool fHelp)
|
|||
// BDB seems to have a bad habit of writing old data into
|
||||
// slack space in .dat files; that is bad if the old data is
|
||||
// unencrypted private keys. So:
|
||||
uiInterface.QueueShutdown();
|
||||
StartShutdown();
|
||||
return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet";
|
||||
}
|
||||
|
||||
class DescribeAddressVisitor : public boost::static_visitor<Object>
|
||||
{
|
||||
public:
|
||||
Object operator()(const CNoDestination &dest) const { return Object(); }
|
||||
|
||||
Object operator()(const CKeyID &keyID) const {
|
||||
Object obj;
|
||||
CPubKey vchPubKey;
|
||||
pwalletMain->GetPubKey(keyID, vchPubKey);
|
||||
obj.push_back(Pair("isscript", false));
|
||||
obj.push_back(Pair("pubkey", HexStr(vchPubKey.Raw())));
|
||||
obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
|
||||
return obj;
|
||||
}
|
||||
|
||||
Object operator()(const CScriptID &scriptID) const {
|
||||
Object obj;
|
||||
obj.push_back(Pair("isscript", true));
|
||||
CScript subscript;
|
||||
pwalletMain->GetCScript(scriptID, subscript);
|
||||
std::vector<CTxDestination> addresses;
|
||||
txnouttype whichType;
|
||||
int nRequired;
|
||||
ExtractDestinations(subscript, whichType, addresses, nRequired);
|
||||
obj.push_back(Pair("script", GetTxnOutputType(whichType)));
|
||||
Array a;
|
||||
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||
a.push_back(CBitcoinAddress(addr).ToString());
|
||||
obj.push_back(Pair("addresses", a));
|
||||
if (whichType == TX_MULTISIG)
|
||||
obj.push_back(Pair("sigsrequired", nRequired));
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
Value validateaddress(const Array& params, bool fHelp)
|
||||
{
|
||||
|
@ -1951,42 +1992,17 @@ Value validateaddress(const Array& params, bool fHelp)
|
|||
ret.push_back(Pair("isvalid", isValid));
|
||||
if (isValid)
|
||||
{
|
||||
// Call Hash160ToAddress() so we always return current ADDRESSVERSION
|
||||
// version of the address:
|
||||
CTxDestination dest = address.Get();
|
||||
string currentAddress = address.ToString();
|
||||
ret.push_back(Pair("address", currentAddress));
|
||||
if (pwalletMain->HaveKey(address))
|
||||
{
|
||||
ret.push_back(Pair("ismine", true));
|
||||
std::vector<unsigned char> vchPubKey;
|
||||
pwalletMain->GetPubKey(address, vchPubKey);
|
||||
ret.push_back(Pair("pubkey", HexStr(vchPubKey)));
|
||||
CKey key;
|
||||
key.SetPubKey(vchPubKey);
|
||||
ret.push_back(Pair("iscompressed", key.IsCompressed()));
|
||||
bool fMine = IsMine(*pwalletMain, dest);
|
||||
ret.push_back(Pair("ismine", fMine));
|
||||
if (fMine) {
|
||||
Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
|
||||
ret.insert(ret.end(), detail.begin(), detail.end());
|
||||
}
|
||||
else if (pwalletMain->HaveCScript(address.GetHash160()))
|
||||
{
|
||||
ret.push_back(Pair("isscript", true));
|
||||
CScript subscript;
|
||||
pwalletMain->GetCScript(address.GetHash160(), subscript);
|
||||
ret.push_back(Pair("ismine", ::IsMine(*pwalletMain, subscript)));
|
||||
std::vector<CBitcoinAddress> addresses;
|
||||
txnouttype whichType;
|
||||
int nRequired;
|
||||
ExtractAddresses(subscript, whichType, addresses, nRequired);
|
||||
ret.push_back(Pair("script", GetTxnOutputType(whichType)));
|
||||
Array a;
|
||||
BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
|
||||
a.push_back(addr.ToString());
|
||||
ret.push_back(Pair("addresses", a));
|
||||
if (whichType == TX_MULTISIG)
|
||||
ret.push_back(Pair("sigsrequired", nRequired));
|
||||
}
|
||||
else
|
||||
ret.push_back(Pair("ismine", false));
|
||||
if (pwalletMain->mapAddressBook.count(address))
|
||||
ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
|
||||
if (pwalletMain->mapAddressBook.count(dest))
|
||||
ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest]));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -2252,7 +2268,7 @@ Value sendrawtx(const Array& params, bool fHelp)
|
|||
CInv inv(MSG_TX, tx.GetHash());
|
||||
RelayInventory(inv);
|
||||
|
||||
return true;
|
||||
return tx.GetHash().GetHex();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2791,7 +2807,7 @@ void ThreadRPCServer2(void* parg)
|
|||
GetConfigFile().string().c_str(),
|
||||
EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
|
||||
_("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL);
|
||||
uiInterface.QueueShutdown();
|
||||
StartShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2863,12 +2879,13 @@ void ThreadRPCServer2(void* parg)
|
|||
{
|
||||
uiInterface.ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
|
||||
_("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL);
|
||||
uiInterface.QueueShutdown();
|
||||
StartShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
vnThreadsRunning[THREAD_RPCLISTENER]--;
|
||||
io_service.run();
|
||||
while (!fShutdown)
|
||||
io_service.run_one();
|
||||
vnThreadsRunning[THREAD_RPCLISTENER]++;
|
||||
|
||||
// Terminate all outstanding accept-requests
|
||||
|
@ -3111,24 +3128,11 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
|
|||
if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "sendmany" && n > 1)
|
||||
{
|
||||
string s = params[1].get_str();
|
||||
Value v;
|
||||
if (!read_string(s, v) || v.type() != obj_type)
|
||||
throw runtime_error("type mismatch");
|
||||
params[1] = v.get_obj();
|
||||
}
|
||||
if (strMethod == "sendmany" && n > 1) ConvertTo<Object>(params[1]);
|
||||
if (strMethod == "sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
|
||||
if (strMethod == "addmultisigaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "addmultisigaddress" && n > 1)
|
||||
{
|
||||
string s = params[1].get_str();
|
||||
Value v;
|
||||
if (!read_string(s, v) || v.type() != array_type)
|
||||
throw runtime_error("type mismatch "+s);
|
||||
params[1] = v.get_array();
|
||||
}
|
||||
if (strMethod == "addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,27 +35,32 @@ namespace Checkpoints
|
|||
(168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
|
||||
;
|
||||
|
||||
static MapCheckpoints mapCheckpointsTestnet =
|
||||
boost::assign::map_list_of
|
||||
( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
|
||||
;
|
||||
|
||||
bool CheckBlock(int nHeight, const uint256& hash)
|
||||
{
|
||||
if (fTestNet) return true; // Testnet has no checkpoints
|
||||
MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);
|
||||
|
||||
MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
|
||||
if (i == mapCheckpoints.end()) return true;
|
||||
MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
|
||||
if (i == checkpoints.end()) return true;
|
||||
return hash == i->second;
|
||||
}
|
||||
|
||||
int GetTotalBlocksEstimate()
|
||||
{
|
||||
if (fTestNet) return 0;
|
||||
MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);
|
||||
|
||||
return mapCheckpoints.rbegin()->first;
|
||||
return checkpoints.rbegin()->first;
|
||||
}
|
||||
|
||||
CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
|
||||
{
|
||||
if (fTestNet) return NULL;
|
||||
MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);
|
||||
|
||||
BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
|
||||
BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
|
||||
{
|
||||
const uint256& hash = i.second;
|
||||
std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
|
||||
|
|
137
src/init.cpp
137
src/init.cpp
|
@ -38,6 +38,17 @@ void ExitTimeout(void* parg)
|
|||
#endif
|
||||
}
|
||||
|
||||
void StartShutdown()
|
||||
{
|
||||
#ifdef QT_GUI
|
||||
// ensure we leave the Qt main loop for a clean GUI exit (Shutdown() is called in bitcoin.cpp afterwards)
|
||||
uiInterface.QueueShutdown();
|
||||
#else
|
||||
// Without UI, Shutdown() can simply be started in a new thread
|
||||
CreateThread(Shutdown, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Shutdown(void* parg)
|
||||
{
|
||||
static CCriticalSection cs_Shutdown;
|
||||
|
@ -66,7 +77,10 @@ void Shutdown(void* parg)
|
|||
Sleep(50);
|
||||
printf("Bitcoin exited\n\n");
|
||||
fExit = true;
|
||||
#ifndef QT_GUI
|
||||
// ensure non UI client get's exited here, but let Bitcoin-Qt reach return 0; in bitcoin.cpp
|
||||
exit(0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -182,12 +196,15 @@ bool static InitWarning(const std::string &str)
|
|||
}
|
||||
|
||||
|
||||
bool static Bind(const CService &addr) {
|
||||
bool static Bind(const CService &addr, bool fError = true) {
|
||||
if (IsLimited(addr))
|
||||
return false;
|
||||
std::string strError;
|
||||
if (!BindListenPort(addr, strError))
|
||||
if (!BindListenPort(addr, strError)) {
|
||||
if (fError)
|
||||
return InitError(strError);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -204,20 +221,18 @@ std::string HelpMessage()
|
|||
" -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
|
||||
" -timeout=<n> " + _("Specify connection timeout (in milliseconds)") + "\n" +
|
||||
" -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" +
|
||||
" -socks=<n> " + _("Select the version of socks proxy to use (4 or 5, 5 is default)") + "\n" +
|
||||
" -noproxy=<net> " + _("Do not use proxy for connections to network <net> (IPv4 or IPv6)") + "\n" +
|
||||
" -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" +
|
||||
" -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" +
|
||||
" -proxydns " + _("Pass DNS requests to (SOCKS5) proxy") + "\n" +
|
||||
" -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" +
|
||||
" -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
|
||||
" -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n" +
|
||||
" -connect=<ip> " + _("Connect only to the specified node") + "\n" +
|
||||
" -connect=<ip> " + _("Connect only to the specified node(s)") + "\n" +
|
||||
" -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" +
|
||||
" -externalip=<ip> " + _("Specify your own public address") + "\n" +
|
||||
" -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4 or IPv6)") + "\n" +
|
||||
" -discover " + _("Try to discover public IP address (default: 1)") + "\n" +
|
||||
" -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n" +
|
||||
" -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" +
|
||||
" -listen " + _("Accept connections from outside (default: 1)") + "\n" +
|
||||
" -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n" +
|
||||
" -bind=<addr> " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" +
|
||||
" -dnsseed " + _("Find peers using DNS lookup (default: 1)") + "\n" +
|
||||
" -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
|
||||
|
@ -226,9 +241,9 @@ std::string HelpMessage()
|
|||
" -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" +
|
||||
#ifdef USE_UPNP
|
||||
#if USE_UPNP
|
||||
" -upnp " + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" +
|
||||
" -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n" +
|
||||
#else
|
||||
" -upnp " + _("Use Universal Plug and Play to map the listening port (default: 0)") + "\n" +
|
||||
" -upnp " + _("Use UPnP to map the listening port (default: 0)") + "\n" +
|
||||
#endif
|
||||
#endif
|
||||
" -detachdb " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" +
|
||||
|
@ -308,30 +323,38 @@ bool AppInit2()
|
|||
// ********************************************************* Step 2: parameter interactions
|
||||
|
||||
fTestNet = GetBoolArg("-testnet");
|
||||
if (fTestNet)
|
||||
{
|
||||
if (fTestNet) {
|
||||
SoftSetBoolArg("-irc", true);
|
||||
}
|
||||
|
||||
if (mapArgs.count("-connect"))
|
||||
SoftSetBoolArg("-dnsseed", false);
|
||||
|
||||
// even in Tor mode, if -bind is specified, you really want -listen
|
||||
if (mapArgs.count("-bind"))
|
||||
if (mapArgs.count("-bind")) {
|
||||
// when specifying an explicit binding address, you want to listen on it
|
||||
// even when -connect or -proxy is specified
|
||||
SoftSetBoolArg("-listen", true);
|
||||
}
|
||||
|
||||
bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
|
||||
if (fTor)
|
||||
{
|
||||
// Use SoftSetBoolArg here so user can override any of these if they wish.
|
||||
// Note: the GetBoolArg() calls for all of these must happen later.
|
||||
if (mapArgs.count("-connect")) {
|
||||
// when only connecting to trusted nodes, do not seed via DNS, or listen by default
|
||||
SoftSetBoolArg("-dnsseed", false);
|
||||
SoftSetBoolArg("-listen", false);
|
||||
SoftSetBoolArg("-irc", false);
|
||||
SoftSetBoolArg("-proxydns", true);
|
||||
}
|
||||
|
||||
if (mapArgs.count("-proxy")) {
|
||||
// to protect privacy, do not listen by default if a proxy server is specified
|
||||
SoftSetBoolArg("-listen", false);
|
||||
}
|
||||
|
||||
if (GetBoolArg("-listen", true)) {
|
||||
// do not map ports or try to retrieve public IP when not listening (pointless)
|
||||
SoftSetBoolArg("-upnp", false);
|
||||
SoftSetBoolArg("-discover", false);
|
||||
}
|
||||
|
||||
if (mapArgs.count("-externalip")) {
|
||||
// if an explicit public IP is specified, do not try to find others
|
||||
SoftSetBoolArg("-discover", false);
|
||||
}
|
||||
|
||||
// ********************************************************* Step 3: parameter-to-internal-flags
|
||||
|
||||
fDebug = GetBoolArg("-debug");
|
||||
|
@ -414,7 +437,9 @@ bool AppInit2()
|
|||
ShrinkDebugFile();
|
||||
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
|
||||
printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
|
||||
printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
|
||||
printf("Used data directory %s\n", GetDataDir().string().c_str());
|
||||
std::ostringstream strErrors;
|
||||
|
||||
if (fDaemon)
|
||||
|
@ -424,30 +449,8 @@ bool AppInit2()
|
|||
|
||||
// ********************************************************* Step 5: network initialization
|
||||
|
||||
if (mapArgs.count("-proxy"))
|
||||
{
|
||||
fUseProxy = true;
|
||||
addrProxy = CService(mapArgs["-proxy"], 9050);
|
||||
if (!addrProxy.IsValid())
|
||||
return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
|
||||
}
|
||||
int nSocksVersion = GetArg("-socks", 5);
|
||||
|
||||
if (mapArgs.count("-noproxy"))
|
||||
{
|
||||
BOOST_FOREACH(std::string snet, mapMultiArgs["-noproxy"]) {
|
||||
enum Network net = ParseNetwork(snet);
|
||||
if (net == NET_UNROUTABLE)
|
||||
return InitError(strprintf(_("Unknown network specified in -noproxy: '%s'"), snet.c_str()));
|
||||
SetNoProxy(net);
|
||||
}
|
||||
}
|
||||
|
||||
fNameLookup = GetBoolArg("-dns");
|
||||
fProxyNameLookup = GetBoolArg("-proxydns");
|
||||
if (fProxyNameLookup)
|
||||
fNameLookup = true;
|
||||
fNoListen = !GetBoolArg("-listen", true);
|
||||
nSocksVersion = GetArg("-socks", 5);
|
||||
if (nSocksVersion != 4 && nSocksVersion != 5)
|
||||
return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
|
||||
|
||||
|
@ -466,8 +469,29 @@ bool AppInit2()
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
|
||||
AddOneShot(strDest);
|
||||
if (mapArgs.count("-proxy")) {
|
||||
CService addrProxy = CService(mapArgs["-proxy"], 9050);
|
||||
if (!addrProxy.IsValid())
|
||||
return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
|
||||
|
||||
if (!IsLimited(NET_IPV4))
|
||||
SetProxy(NET_IPV4, addrProxy, nSocksVersion);
|
||||
if (nSocksVersion > 4) {
|
||||
#ifdef USE_IPV6
|
||||
if (!IsLimited(NET_IPV6))
|
||||
SetProxy(NET_IPV6, addrProxy, nSocksVersion);
|
||||
#endif
|
||||
SetNameProxy(addrProxy, nSocksVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// see Step 2: parameter interactions for more information about these
|
||||
fNoListen = !GetBoolArg("-listen", true);
|
||||
fDiscover = GetBoolArg("-discover", true);
|
||||
fNameLookup = GetBoolArg("-dns", true);
|
||||
#ifdef USE_UPNP
|
||||
fUseUPnP = GetBoolArg("-upnp", USE_UPNP);
|
||||
#endif
|
||||
|
||||
bool fBound = false;
|
||||
if (!fNoListen)
|
||||
|
@ -483,15 +507,15 @@ bool AppInit2()
|
|||
} else {
|
||||
struct in_addr inaddr_any;
|
||||
inaddr_any.s_addr = INADDR_ANY;
|
||||
if (!IsLimited(NET_IPV4))
|
||||
fBound |= Bind(CService(inaddr_any, GetListenPort()));
|
||||
#ifdef USE_IPV6
|
||||
if (!IsLimited(NET_IPV6))
|
||||
fBound |= Bind(CService(in6addr_any, GetListenPort()));
|
||||
fBound |= Bind(CService(in6addr_any, GetListenPort()), false);
|
||||
#endif
|
||||
if (!IsLimited(NET_IPV4))
|
||||
fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound);
|
||||
}
|
||||
if (!fBound)
|
||||
return InitError(_("Not listening on any port"));
|
||||
return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
|
||||
}
|
||||
|
||||
if (mapArgs.count("-externalip"))
|
||||
|
@ -504,6 +528,9 @@ bool AppInit2()
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
|
||||
AddOneShot(strDest);
|
||||
|
||||
// ********************************************************* Step 6: load blockchain
|
||||
|
||||
if (GetBoolArg("-loadblockindextest"))
|
||||
|
@ -604,11 +631,11 @@ bool AppInit2()
|
|||
// Create new keyUser and set as default key
|
||||
RandAddSeedPerfmon();
|
||||
|
||||
std::vector<unsigned char> newDefaultKey;
|
||||
CPubKey newDefaultKey;
|
||||
if (!pwalletMain->GetKeyFromPool(newDefaultKey, false))
|
||||
strErrors << _("Cannot initialize keypool") << "\n";
|
||||
pwalletMain->SetDefaultKey(newDefaultKey);
|
||||
if (!pwalletMain->SetAddressBookName(CBitcoinAddress(pwalletMain->vchDefaultKey), ""))
|
||||
if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), ""))
|
||||
strErrors << _("Cannot write default address") << "\n";
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
extern CWallet* pwalletMain;
|
||||
|
||||
void StartShutdown();
|
||||
void Shutdown(void* parg);
|
||||
bool AppInit2();
|
||||
std::string HelpMessage();
|
||||
|
|
|
@ -176,8 +176,6 @@ bool GetIPFromIRC(SOCKET hSocket, string strMyName, CNetAddr& ipRet)
|
|||
// Hybrid IRC used by lfnet always returns IP when you userhost yourself,
|
||||
// but in case another IRC is ever used this should work.
|
||||
printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
|
||||
if (fUseProxy)
|
||||
return false;
|
||||
CNetAddr addr(strHost, true);
|
||||
if (!addr.IsValid())
|
||||
return false;
|
||||
|
@ -281,7 +279,7 @@ void ThreadIRCSeed2(void* parg)
|
|||
if (GetIPFromIRC(hSocket, strMyName, addrFromIRC))
|
||||
{
|
||||
printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str());
|
||||
if (!fUseProxy && addrFromIRC.IsRoutable())
|
||||
if (addrFromIRC.IsRoutable())
|
||||
{
|
||||
// IRC lets you to re-nick
|
||||
AddLocal(addrFromIRC, LOCAL_IRC);
|
||||
|
@ -291,8 +289,8 @@ void ThreadIRCSeed2(void* parg)
|
|||
}
|
||||
|
||||
if (fTestNet) {
|
||||
Send(hSocket, "JOIN #bitcoinTEST\r");
|
||||
Send(hSocket, "WHO #bitcoinTEST\r");
|
||||
Send(hSocket, "JOIN #bitcoinTEST3\r");
|
||||
Send(hSocket, "WHO #bitcoinTEST3\r");
|
||||
} else {
|
||||
// randomly join #bitcoin00-#bitcoin99
|
||||
int channel_number = GetRandInt(100);
|
||||
|
|
12
src/key.cpp
12
src/key.cpp
|
@ -239,18 +239,18 @@ CPrivKey CKey::GetPrivKey() const
|
|||
return vchPrivKey;
|
||||
}
|
||||
|
||||
bool CKey::SetPubKey(const std::vector<unsigned char>& vchPubKey)
|
||||
bool CKey::SetPubKey(const CPubKey& vchPubKey)
|
||||
{
|
||||
const unsigned char* pbegin = &vchPubKey[0];
|
||||
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
|
||||
const unsigned char* pbegin = &vchPubKey.vchPubKey[0];
|
||||
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.vchPubKey.size()))
|
||||
return false;
|
||||
fSet = true;
|
||||
if (vchPubKey.size() == 33)
|
||||
if (vchPubKey.vchPubKey.size() == 33)
|
||||
SetCompressedPubKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> CKey::GetPubKey() const
|
||||
CPubKey CKey::GetPubKey() const
|
||||
{
|
||||
int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||
if (!nSize)
|
||||
|
@ -259,7 +259,7 @@ std::vector<unsigned char> CKey::GetPubKey() const
|
|||
unsigned char* pbegin = &vchPubKey[0];
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||
return vchPubKey;
|
||||
return CPubKey(vchPubKey);
|
||||
}
|
||||
|
||||
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig)
|
||||
|
|
60
src/key.h
60
src/key.h
|
@ -9,7 +9,9 @@
|
|||
#include <vector>
|
||||
|
||||
#include "allocators.h"
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <openssl/ec.h> // for EC_KEY definition
|
||||
|
||||
|
@ -42,6 +44,60 @@ public:
|
|||
explicit key_error(const std::string& str) : std::runtime_error(str) {}
|
||||
};
|
||||
|
||||
/** A reference to a CKey: the Hash160 of its serialized public key */
|
||||
class CKeyID : public uint160
|
||||
{
|
||||
public:
|
||||
CKeyID() : uint160(0) { }
|
||||
CKeyID(const uint160 &in) : uint160(in) { }
|
||||
};
|
||||
|
||||
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
|
||||
class CScriptID : public uint160
|
||||
{
|
||||
public:
|
||||
CScriptID() : uint160(0) { }
|
||||
CScriptID(const uint160 &in) : uint160(in) { }
|
||||
};
|
||||
|
||||
/** An encapsulated public key. */
|
||||
class CPubKey {
|
||||
private:
|
||||
std::vector<unsigned char> vchPubKey;
|
||||
friend class CKey;
|
||||
|
||||
public:
|
||||
CPubKey() { }
|
||||
CPubKey(const std::vector<unsigned char> &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { }
|
||||
friend bool operator==(const CPubKey &a, const CPubKey &b) { return a.vchPubKey == b.vchPubKey; }
|
||||
friend bool operator!=(const CPubKey &a, const CPubKey &b) { return a.vchPubKey != b.vchPubKey; }
|
||||
friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; }
|
||||
|
||||
IMPLEMENT_SERIALIZE(
|
||||
READWRITE(vchPubKey);
|
||||
)
|
||||
|
||||
CKeyID GetID() const {
|
||||
return CKeyID(Hash160(vchPubKey));
|
||||
}
|
||||
|
||||
uint256 GetHash() const {
|
||||
return Hash(vchPubKey.begin(), vchPubKey.end());
|
||||
}
|
||||
|
||||
bool IsValid() const {
|
||||
return vchPubKey.size() == 33 || vchPubKey.size() == 65;
|
||||
}
|
||||
|
||||
bool IsCompressed() const {
|
||||
return vchPubKey.size() == 33;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> Raw() const {
|
||||
return vchPubKey;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// secure_allocator is defined in serialize.h
|
||||
// CPrivKey is a serialized private key, with all parameters included (279 bytes)
|
||||
|
@ -78,8 +134,8 @@ public:
|
|||
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false);
|
||||
CSecret GetSecret(bool &fCompressed) const;
|
||||
CPrivKey GetPrivKey() const;
|
||||
bool SetPubKey(const std::vector<unsigned char>& vchPubKey);
|
||||
std::vector<unsigned char> GetPubKey() const;
|
||||
bool SetPubKey(const CPubKey& vchPubKey);
|
||||
CPubKey GetPubKey() const;
|
||||
|
||||
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "keystore.h"
|
||||
#include "script.h"
|
||||
|
||||
bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
|
||||
bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
|
||||
{
|
||||
CKey key;
|
||||
if (!GetKey(address, key))
|
||||
|
@ -21,7 +21,7 @@ bool CBasicKeyStore::AddKey(const CKey& key)
|
|||
CSecret secret = key.GetSecret(fCompressed);
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
|
||||
mapKeys[key.GetPubKey().GetID()] = make_pair(secret, fCompressed);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -30,12 +30,12 @@ bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
|
|||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
mapScripts[Hash160(redeemScript)] = redeemScript;
|
||||
mapScripts[redeemScript.GetID()] = redeemScript;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBasicKeyStore::HaveCScript(const uint160& hash) const
|
||||
bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const
|
||||
{
|
||||
bool result;
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ bool CBasicKeyStore::HaveCScript(const uint160& hash) const
|
|||
}
|
||||
|
||||
|
||||
bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) const
|
||||
bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
|
@ -97,10 +97,10 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
|||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
||||
for (; mi != mapCryptedKeys.end(); ++mi)
|
||||
{
|
||||
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
|
||||
const CPubKey &vchPubKey = (*mi).second.first;
|
||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
||||
CSecret vchSecret;
|
||||
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
|
||||
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||
return false;
|
||||
if (vchSecret.size() != 32)
|
||||
return false;
|
||||
|
@ -128,9 +128,9 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
|
|||
return false;
|
||||
|
||||
std::vector<unsigned char> vchCryptedSecret;
|
||||
std::vector<unsigned char> vchPubKey = key.GetPubKey();
|
||||
CPubKey vchPubKey = key.GetPubKey();
|
||||
bool fCompressed;
|
||||
if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
|
||||
if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret))
|
||||
return false;
|
||||
|
||||
if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
|
||||
|
@ -140,19 +140,19 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
|
|||
}
|
||||
|
||||
|
||||
bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||
bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!SetCrypted())
|
||||
return false;
|
||||
|
||||
mapCryptedKeys[CBitcoinAddress(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
|
||||
mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
||||
bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
|
@ -162,10 +162,10 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
|||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
||||
if (mi != mapCryptedKeys.end())
|
||||
{
|
||||
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
|
||||
const CPubKey &vchPubKey = (*mi).second.first;
|
||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
||||
CSecret vchSecret;
|
||||
if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
|
||||
if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||
return false;
|
||||
if (vchSecret.size() != 32)
|
||||
return false;
|
||||
|
@ -177,7 +177,7 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
|
||||
bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
|
@ -207,10 +207,10 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
|||
CKey key;
|
||||
if (!key.SetSecret(mKey.second.first, mKey.second.second))
|
||||
return false;
|
||||
const std::vector<unsigned char> vchPubKey = key.GetPubKey();
|
||||
const CPubKey vchPubKey = key.GetPubKey();
|
||||
std::vector<unsigned char> vchCryptedSecret;
|
||||
bool fCompressed;
|
||||
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
|
||||
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret))
|
||||
return false;
|
||||
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
|
||||
return false;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include "crypter.h"
|
||||
#include "sync.h"
|
||||
#include "base58.h"
|
||||
#include <boost/signals2/signal.hpp>
|
||||
|
||||
class CScript;
|
||||
|
@ -25,17 +24,17 @@ public:
|
|||
virtual bool AddKey(const CKey& key) =0;
|
||||
|
||||
// Check whether a key corresponding to a given address is present in the store.
|
||||
virtual bool HaveKey(const CBitcoinAddress &address) const =0;
|
||||
virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
|
||||
virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
|
||||
virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
|
||||
virtual bool HaveKey(const CKeyID &address) const =0;
|
||||
virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;
|
||||
virtual void GetKeys(std::set<CKeyID> &setAddress) const =0;
|
||||
virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
|
||||
|
||||
// Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
|
||||
virtual bool AddCScript(const CScript& redeemScript) =0;
|
||||
virtual bool HaveCScript(const uint160 &hash) const =0;
|
||||
virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const =0;
|
||||
virtual bool HaveCScript(const CScriptID &hash) const =0;
|
||||
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0;
|
||||
|
||||
virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret, bool &fCompressed) const
|
||||
virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const
|
||||
{
|
||||
CKey key;
|
||||
if (!GetKey(address, key))
|
||||
|
@ -45,8 +44,8 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
typedef std::map<CBitcoinAddress, std::pair<CSecret, bool> > KeyMap;
|
||||
typedef std::map<uint160, CScript > ScriptMap;
|
||||
typedef std::map<CKeyID, std::pair<CSecret, bool> > KeyMap;
|
||||
typedef std::map<CScriptID, CScript > ScriptMap;
|
||||
|
||||
/** Basic key store, that keeps keys in an address->secret map */
|
||||
class CBasicKeyStore : public CKeyStore
|
||||
|
@ -57,7 +56,7 @@ protected:
|
|||
|
||||
public:
|
||||
bool AddKey(const CKey& key);
|
||||
bool HaveKey(const CBitcoinAddress &address) const
|
||||
bool HaveKey(const CKeyID &address) const
|
||||
{
|
||||
bool result;
|
||||
{
|
||||
|
@ -66,7 +65,7 @@ public:
|
|||
}
|
||||
return result;
|
||||
}
|
||||
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
|
||||
void GetKeys(std::set<CKeyID> &setAddress) const
|
||||
{
|
||||
setAddress.clear();
|
||||
{
|
||||
|
@ -79,7 +78,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
|
||||
bool GetKey(const CKeyID &address, CKey &keyOut) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
|
@ -94,11 +93,11 @@ public:
|
|||
return false;
|
||||
}
|
||||
virtual bool AddCScript(const CScript& redeemScript);
|
||||
virtual bool HaveCScript(const uint160 &hash) const;
|
||||
virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const;
|
||||
virtual bool HaveCScript(const CScriptID &hash) const;
|
||||
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const;
|
||||
};
|
||||
|
||||
typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;
|
||||
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
||||
|
||||
/** Keystore which keeps the private keys encrypted.
|
||||
* It derives from the basic key store, which is used if no encryption is active.
|
||||
|
@ -146,9 +145,9 @@ public:
|
|||
|
||||
bool Lock();
|
||||
|
||||
virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
||||
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
||||
bool AddKey(const CKey& key);
|
||||
bool HaveKey(const CBitcoinAddress &address) const
|
||||
bool HaveKey(const CKeyID &address) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
|
@ -158,9 +157,9 @@ public:
|
|||
}
|
||||
return false;
|
||||
}
|
||||
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
|
||||
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
|
||||
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
|
||||
bool GetKey(const CKeyID &address, CKey& keyOut) const;
|
||||
bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
|
||||
void GetKeys(std::set<CKeyID> &setAddress) const
|
||||
{
|
||||
if (!IsCrypted())
|
||||
{
|
||||
|
|
23
src/main.cpp
23
src/main.cpp
|
@ -865,12 +865,12 @@ unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBl
|
|||
// Only change once per interval
|
||||
if ((pindexLast->nHeight+1) % nInterval != 0)
|
||||
{
|
||||
// Special rules for testnet after 15 Feb 2012:
|
||||
if (fTestNet && pblock->nTime > 1329264000)
|
||||
// Special difficulty rule for testnet:
|
||||
if (fTestNet)
|
||||
{
|
||||
// If the new block's timestamp is more than 2* 10 minutes
|
||||
// then allow mining of a min-difficulty block.
|
||||
if (pblock->nTime - pindexLast->nTime > nTargetSpacing*2)
|
||||
if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2)
|
||||
return nProofOfWorkLimit;
|
||||
else
|
||||
{
|
||||
|
@ -1875,7 +1875,7 @@ bool CheckDiskSpace(uint64 nAdditionalBytes)
|
|||
strMiscWarning = strMessage;
|
||||
printf("*** %s\n", strMessage.c_str());
|
||||
uiInterface.ThreadSafeMessageBox(strMessage, "Bitcoin", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
|
||||
uiInterface.QueueShutdown();
|
||||
StartShutdown();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1926,12 +1926,11 @@ bool LoadBlockIndex(bool fAllowNew)
|
|||
{
|
||||
if (fTestNet)
|
||||
{
|
||||
hashGenesisBlock = uint256("0x00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008");
|
||||
bnProofOfWorkLimit = CBigNum(~uint256(0) >> 28);
|
||||
pchMessageStart[0] = 0xfa;
|
||||
pchMessageStart[1] = 0xbf;
|
||||
pchMessageStart[2] = 0xb5;
|
||||
pchMessageStart[3] = 0xda;
|
||||
hashGenesisBlock = uint256("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943");
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1977,8 +1976,7 @@ bool LoadBlockIndex(bool fAllowNew)
|
|||
if (fTestNet)
|
||||
{
|
||||
block.nTime = 1296688602;
|
||||
block.nBits = 0x1d07fff8;
|
||||
block.nNonce = 384568319;
|
||||
block.nNonce = 414098458;
|
||||
}
|
||||
|
||||
//// debug print
|
||||
|
@ -2304,7 +2302,7 @@ unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
|
|||
|
||||
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
{
|
||||
static map<CService, vector<unsigned char> > mapReuseKey;
|
||||
static map<CService, CPubKey> mapReuseKey;
|
||||
RandAddSeedPerfmon();
|
||||
if (fDebug)
|
||||
printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
|
||||
|
@ -2379,7 +2377,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
if (!pfrom->fInbound)
|
||||
{
|
||||
// Advertise our address
|
||||
if (!fNoListen && !fUseProxy && !IsInitialBlockDownload())
|
||||
if (!fNoListen && !IsInitialBlockDownload())
|
||||
{
|
||||
CAddress addr = GetLocalAddress(&pfrom->addr);
|
||||
if (addr.IsRoutable())
|
||||
|
@ -3015,8 +3013,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||
// Keep-alive ping. We send a nonce of zero because we don't use it anywhere
|
||||
// right now.
|
||||
if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) {
|
||||
uint64 nonce = 0;
|
||||
if (pto->nVersion > BIP0031_VERSION)
|
||||
pto->PushMessage("ping", 0);
|
||||
pto->PushMessage("ping", nonce);
|
||||
else
|
||||
pto->PushMessage("ping");
|
||||
}
|
||||
|
@ -3037,7 +3036,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||
pnode->setAddrKnown.clear();
|
||||
|
||||
// Rebroadcast our address
|
||||
if (!fNoListen && !fUseProxy)
|
||||
if (!fNoListen)
|
||||
{
|
||||
CAddress addr = GetLocalAddress(&pnode->addr);
|
||||
if (addr.IsRoutable())
|
||||
|
|
54
src/net.cpp
54
src/net.cpp
|
@ -47,7 +47,8 @@ struct LocalServiceInfo {
|
|||
// Global state variables
|
||||
//
|
||||
bool fClient = false;
|
||||
static bool fUseUPnP = false;
|
||||
bool fDiscover = true;
|
||||
bool fUseUPnP = false;
|
||||
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
|
||||
static CCriticalSection cs_mapLocalHost;
|
||||
static map<CNetAddr, LocalServiceInfo> mapLocalHost;
|
||||
|
@ -99,7 +100,7 @@ void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
|
|||
// find 'best' local address for a particular peer
|
||||
bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
|
||||
{
|
||||
if (fUseProxy || mapArgs.count("-connect") || fNoListen)
|
||||
if (fNoListen)
|
||||
return false;
|
||||
|
||||
int nBestScore = -1;
|
||||
|
@ -211,7 +212,7 @@ bool AddLocal(const CService& addr, int nScore)
|
|||
if (!addr.IsRoutable())
|
||||
return false;
|
||||
|
||||
if (!GetBoolArg("-discover", true) && nScore < LOCAL_MANUAL)
|
||||
if (!fDiscover && nScore < LOCAL_MANUAL)
|
||||
return false;
|
||||
|
||||
if (IsLimited(addr))
|
||||
|
@ -345,9 +346,6 @@ bool GetMyExternalIP(CNetAddr& ipRet)
|
|||
const char* pszGet;
|
||||
const char* pszKeyword;
|
||||
|
||||
if (fNoListen||fUseProxy)
|
||||
return false;
|
||||
|
||||
for (int nLookup = 0; nLookup <= 1; nLookup++)
|
||||
for (int nHost = 1; nHost <= 2; nHost++)
|
||||
{
|
||||
|
@ -542,7 +540,7 @@ void CNode::PushVersion()
|
|||
{
|
||||
/// when NTP implemented, change to just nTime = GetAdjustedTime()
|
||||
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
|
||||
CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
|
||||
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
|
||||
CAddress addrMe = GetLocalAddress(&addr);
|
||||
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
|
||||
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
|
||||
|
@ -1016,7 +1014,7 @@ void ThreadMapPort2(void* parg)
|
|||
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
|
||||
if (r == 1)
|
||||
{
|
||||
if (GetBoolArg("-discover", true)) {
|
||||
if (fDiscover) {
|
||||
char externalIPAddress[40];
|
||||
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
|
||||
if(r != UPNPCOMMAND_SUCCESS)
|
||||
|
@ -1093,12 +1091,8 @@ void ThreadMapPort2(void* parg)
|
|||
}
|
||||
}
|
||||
|
||||
void MapPort(bool fMapPort)
|
||||
void MapPort()
|
||||
{
|
||||
if (fUseUPnP != fMapPort)
|
||||
{
|
||||
fUseUPnP = fMapPort;
|
||||
}
|
||||
if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
|
||||
{
|
||||
if (!CreateThread(ThreadMapPort, NULL))
|
||||
|
@ -1106,7 +1100,7 @@ void MapPort(bool fMapPort)
|
|||
}
|
||||
}
|
||||
#else
|
||||
void MapPort(bool /* unused fMapPort */)
|
||||
void MapPort()
|
||||
{
|
||||
// Intentionally left blank.
|
||||
}
|
||||
|
@ -1160,7 +1154,7 @@ void ThreadDNSAddressSeed2(void* parg)
|
|||
printf("Loading addresses from DNS seeds (could take a while)\n");
|
||||
|
||||
for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
|
||||
if (fProxyNameLookup) {
|
||||
if (GetNameProxy()) {
|
||||
AddOneShot(strDNSSeed[seed_idx][1]);
|
||||
} else {
|
||||
vector<CNetAddr> vaddr;
|
||||
|
@ -1394,8 +1388,7 @@ void ThreadOpenConnections2(void* parg)
|
|||
return;
|
||||
|
||||
// Add seed nodes if IRC isn't working
|
||||
bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
|
||||
if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
|
||||
if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
|
||||
{
|
||||
std::vector<CAddress> vAdd;
|
||||
for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
|
||||
|
@ -1492,7 +1485,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
|||
if (mapArgs.count("-addnode") == 0)
|
||||
return;
|
||||
|
||||
if (fProxyNameLookup) {
|
||||
if (GetNameProxy()) {
|
||||
while(!fShutdown) {
|
||||
BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
|
||||
CAddress addr;
|
||||
|
@ -1665,7 +1658,7 @@ void ThreadMessageHandler2(void* parg)
|
|||
vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
|
||||
Sleep(100);
|
||||
if (fRequestShutdown)
|
||||
Shutdown(NULL);
|
||||
StartShutdown();
|
||||
vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
|
||||
if (fShutdown)
|
||||
return;
|
||||
|
@ -1778,7 +1771,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
|||
|
||||
vhListenSocket.push_back(hListenSocket);
|
||||
|
||||
if (addrBind.IsRoutable() && GetBoolArg("-discover", true))
|
||||
if (addrBind.IsRoutable() && fDiscover)
|
||||
AddLocal(addrBind, LOCAL_BIND);
|
||||
|
||||
return true;
|
||||
|
@ -1786,7 +1779,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
|||
|
||||
void static Discover()
|
||||
{
|
||||
if (!GetBoolArg("-discover", true))
|
||||
if (!fDiscover)
|
||||
return;
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -1835,22 +1828,11 @@ void static Discover()
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!fUseProxy && !mapArgs.count("-connect") && !fNoListen)
|
||||
{
|
||||
CreateThread(ThreadGetMyExternalIP, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void StartNode(void* parg)
|
||||
{
|
||||
#ifdef USE_UPNP
|
||||
#if USE_UPNP
|
||||
fUseUPnP = GetBoolArg("-upnp", true);
|
||||
#else
|
||||
fUseUPnP = GetBoolArg("-upnp", false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (semOutbound == NULL) {
|
||||
// initialize semaphore
|
||||
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
|
||||
|
@ -1873,8 +1855,8 @@ void StartNode(void* parg)
|
|||
printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
|
||||
|
||||
// Map ports with UPnP
|
||||
if (fHaveUPnP)
|
||||
MapPort(fUseUPnP);
|
||||
if (fUseUPnP)
|
||||
MapPort();
|
||||
|
||||
// Get addresses from IRC and advertise ours
|
||||
if (!CreateThread(ThreadIRCSeed, NULL))
|
||||
|
@ -1930,7 +1912,9 @@ bool StopNode()
|
|||
if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
|
||||
if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
|
||||
if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
|
||||
if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
|
||||
#ifdef USE_UPNP
|
||||
if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
|
||||
#endif
|
||||
if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
|
||||
if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
|
||||
if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
|
||||
|
|
|
@ -36,7 +36,7 @@ void AddressCurrentlyConnected(const CService& addr);
|
|||
CNode* FindNode(const CNetAddr& ip);
|
||||
CNode* FindNode(const CService& ip);
|
||||
CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0);
|
||||
void MapPort(bool fMapPort);
|
||||
void MapPort();
|
||||
unsigned short GetListenPort();
|
||||
bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
|
||||
void StartNode(void* parg);
|
||||
|
@ -110,6 +110,8 @@ enum threadId
|
|||
};
|
||||
|
||||
extern bool fClient;
|
||||
extern bool fDiscover;
|
||||
extern bool fUseUPnP;
|
||||
extern uint64 nLocalServices;
|
||||
extern uint64 nLocalHostNonce;
|
||||
extern boost::array<int, THREAD_MAX> vnThreadsRunning;
|
||||
|
|
|
@ -16,14 +16,11 @@
|
|||
using namespace std;
|
||||
|
||||
// Settings
|
||||
int nSocksVersion = 5;
|
||||
int fUseProxy = false;
|
||||
bool fProxyNameLookup = false;
|
||||
bool fNameLookup = false;
|
||||
CService addrProxy("127.0.0.1",9050);
|
||||
typedef std::pair<CService, int> proxyType;
|
||||
static proxyType proxyInfo[NET_MAX];
|
||||
static proxyType nameproxyInfo;
|
||||
int nConnectTimeout = 5000;
|
||||
static bool vfNoProxy[NET_MAX] = {};
|
||||
|
||||
bool fNameLookup = false;
|
||||
|
||||
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
|
||||
|
||||
|
@ -36,11 +33,6 @@ enum Network ParseNetwork(std::string net) {
|
|||
return NET_UNROUTABLE;
|
||||
}
|
||||
|
||||
void SetNoProxy(enum Network net, bool fNoProxy) {
|
||||
assert(net >= 0 && net < NET_MAX);
|
||||
vfNoProxy[net] = fNoProxy;
|
||||
}
|
||||
|
||||
bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
|
||||
{
|
||||
vIP.clear();
|
||||
|
@ -431,29 +423,71 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) {
|
||||
assert(net >= 0 && net < NET_MAX);
|
||||
if (nSocksVersion != 0 && nSocksVersion != 4 && nSocksVersion != 5)
|
||||
return false;
|
||||
if (nSocksVersion != 0 && !addrProxy.IsValid())
|
||||
return false;
|
||||
proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetProxy(enum Network net, CService &addrProxy) {
|
||||
assert(net >= 0 && net < NET_MAX);
|
||||
if (!proxyInfo[net].second)
|
||||
return false;
|
||||
addrProxy = proxyInfo[net].first;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetNameProxy(CService addrProxy, int nSocksVersion) {
|
||||
if (nSocksVersion != 0 && nSocksVersion != 5)
|
||||
return false;
|
||||
if (nSocksVersion != 0 && !addrProxy.IsValid())
|
||||
return false;
|
||||
nameproxyInfo = std::make_pair(addrProxy, nSocksVersion);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetNameProxy() {
|
||||
return nameproxyInfo.second != 0;
|
||||
}
|
||||
|
||||
bool IsProxy(const CNetAddr &addr) {
|
||||
for (int i=0; i<NET_MAX; i++) {
|
||||
if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
|
||||
{
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
bool fProxy = (fUseProxy && addrDest.IsRoutable() && !vfNoProxy[addrDest.GetNetwork()]);
|
||||
const proxyType &proxy = proxyInfo[addrDest.GetNetwork()];
|
||||
|
||||
if (!ConnectSocketDirectly(fProxy ? addrProxy : addrDest, hSocket, nTimeout))
|
||||
// no proxy needed
|
||||
if (!proxy.second)
|
||||
return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
|
||||
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
|
||||
// first connect to proxy server
|
||||
if (!ConnectSocketDirectly(proxy.first, hSocket, nTimeout))
|
||||
return false;
|
||||
|
||||
if (fProxy)
|
||||
{
|
||||
switch(nSocksVersion)
|
||||
{
|
||||
// do socks negotiation
|
||||
switch (proxy.second) {
|
||||
case 4:
|
||||
if (!Socks4(addrDest, hSocket))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
default:
|
||||
if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
hSocketRet = hSocket;
|
||||
|
@ -465,6 +499,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
|
|||
string strDest(pszDest);
|
||||
int port = portDefault;
|
||||
|
||||
// split hostname and port
|
||||
size_t colon = strDest.find_last_of(':');
|
||||
if (colon != strDest.npos) {
|
||||
char *endp = NULL;
|
||||
|
@ -479,22 +514,22 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
|
|||
strDest = strDest.substr(1, strDest.size()-2);
|
||||
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
CService addrResolved(CNetAddr(strDest, fNameLookup && !fProxyNameLookup), port);
|
||||
CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxyInfo.second), port);
|
||||
if (addrResolved.IsValid()) {
|
||||
addr = addrResolved;
|
||||
return ConnectSocket(addr, hSocketRet, nTimeout);
|
||||
}
|
||||
addr = CService("0.0.0.0:0");
|
||||
if (!fNameLookup)
|
||||
if (!nameproxyInfo.second)
|
||||
return false;
|
||||
if (!ConnectSocketDirectly(addrProxy, hSocket, nTimeout))
|
||||
if (!ConnectSocketDirectly(nameproxyInfo.first, hSocket, nTimeout))
|
||||
return false;
|
||||
|
||||
switch(nSocksVersion)
|
||||
switch(nameproxyInfo.second)
|
||||
{
|
||||
default:
|
||||
case 4: return false;
|
||||
case 5:
|
||||
default:
|
||||
if (!Socks5(strDest, port, hSocket))
|
||||
return false;
|
||||
break;
|
||||
|
@ -975,7 +1010,7 @@ bool operator<(const CService& a, const CService& b)
|
|||
bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
|
||||
{
|
||||
if (IsIPv4()) {
|
||||
if (*addrlen < sizeof(struct sockaddr_in))
|
||||
if (*addrlen < (socklen_t)sizeof(struct sockaddr_in))
|
||||
return false;
|
||||
*addrlen = sizeof(struct sockaddr_in);
|
||||
struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr;
|
||||
|
@ -988,7 +1023,7 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
|
|||
}
|
||||
#ifdef USE_IPV6
|
||||
if (IsIPv6()) {
|
||||
if (*addrlen < sizeof(struct sockaddr_in6))
|
||||
if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6))
|
||||
return false;
|
||||
*addrlen = sizeof(struct sockaddr_in6);
|
||||
struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr;
|
||||
|
|
|
@ -28,8 +28,8 @@ enum Network
|
|||
NET_MAX
|
||||
};
|
||||
|
||||
enum Network ParseNetwork(std::string net);
|
||||
void SetNoProxy(enum Network net, bool fNoProxy = true);
|
||||
extern int nConnectTimeout;
|
||||
extern bool fNameLookup;
|
||||
|
||||
/** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */
|
||||
class CNetAddr
|
||||
|
@ -132,6 +132,12 @@ class CService : public CNetAddr
|
|||
)
|
||||
};
|
||||
|
||||
enum Network ParseNetwork(std::string net);
|
||||
bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion = 5);
|
||||
bool GetProxy(enum Network net, CService &addrProxy);
|
||||
bool IsProxy(const CNetAddr &addr);
|
||||
bool SetNameProxy(CService addrProxy, int nSocksVersion = 5);
|
||||
bool GetNameProxy();
|
||||
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);
|
||||
bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0);
|
||||
bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
|
||||
|
@ -140,11 +146,4 @@ bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
|
|||
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
|
||||
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout);
|
||||
|
||||
// Settings
|
||||
extern int nSocksVersion;
|
||||
extern int fUseProxy;
|
||||
extern bool fProxyNameLookup;
|
||||
extern bool fNameLookup;
|
||||
extern CService addrProxy;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,16 +20,9 @@ static bool noui_ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCapt
|
|||
return true;
|
||||
}
|
||||
|
||||
static void noui_QueueShutdown()
|
||||
{
|
||||
// Without UI, Shutdown can simply be started in a new thread
|
||||
CreateThread(Shutdown, NULL);
|
||||
}
|
||||
|
||||
void noui_connect()
|
||||
{
|
||||
// Connect bitcoind signal handlers
|
||||
uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);
|
||||
uiInterface.ThreadSafeAskFee.connect(noui_ThreadSafeAskFee);
|
||||
uiInterface.QueueShutdown.connect(noui_QueueShutdown);
|
||||
}
|
||||
|
|
|
@ -136,11 +136,6 @@ void AddressBookPage::setModel(AddressTableModel *model)
|
|||
connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||
this, SLOT(selectNewAddress(QModelIndex,int,int)));
|
||||
|
||||
if(mode == ForSending)
|
||||
{
|
||||
// Auto-select first row when in sending mode
|
||||
ui->tableView->selectRow(0);
|
||||
}
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "walletmodel.h"
|
||||
|
||||
#include "wallet.h"
|
||||
#include "base58.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QColor>
|
||||
|
@ -58,11 +59,11 @@ public:
|
|||
cachedAddressTable.clear();
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook)
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& item, wallet->mapAddressBook)
|
||||
{
|
||||
const CBitcoinAddress& address = item.first;
|
||||
const std::string& strName = item.second;
|
||||
bool fMine = wallet->HaveKey(address);
|
||||
bool fMine = IsMine(*wallet, address.Get());
|
||||
cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending,
|
||||
QString::fromStdString(strName),
|
||||
QString::fromStdString(address.ToString())));
|
||||
|
@ -220,7 +221,8 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
|
|||
switch(index.column())
|
||||
{
|
||||
case Label:
|
||||
wallet->SetAddressBookName(rec->address.toStdString(), value.toString().toStdString());
|
||||
wallet->SetAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get(), value.toString().toStdString());
|
||||
rec->label = value.toString();
|
||||
break;
|
||||
case Address:
|
||||
// Refuse to set invalid address, set error status and return false
|
||||
|
@ -235,9 +237,9 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
|
|||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
// Remove old entry
|
||||
wallet->DelAddressBookName(rec->address.toStdString());
|
||||
wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get());
|
||||
// Add new entry with new address
|
||||
wallet->SetAddressBookName(value.toString().toStdString(), rec->label.toStdString());
|
||||
wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()).Get(), rec->label.toStdString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -314,7 +316,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||
// Check for duplicate addresses
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
if(wallet->mapAddressBook.count(strAddress))
|
||||
if(wallet->mapAddressBook.count(CBitcoinAddress(strAddress).Get()))
|
||||
{
|
||||
editStatus = DUPLICATE_ADDRESS;
|
||||
return QString();
|
||||
|
@ -331,13 +333,13 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||
editStatus = WALLET_UNLOCK_FAILURE;
|
||||
return QString();
|
||||
}
|
||||
std::vector<unsigned char> newKey;
|
||||
CPubKey newKey;
|
||||
if(!wallet->GetKeyFromPool(newKey, true))
|
||||
{
|
||||
editStatus = KEY_GENERATION_FAILURE;
|
||||
return QString();
|
||||
}
|
||||
strAddress = CBitcoinAddress(newKey).ToString();
|
||||
strAddress = CBitcoinAddress(newKey.GetID()).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -346,7 +348,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||
// Add entry
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
wallet->SetAddressBookName(strAddress, strLabel);
|
||||
wallet->SetAddressBookName(CBitcoinAddress(strAddress).Get(), strLabel);
|
||||
}
|
||||
return QString::fromStdString(strAddress);
|
||||
}
|
||||
|
@ -363,7 +365,7 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
|
|||
}
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
wallet->DelAddressBookName(rec->address.toStdString());
|
||||
wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -375,7 +377,7 @@ QString AddressTableModel::labelForAddress(const QString &address) const
|
|||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
CBitcoinAddress address_parsed(address.toStdString());
|
||||
std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed);
|
||||
std::map<CTxDestination, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed.Get());
|
||||
if (mi != wallet->mapAddressBook.end())
|
||||
{
|
||||
return QString::fromStdString(mi->second);
|
||||
|
|
|
@ -113,54 +113,6 @@ static void handleRunawayException(std::exception *e)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/** Help message for Bitcoin-Qt, shown with --help. */
|
||||
class HelpMessageBox: public QMessageBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HelpMessageBox(QWidget *parent = 0);
|
||||
|
||||
void exec();
|
||||
private:
|
||||
QString header;
|
||||
QString coreOptions;
|
||||
QString uiOptions;
|
||||
};
|
||||
|
||||
HelpMessageBox::HelpMessageBox(QWidget *parent):
|
||||
QMessageBox(parent)
|
||||
{
|
||||
header = tr("Bitcoin-Qt") + " " + tr("version") + " " +
|
||||
QString::fromStdString(FormatFullVersion()) + "\n\n" +
|
||||
tr("Usage:") + "\n" +
|
||||
" bitcoin-qt [" + tr("options") + "] " + "\n";
|
||||
coreOptions = QString::fromStdString(HelpMessage());
|
||||
uiOptions = tr("UI options") + ":\n" +
|
||||
" -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
|
||||
" -min " + tr("Start minimized") + "\n" +
|
||||
" -splash " + tr("Show splash screen on startup (default: 1)") + "\n";
|
||||
|
||||
setWindowTitle(tr("Bitcoin-Qt"));
|
||||
setTextFormat(Qt::PlainText);
|
||||
// setMinimumWidth is ignored for QMessageBox so put in nonbreaking spaces to make it wider.
|
||||
QChar em_space(0x2003);
|
||||
setText(header + QString(em_space).repeated(40));
|
||||
setDetailedText(coreOptions + "\n" + uiOptions);
|
||||
}
|
||||
#include "bitcoin.moc"
|
||||
|
||||
void HelpMessageBox::exec()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
// On windows, show a message box, as there is no stderr in windowed applications
|
||||
QMessageBox::exec();
|
||||
#else
|
||||
// On other operating systems, the expected action is to print the message to the console.
|
||||
QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions;
|
||||
fprintf(stderr, "%s", strUsage.toStdString().c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BITCOIN_QT_TEST
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -259,7 +211,7 @@ int main(int argc, char *argv[])
|
|||
// but before showing splash screen.
|
||||
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
||||
{
|
||||
HelpMessageBox help;
|
||||
GUIUtil::HelpMessageBox help;
|
||||
help.exec();
|
||||
return 1;
|
||||
}
|
||||
|
@ -338,6 +290,7 @@ int main(int argc, char *argv[])
|
|||
window.setWalletModel(0);
|
||||
guiref = 0;
|
||||
}
|
||||
// Shutdown the core and it's threads, but don't exit Bitcoin-Qt here
|
||||
Shutdown(NULL);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
<file alias="fi">locale/bitcoin_fi.qm</file>
|
||||
<file alias="fr">locale/bitcoin_fr.qm</file>
|
||||
<file alias="fr_CA">locale/bitcoin_fr_CA.qm</file>
|
||||
<file alias="fr_FR">locale/bitcoin_fr_FR.qm</file>
|
||||
<file alias="he">locale/bitcoin_he.qm</file>
|
||||
<file alias="hr">locale/bitcoin_hr.qm</file>
|
||||
<file alias="hu">locale/bitcoin_hu.qm</file>
|
||||
|
|
|
@ -409,17 +409,17 @@ void BitcoinGUI::createTrayIcon()
|
|||
|
||||
// Configuration of the tray icon (or dock icon) icon menu
|
||||
trayIconMenu->addAction(toggleHideAction);
|
||||
trayIconMenu->addAction(openRPCConsoleAction);
|
||||
trayIconMenu->addSeparator();
|
||||
trayIconMenu->addAction(messageAction);
|
||||
trayIconMenu->addAction(verifyMessageAction);
|
||||
trayIconMenu->addAction(sendCoinsAction);
|
||||
trayIconMenu->addAction(receiveCoinsAction);
|
||||
#ifndef FIRST_CLASS_MESSAGING
|
||||
trayIconMenu->addSeparator();
|
||||
#endif
|
||||
trayIconMenu->addAction(sendCoinsAction);
|
||||
trayIconMenu->addAction(receiveCoinsAction);
|
||||
trayIconMenu->addAction(messageAction);
|
||||
trayIconMenu->addAction(verifyMessageAction);
|
||||
trayIconMenu->addSeparator();
|
||||
trayIconMenu->addAction(optionsAction);
|
||||
trayIconMenu->addAction(openRPCConsoleAction);
|
||||
#ifndef Q_WS_MAC // This is built-in on Mac
|
||||
trayIconMenu->addSeparator();
|
||||
trayIconMenu->addAction(quitAction);
|
||||
|
@ -439,28 +439,6 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
|
|||
}
|
||||
#endif
|
||||
|
||||
void BitcoinGUI::toggleHidden()
|
||||
{
|
||||
// activateWindow() (sometimes) helps with keyboard focus on Windows
|
||||
if (isHidden())
|
||||
{
|
||||
show();
|
||||
activateWindow();
|
||||
}
|
||||
else if (isMinimized())
|
||||
{
|
||||
showNormal();
|
||||
activateWindow();
|
||||
}
|
||||
else if (GUIUtil::isObscured(this))
|
||||
{
|
||||
raise();
|
||||
activateWindow();
|
||||
}
|
||||
else
|
||||
hide();
|
||||
}
|
||||
|
||||
void BitcoinGUI::optionsClicked()
|
||||
{
|
||||
if(!clientModel || !clientModel->getOptionsModel())
|
||||
|
@ -766,12 +744,19 @@ void BitcoinGUI::dropEvent(QDropEvent *event)
|
|||
{
|
||||
if(event->mimeData()->hasUrls())
|
||||
{
|
||||
gotoSendCoinsPage();
|
||||
int nValidUrisFound = 0;
|
||||
QList<QUrl> uris = event->mimeData()->urls();
|
||||
foreach(const QUrl &uri, uris)
|
||||
{
|
||||
sendCoinsPage->handleURI(uri.toString());
|
||||
if (sendCoinsPage->handleURI(uri.toString()))
|
||||
nValidUrisFound++;
|
||||
}
|
||||
|
||||
// if valid URIs were found
|
||||
if (nValidUrisFound)
|
||||
gotoSendCoinsPage();
|
||||
else
|
||||
notificator->notify(Notificator::Warning, tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."));
|
||||
}
|
||||
|
||||
event->acceptProposedAction();
|
||||
|
@ -779,13 +764,14 @@ void BitcoinGUI::dropEvent(QDropEvent *event)
|
|||
|
||||
void BitcoinGUI::handleURI(QString strURI)
|
||||
{
|
||||
gotoSendCoinsPage();
|
||||
sendCoinsPage->handleURI(strURI);
|
||||
|
||||
if(!isActiveWindow())
|
||||
activateWindow();
|
||||
|
||||
// URI has to be valid
|
||||
if (sendCoinsPage->handleURI(strURI))
|
||||
{
|
||||
showNormalIfMinimized();
|
||||
gotoSendCoinsPage();
|
||||
}
|
||||
else
|
||||
notificator->notify(Notificator::Warning, tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."));
|
||||
}
|
||||
|
||||
void BitcoinGUI::setEncryptionStatus(int status)
|
||||
|
@ -849,7 +835,7 @@ void BitcoinGUI::changePassphrase()
|
|||
|
||||
void BitcoinGUI::verifyMessage()
|
||||
{
|
||||
VerifyMessageDialog *dlg = new VerifyMessageDialog(walletModel->getAddressTableModel(), this);
|
||||
VerifyMessageDialog *dlg = new VerifyMessageDialog(this);
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dlg->show();
|
||||
}
|
||||
|
@ -867,10 +853,29 @@ void BitcoinGUI::unlockWallet()
|
|||
}
|
||||
}
|
||||
|
||||
void BitcoinGUI::showNormalIfMinimized()
|
||||
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
|
||||
{
|
||||
if(!isVisible()) // Show, if hidden
|
||||
// activateWindow() (sometimes) helps with keyboard focus on Windows
|
||||
if (isHidden())
|
||||
{
|
||||
show();
|
||||
if(isMinimized()) // Unminimize, if minimized
|
||||
activateWindow();
|
||||
}
|
||||
else if (isMinimized())
|
||||
{
|
||||
showNormal();
|
||||
activateWindow();
|
||||
}
|
||||
else if (GUIUtil::isObscured(this))
|
||||
{
|
||||
raise();
|
||||
activateWindow();
|
||||
}
|
||||
else if(fToggleHidden)
|
||||
hide();
|
||||
}
|
||||
|
||||
void BitcoinGUI::toggleHidden()
|
||||
{
|
||||
showNormalIfMinimized(true);
|
||||
}
|
||||
|
|
|
@ -169,9 +169,9 @@ private slots:
|
|||
/** Ask for pass phrase to unlock wallet temporarily */
|
||||
void unlockWallet();
|
||||
|
||||
/** Show window if hidden, unminimize when minimized */
|
||||
void showNormalIfMinimized();
|
||||
/** Hide window if visible, show if hidden */
|
||||
/** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */
|
||||
void showNormalIfMinimized(bool fToggleHidden = false);
|
||||
/** simply calls showNormalIfMinimized(true) for use in SLOT() macro */
|
||||
void toggleHidden();
|
||||
};
|
||||
|
||||
|
|
|
@ -6,114 +6,6 @@
|
|||
#define UNUSED
|
||||
#endif
|
||||
static const char UNUSED *bitcoin_strings[] = {QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Unable to bind to %s on this computer. Bitcoin is probably already running."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %d, %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low "),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "List commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (default: 25)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set database disk log size in megabytes (default: 100)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout (in milliseconds)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks proxy"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Select the version of socks proxy to use (4 or 5, 5 is default)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Do not use proxy for connections to network <net> (IPv4 or IPv6)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Pass DNS requests to (SOCKS5) proxy"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: 8333 or testnet: 18333)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: 125)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (IPv4 or IPv6)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Try to discover public IP address (default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using internet relay chat (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Bind to given address. Use [host]:port notation for IPv6"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using DNS lookup (default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: 100)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Number of seconds to keep misbehaving peers from reconnecting (default: "
|
||||
"86400)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use Universal Plug and Play to map the listening port (default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use Universal Plug and Play to map the listening port (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Detach block and address databases. Increases shutdown time (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Output extra debugging information"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to debugger"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: 8332)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on <ip> (default: 127.0.0.1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Execute command when the best block changes (%s in cmd is replaced by block "
|
||||
"hash)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 2500, 0 = all)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "How thorough the block verification is (0-6, default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000?.dat file"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"\n"
|
||||
"SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:"
|
||||
"@STRENGTH)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Cannot obtain a lock on data directory %s. Bitcoin is probably already "
|
||||
"running."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading addr.dat"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading blkindex.dat"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin to complete"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot initialize keypool"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -noproxy: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown -socks proxy version requested: %i"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Not listening on any port"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: -paytxfee is set very high. This is the transaction fee you will "
|
||||
"pay if you send a transaction."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: could not start node"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"%s, you must set a rpcpassword in the configuration file:\n"
|
||||
" %s\n"
|
||||
"It is recommended you use the following random password:\n"
|
||||
|
@ -122,26 +14,130 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
|||
"(you do not need to remember this password)\n"
|
||||
"If the file does not exist, create it with owner-readable-only file "
|
||||
"permissions.\n"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "An error occured while setting up the RPC port %i for listening: %s"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:"
|
||||
"@STRENGTH)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Cannot obtain a lock on data directory %s. Bitcoin is probably already "
|
||||
"running."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Detach block and address databases. Increases shutdown time (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: The transaction was rejected. This might happen if some of the coins "
|
||||
"in your wallet were already spent, such as if you used a copy of wallet.dat "
|
||||
"and coins were spent in the copy but not marked as spent here."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: This transaction requires a transaction fee of at least %s because of "
|
||||
"its amount, complexity, or use of recently received funds "),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Execute command when the best block changes (%s in cmd is replaced by block "
|
||||
"hash)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Number of seconds to keep misbehaving peers from reconnecting (default: "
|
||||
"86400)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Unable to bind to %s on this computer. Bitcoin is probably already running."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: -paytxfee is set very high. This is the transaction fee you will "
|
||||
"pay if you send a transaction."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: Please check that your computer's date and time are correct. If "
|
||||
"your clock is wrong Bitcoin will not work properly."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"You must set rpcpassword=<password> in the configuration file:\n"
|
||||
"%s\n"
|
||||
"If the file does not exist, create it with owner-readable-only file "
|
||||
"permissions."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: Please check that your computer's date and time are correct. If "
|
||||
"your clock is wrong Bitcoin will not work properly."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction "),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: This transaction requires a transaction fee of at least %s because of "
|
||||
"its amount, complexity, or use of recently received funds "),
|
||||
"\n"
|
||||
"SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "An error occured while setting up the RPC port %i for listening: %s"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Bind to given address. Use [host]:port notation for IPv6"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot initialize keypool"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks proxy"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Discover own IP address (default: 1 when listening and no -externalip)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading blkindex.dat"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Transaction creation failed "),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Sending..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: The transaction was rejected. This might happen if some of the coins "
|
||||
"in your wallet were already spent, such as if you used a copy of wallet.dat "
|
||||
"and coins were spent in the copy but not marked as spent here."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction "),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: could not start node"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using DNS lookup (default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using internet relay chat (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 2500, 0 = all)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "How thorough the block verification is (0-6, default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000?.dat file"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "List commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: 8332)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: 8333 or testnet: 18333)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: 125)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (IPv4 or IPv6)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Output extra debugging information"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Select the version of socks proxy to use (4-5, default: 5)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on <ip> (default: 127.0.0.1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to debugger"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Sending..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (default: 25)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set database disk log size in megabytes (default: 100)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout (in milliseconds)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: 100)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %d, %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown -socks proxy version requested: %i"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 1 when listening)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin to complete"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low"),
|
||||
};
|
|
@ -130,9 +130,9 @@ QString ClientModel::clientName() const
|
|||
return QString::fromStdString(CLIENT_NAME);
|
||||
}
|
||||
|
||||
QDateTime ClientModel::formatClientStartupTime() const
|
||||
QString ClientModel::formatClientStartupTime() const
|
||||
{
|
||||
return QDateTime::fromTime_t(nClientStartupTime);
|
||||
return QDateTime::fromTime_t(nClientStartupTime).toString();
|
||||
}
|
||||
|
||||
// Handlers for core signals
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
QString formatFullVersion() const;
|
||||
QString formatBuildDate() const;
|
||||
QString clientName() const;
|
||||
QDateTime formatClientStartupTime() const;
|
||||
QString formatClientStartupTime() const;
|
||||
|
||||
private:
|
||||
OptionsModel *optionsModel;
|
||||
|
|
466
src/qt/forms/optionsdialog.ui
Normal file
466
src/qt/forms/optionsdialog.ui
Normal file
|
@ -0,0 +1,466 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OptionsDialog</class>
|
||||
<widget class="QDialog" name="OptionsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>540</width>
|
||||
<height>380</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="tabPosition">
|
||||
<enum>QTabWidget::North</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabMain">
|
||||
<attribute name="title">
|
||||
<string>&Main</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Main">
|
||||
<item>
|
||||
<widget class="QLabel" name="transactionFeeInfoLabel">
|
||||
<property name="text">
|
||||
<string>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_Main">
|
||||
<item>
|
||||
<widget class="QLabel" name="transactionFeeLabel">
|
||||
<property name="text">
|
||||
<string>Pay transaction &fee</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>transactionFee</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="BitcoinAmountField" name="transactionFee"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_Main">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="bitcoinAtStartup">
|
||||
<property name="toolTip">
|
||||
<string>Automatically start Bitcoin after logging in to the system.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Start Bitcoin on system login</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="detachDatabases">
|
||||
<property name="toolTip">
|
||||
<string>Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Detach databases at shutdown</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Main">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabNetwork">
|
||||
<attribute name="title">
|
||||
<string>&Network</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Network">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="mapPortUpnp">
|
||||
<property name="toolTip">
|
||||
<string>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Map port using &UPnP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="connectSocks">
|
||||
<property name="toolTip">
|
||||
<string>Connect to the Bitcon network through a SOCKS proxy (e.g. when connecting through Tor).</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Connect through SOCKS proxy:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_Network">
|
||||
<item>
|
||||
<widget class="QLabel" name="proxyIpLabel">
|
||||
<property name="text">
|
||||
<string>Proxy &IP:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>proxyIp</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValidatedLineEdit" name="proxyIp">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>IP address of the proxy (e.g. 127.0.0.1)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="proxyPortLabel">
|
||||
<property name="text">
|
||||
<string>&Port:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>proxyPort</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="proxyPort">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>55</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Port of the proxy (e.g. 9050)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="socksVersionLabel">
|
||||
<property name="text">
|
||||
<string>SOCKS &Version:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>socksVersion</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValueComboBox" name="socksVersion">
|
||||
<property name="toolTip">
|
||||
<string>SOCKS version of the proxy (e.g. 5)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_Network">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Network">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabWindow">
|
||||
<attribute name="title">
|
||||
<string>&Window</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Window">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="minimizeToTray">
|
||||
<property name="toolTip">
|
||||
<string>Show only a tray icon after minimizing the window.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Minimize to the tray instead of the taskbar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="minimizeOnClose">
|
||||
<property name="toolTip">
|
||||
<string>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>M&inimize on close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Window">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabDisplay">
|
||||
<attribute name="title">
|
||||
<string>&Display</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Display">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1_Display">
|
||||
<item>
|
||||
<widget class="QLabel" name="langLabel">
|
||||
<property name="text">
|
||||
<string>User Interface &language:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lang</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValueComboBox" name="lang">
|
||||
<property name="toolTip">
|
||||
<string>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2_Display">
|
||||
<item>
|
||||
<widget class="QLabel" name="unitLabel">
|
||||
<property name="text">
|
||||
<string>&Unit to show amounts in:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>unit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValueComboBox" name="unit">
|
||||
<property name="toolTip">
|
||||
<string>Choose the default subdivision unit to show in the interface and when sending coins.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="displayAddresses">
|
||||
<property name="toolTip">
|
||||
<string>Whether to show Bitcoin addresses in the transaction list or not.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Display addresses in transaction list</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Display">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_Buttons">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="okButton">
|
||||
<property name="text">
|
||||
<string>&OK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="text">
|
||||
<string>&Cancel</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="applyButton">
|
||||
<property name="text">
|
||||
<string>&Apply</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>BitcoinAmountField</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>bitcoinamountfield.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QValueComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>qvaluecombobox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QValidatedLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>qvalidatedlineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>552</width>
|
||||
<width>573</width>
|
||||
<height>342</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -105,7 +105,7 @@
|
|||
<string>Your current balance</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">123.456 BTC</string>
|
||||
<string notr="true">0 BTC</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
|
@ -141,14 +141,14 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Number of transactions:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="labelNumTransactions">
|
||||
<property name="toolTip">
|
||||
<string>Total number of transactions in wallet</string>
|
||||
|
@ -158,6 +158,32 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelImmatureText">
|
||||
<property name="text">
|
||||
<string>Immature:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="labelImmature">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Mined balance that has not yet matured</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">0 BTC</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>706</width>
|
||||
<height>446</height>
|
||||
<width>740</width>
|
||||
<height>450</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -301,9 +301,38 @@
|
|||
<property name="text">
|
||||
<string>&Open</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QLabel" name="labelCLOptions">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Command-line options</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<widget class="QPushButton" name="showCLOptionsButton">
|
||||
<property name="toolTip">
|
||||
<string>Show the Bitcoin-Qt help message to get a list with possible Bitcoin command-line options.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Show</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>494</width>
|
||||
<height>342</height>
|
||||
<width>650</width>
|
||||
<height>380</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -17,7 +17,7 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Enter the message and signature below (be careful to correctly copy newlines, spaces, tabs and other invisible characters) to obtain the Bitcoin address used to sign the message.</string>
|
||||
<string>Enter the signing address, signature and message below (be careful to correctly copy newlines, spaces, tabs and other invisible characters) to verify the message.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
|
@ -27,39 +27,29 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValidatedLineEdit" name="lnAddress">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValidatedLineEdit" name="lnSig">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="edMessage"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lnSig">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lnAddress">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblStatus">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="verifyMessage">
|
||||
<property name="toolTip">
|
||||
<string>Verify a message and obtain the Bitcoin address used to sign the message</string>
|
||||
<string>Verify a message to ensure it was signed with the specified Bitcoin address</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Verify Message</string>
|
||||
|
@ -70,23 +60,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="copyToClipboard">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Copy the currently selected address to the system clipboard</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Copy Address</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearButton">
|
||||
<property name="toolTip">
|
||||
|
@ -101,6 +74,41 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblStatus">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
@ -118,6 +126,13 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QValidatedLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>qvalidatedlineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "walletmodel.h"
|
||||
#include "bitcoinunits.h"
|
||||
#include "util.h"
|
||||
#include "init.h"
|
||||
#include "base58.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
|
@ -35,6 +37,8 @@
|
|||
#define NOMINMAX
|
||||
#endif
|
||||
#include "shlwapi.h"
|
||||
#include "shlobj.h"
|
||||
#include "shellapi.h"
|
||||
#endif
|
||||
|
||||
namespace GUIUtil {
|
||||
|
@ -77,6 +81,11 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
|
|||
if(uri.scheme() != QString("bitcoin"))
|
||||
return false;
|
||||
|
||||
// check if the address is valid
|
||||
CBitcoinAddress addressFromUri(uri.path().toStdString());
|
||||
if (!addressFromUri.IsValid())
|
||||
return false;
|
||||
|
||||
SendCoinsRecipient rv;
|
||||
rv.address = uri.path();
|
||||
rv.amount = 0;
|
||||
|
@ -220,29 +229,26 @@ Qt::ConnectionType blockingGUIThreadConnection()
|
|||
bool checkPoint(const QPoint &p, const QWidget *w)
|
||||
{
|
||||
QWidget *atW = qApp->widgetAt(w->mapToGlobal(p));
|
||||
if(!atW) return false;
|
||||
if (!atW) return false;
|
||||
return atW->topLevelWidget() == w;
|
||||
}
|
||||
|
||||
bool isObscured(QWidget *w)
|
||||
{
|
||||
|
||||
return !(checkPoint(QPoint(0, 0), w)
|
||||
&& checkPoint(QPoint(w->width() - 1, 0), w)
|
||||
&& checkPoint(QPoint(0, w->height() - 1), w)
|
||||
&& checkPoint(QPoint(w->width() - 1, w->height() - 1), w)
|
||||
&& checkPoint(QPoint(w->width()/2, w->height()/2), w));
|
||||
&& checkPoint(QPoint(w->width() / 2, w->height() / 2), w));
|
||||
}
|
||||
|
||||
void openDebugLogfile()
|
||||
{
|
||||
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
|
||||
|
||||
#ifdef WIN32
|
||||
if (boost::filesystem::exists(pathDebug))
|
||||
/* Open debug.log with the associated application */
|
||||
ShellExecuteA((HWND)0, (LPCSTR)"open", (LPCSTR)pathDebug.string().c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
#endif
|
||||
if (boost::filesystem::exists(pathDebug))
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(pathDebug.string())));
|
||||
}
|
||||
|
||||
ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) :
|
||||
|
@ -413,5 +419,39 @@ bool SetStartOnSystemStartup(bool fAutoStart) { return false; }
|
|||
|
||||
#endif
|
||||
|
||||
HelpMessageBox::HelpMessageBox(QWidget *parent) :
|
||||
QMessageBox(parent)
|
||||
{
|
||||
header = tr("Bitcoin-Qt") + " " + tr("version") + " " +
|
||||
QString::fromStdString(FormatFullVersion()) + "\n\n" +
|
||||
tr("Usage:") + "\n" +
|
||||
" bitcoin-qt [" + tr("command-line options") + "] " + "\n";
|
||||
|
||||
coreOptions = QString::fromStdString(HelpMessage());
|
||||
|
||||
uiOptions = tr("UI options") + ":\n" +
|
||||
" -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
|
||||
" -min " + tr("Start minimized") + "\n" +
|
||||
" -splash " + tr("Show splash screen on startup (default: 1)") + "\n";
|
||||
|
||||
setWindowTitle(tr("Bitcoin-Qt"));
|
||||
setTextFormat(Qt::PlainText);
|
||||
// setMinimumWidth is ignored for QMessageBox so put in nonbreaking spaces to make it wider.
|
||||
setText(header + QString(QChar(0x2003)).repeated(50));
|
||||
setDetailedText(coreOptions + "\n" + uiOptions);
|
||||
}
|
||||
|
||||
void HelpMessageBox::exec()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
// On windows, show a message box, as there is no stderr in windowed applications
|
||||
QMessageBox::exec();
|
||||
#else
|
||||
// On other operating systems, the expected action is to print the message to the console.
|
||||
QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions;
|
||||
fprintf(stderr, "%s", strUsage.toStdString().c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace GUIUtil
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <QMessageBox>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFont;
|
||||
|
@ -80,6 +81,7 @@ namespace GUIUtil
|
|||
class ToolTipToRichTextFilter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ToolTipToRichTextFilter(int size_threshold, QObject *parent = 0);
|
||||
|
||||
|
@ -93,6 +95,22 @@ namespace GUIUtil
|
|||
bool GetStartOnSystemStartup();
|
||||
bool SetStartOnSystemStartup(bool fAutoStart);
|
||||
|
||||
/** Help message for Bitcoin-Qt, shown with --help. */
|
||||
class HelpMessageBox : public QMessageBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HelpMessageBox(QWidget *parent = 0);
|
||||
|
||||
void exec();
|
||||
|
||||
private:
|
||||
QString header;
|
||||
QString coreOptions;
|
||||
QString uiOptions;
|
||||
};
|
||||
|
||||
} // namespace GUIUtil
|
||||
|
||||
#endif // GUIUTIL_H
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -10,6 +10,7 @@
|
|||
#include "main.h"
|
||||
#include "wallet.h"
|
||||
#include "init.h"
|
||||
#include "base58.h"
|
||||
|
||||
#include "messagepage.h"
|
||||
#include "ui_messagepage.h"
|
||||
|
@ -83,6 +84,13 @@ void MessagePage::on_signMessage_clicked()
|
|||
QMessageBox::Abort, QMessageBox::Abort);
|
||||
return;
|
||||
}
|
||||
CKeyID keyID;
|
||||
if (!addr.GetKeyID(keyID))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error signing"), tr("%1 does not refer to a key.").arg(address),
|
||||
QMessageBox::Abort, QMessageBox::Abort);
|
||||
return;
|
||||
}
|
||||
|
||||
WalletModel::UnlockContext ctx(model->requestUnlock());
|
||||
if(!ctx.isValid())
|
||||
|
@ -92,7 +100,7 @@ void MessagePage::on_signMessage_clicked()
|
|||
}
|
||||
|
||||
CKey key;
|
||||
if (!pwalletMain->GetKey(addr, key))
|
||||
if (!pwalletMain->GetKey(keyID, key))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error signing"), tr("Private key for %1 is not available.").arg(address),
|
||||
QMessageBox::Abort, QMessageBox::Abort);
|
||||
|
|
|
@ -1,396 +1,218 @@
|
|||
#include "optionsdialog.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "ui_optionsdialog.h"
|
||||
|
||||
#include "bitcoinamountfield.h"
|
||||
#include "monitoreddatamapper.h"
|
||||
#include "guiutil.h"
|
||||
#include "bitcoinunits.h"
|
||||
#include "monitoreddatamapper.h"
|
||||
#include "netbase.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "qvalidatedlineedit.h"
|
||||
#include "qvaluecombobox.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QListWidget>
|
||||
#include <QStackedWidget>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDir>
|
||||
#include <QIntValidator>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QIntValidator>
|
||||
#include <QDoubleValidator>
|
||||
#include <QRegExpValidator>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QRegExp>
|
||||
#include <QRegExpValidator>
|
||||
#include <QTabWidget>
|
||||
#include <QWidget>
|
||||
|
||||
class OptionsPage: public QWidget
|
||||
OptionsDialog::OptionsDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::OptionsDialog),
|
||||
model(0),
|
||||
mapper(0),
|
||||
fRestartWarningDisplayed_Proxy(false),
|
||||
fRestartWarningDisplayed_Lang(false),
|
||||
fProxyIpValid(true)
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OptionsPage(QWidget *parent=0): QWidget(parent) {}
|
||||
ui->setupUi(this);
|
||||
|
||||
virtual void setMapper(MonitoredDataMapper *mapper) = 0;
|
||||
};
|
||||
|
||||
class MainOptionsPage: public OptionsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainOptionsPage(QWidget *parent=0);
|
||||
|
||||
virtual void setMapper(MonitoredDataMapper *mapper);
|
||||
private:
|
||||
BitcoinAmountField *fee_edit;
|
||||
QCheckBox *bitcoin_at_startup;
|
||||
QCheckBox *detach_database;
|
||||
};
|
||||
|
||||
class WindowOptionsPage: public OptionsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WindowOptionsPage(QWidget *parent=0);
|
||||
|
||||
virtual void setMapper(MonitoredDataMapper *mapper);
|
||||
private:
|
||||
#ifndef Q_WS_MAC
|
||||
QCheckBox *minimize_to_tray;
|
||||
QCheckBox *minimize_on_close;
|
||||
/* Network elements init */
|
||||
#ifndef USE_UPNP
|
||||
ui->mapPortUpnp->setEnabled(false);
|
||||
#endif
|
||||
};
|
||||
|
||||
class DisplayOptionsPage: public OptionsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DisplayOptionsPage(QWidget *parent=0);
|
||||
ui->socksVersion->setEnabled(false);
|
||||
ui->socksVersion->addItem("5", 5);
|
||||
ui->socksVersion->addItem("4", 4);
|
||||
ui->socksVersion->setCurrentIndex(0);
|
||||
|
||||
virtual void setMapper(MonitoredDataMapper *mapper);
|
||||
private:
|
||||
QValueComboBox *lang;
|
||||
QValueComboBox *unit;
|
||||
QCheckBox *display_addresses;
|
||||
bool restart_warning_displayed;
|
||||
private slots:
|
||||
void showRestartWarning();
|
||||
};
|
||||
ui->proxyIp->setEnabled(false);
|
||||
ui->proxyPort->setEnabled(false);
|
||||
ui->proxyPort->setValidator(new QIntValidator(0, 65535, this));
|
||||
|
||||
class NetworkOptionsPage: public OptionsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NetworkOptionsPage(QWidget *parent=0);
|
||||
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->socksVersion, SLOT(setEnabled(bool)));
|
||||
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool)));
|
||||
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool)));
|
||||
|
||||
virtual void setMapper(MonitoredDataMapper *mapper);
|
||||
private:
|
||||
QCheckBox *map_port_upnp;
|
||||
QCheckBox *connect_socks4;
|
||||
QLineEdit *proxy_ip;
|
||||
QLineEdit *proxy_port;
|
||||
};
|
||||
ui->proxyIp->installEventFilter(this);
|
||||
|
||||
|
||||
#include "optionsdialog.moc"
|
||||
|
||||
OptionsDialog::OptionsDialog(QWidget *parent):
|
||||
QDialog(parent), contents_widget(0), pages_widget(0),
|
||||
model(0)
|
||||
{
|
||||
contents_widget = new QListWidget();
|
||||
contents_widget->setMaximumWidth(128);
|
||||
|
||||
pages_widget = new QStackedWidget();
|
||||
pages_widget->setMinimumWidth(500);
|
||||
pages_widget->setMinimumHeight(300);
|
||||
|
||||
pages.append(new MainOptionsPage(this));
|
||||
pages.append(new NetworkOptionsPage(this));
|
||||
#ifndef Q_WS_MAC
|
||||
/* Hide Window options on Mac as there are currently none available */
|
||||
pages.append(new WindowOptionsPage(this));
|
||||
/* Window elements init */
|
||||
#ifdef Q_WS_MAC
|
||||
ui->tabWindow->setVisible(false);
|
||||
#endif
|
||||
pages.append(new DisplayOptionsPage(this));
|
||||
|
||||
foreach(OptionsPage *page, pages)
|
||||
/* Display elements init */
|
||||
QDir translations(":translations");
|
||||
ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
|
||||
foreach(const QString &langStr, translations.entryList())
|
||||
{
|
||||
QListWidgetItem *item = new QListWidgetItem(page->windowTitle());
|
||||
contents_widget->addItem(item);
|
||||
pages_widget->addWidget(page);
|
||||
ui->lang->addItem(langStr, QVariant(langStr));
|
||||
}
|
||||
|
||||
contents_widget->setCurrentRow(0);
|
||||
ui->unit->setModel(new BitcoinUnits(this));
|
||||
|
||||
QHBoxLayout *main_layout = new QHBoxLayout();
|
||||
main_layout->addWidget(contents_widget);
|
||||
main_layout->addWidget(pages_widget, 1);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
layout->addLayout(main_layout);
|
||||
|
||||
QDialogButtonBox *buttonbox = new QDialogButtonBox();
|
||||
buttonbox->setStandardButtons(QDialogButtonBox::Apply|QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
|
||||
apply_button = buttonbox->button(QDialogButtonBox::Apply);
|
||||
layout->addWidget(buttonbox);
|
||||
|
||||
setLayout(layout);
|
||||
setWindowTitle(tr("Options"));
|
||||
connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning_Proxy()));
|
||||
connect(ui->lang, SIGNAL(activated(int)), this, SLOT(showRestartWarning_Lang()));
|
||||
|
||||
/* Widget-to-option mapper */
|
||||
mapper = new MonitoredDataMapper(this);
|
||||
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
|
||||
mapper->setOrientation(Qt::Vertical);
|
||||
/* enable apply button when data modified */
|
||||
connect(mapper, SIGNAL(viewModified()), this, SLOT(enableApply()));
|
||||
/* disable apply button when new data loaded */
|
||||
connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(disableApply()));
|
||||
|
||||
/* Event bindings */
|
||||
connect(contents_widget, SIGNAL(currentRowChanged(int)), this, SLOT(changePage(int)));
|
||||
connect(buttonbox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(okClicked()));
|
||||
connect(buttonbox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(cancelClicked()));
|
||||
connect(buttonbox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyClicked()));
|
||||
/* enable save buttons when data modified */
|
||||
connect(mapper, SIGNAL(viewModified()), this, SLOT(enableSaveButtons()));
|
||||
/* disable save buttons when new data loaded */
|
||||
connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(disableSaveButtons()));
|
||||
/* disable/enable save buttons when proxy IP is invalid/valid */
|
||||
connect(this, SIGNAL(proxyIpValid(bool)), this, SLOT(setSaveButtonState(bool)));
|
||||
}
|
||||
|
||||
OptionsDialog::~OptionsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void OptionsDialog::setModel(OptionsModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
|
||||
mapper->setModel(model);
|
||||
|
||||
foreach(OptionsPage *page, pages)
|
||||
if(model)
|
||||
{
|
||||
page->setMapper(mapper);
|
||||
connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
|
||||
mapper->setModel(model);
|
||||
setMapper();
|
||||
mapper->toFirst();
|
||||
}
|
||||
|
||||
mapper->toFirst();
|
||||
// update the display unit, to not use the default ("BTC")
|
||||
updateDisplayUnit();
|
||||
}
|
||||
|
||||
void OptionsDialog::changePage(int index)
|
||||
void OptionsDialog::setMapper()
|
||||
{
|
||||
pages_widget->setCurrentIndex(index);
|
||||
/* Main */
|
||||
mapper->addMapping(ui->transactionFee, OptionsModel::Fee);
|
||||
mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
|
||||
mapper->addMapping(ui->detachDatabases, OptionsModel::DetachDatabases);
|
||||
|
||||
/* Network */
|
||||
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
|
||||
mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
|
||||
mapper->addMapping(ui->socksVersion, OptionsModel::ProxySocksVersion);
|
||||
mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
|
||||
mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort);
|
||||
|
||||
/* Window */
|
||||
#ifndef Q_WS_MAC
|
||||
mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray);
|
||||
mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose);
|
||||
#endif
|
||||
|
||||
/* Display */
|
||||
mapper->addMapping(ui->lang, OptionsModel::Language);
|
||||
mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
|
||||
mapper->addMapping(ui->displayAddresses, OptionsModel::DisplayAddresses);
|
||||
}
|
||||
|
||||
void OptionsDialog::okClicked()
|
||||
void OptionsDialog::enableSaveButtons()
|
||||
{
|
||||
// prevent enabling of the save buttons when data modified, if there is an invalid proxy address present
|
||||
if(fProxyIpValid)
|
||||
setSaveButtonState(true);
|
||||
}
|
||||
|
||||
void OptionsDialog::disableSaveButtons()
|
||||
{
|
||||
setSaveButtonState(false);
|
||||
}
|
||||
|
||||
void OptionsDialog::setSaveButtonState(bool fState)
|
||||
{
|
||||
ui->applyButton->setEnabled(fState);
|
||||
ui->okButton->setEnabled(fState);
|
||||
}
|
||||
|
||||
void OptionsDialog::on_okButton_clicked()
|
||||
{
|
||||
mapper->submit();
|
||||
accept();
|
||||
}
|
||||
|
||||
void OptionsDialog::cancelClicked()
|
||||
void OptionsDialog::on_cancelButton_clicked()
|
||||
{
|
||||
reject();
|
||||
}
|
||||
|
||||
void OptionsDialog::applyClicked()
|
||||
void OptionsDialog::on_applyButton_clicked()
|
||||
{
|
||||
mapper->submit();
|
||||
apply_button->setEnabled(false);
|
||||
ui->applyButton->setEnabled(false);
|
||||
}
|
||||
|
||||
void OptionsDialog::enableApply()
|
||||
void OptionsDialog::showRestartWarning_Proxy()
|
||||
{
|
||||
apply_button->setEnabled(true);
|
||||
}
|
||||
|
||||
void OptionsDialog::disableApply()
|
||||
{
|
||||
apply_button->setEnabled(false);
|
||||
}
|
||||
|
||||
/* Main options */
|
||||
MainOptionsPage::MainOptionsPage(QWidget *parent):
|
||||
OptionsPage(parent)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
setWindowTitle(tr("Main"));
|
||||
|
||||
QLabel *fee_help = new QLabel(tr("Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended."));
|
||||
fee_help->setWordWrap(true);
|
||||
layout->addWidget(fee_help);
|
||||
|
||||
QHBoxLayout *fee_hbox = new QHBoxLayout();
|
||||
fee_hbox->addSpacing(18);
|
||||
QLabel *fee_label = new QLabel(tr("Pay transaction &fee"));
|
||||
fee_hbox->addWidget(fee_label);
|
||||
fee_edit = new BitcoinAmountField();
|
||||
|
||||
fee_label->setBuddy(fee_edit);
|
||||
fee_hbox->addWidget(fee_edit);
|
||||
fee_hbox->addStretch(1);
|
||||
|
||||
layout->addLayout(fee_hbox);
|
||||
|
||||
bitcoin_at_startup = new QCheckBox(tr("&Start Bitcoin on system login"));
|
||||
bitcoin_at_startup->setToolTip(tr("Automatically start Bitcoin after logging in to the system"));
|
||||
layout->addWidget(bitcoin_at_startup);
|
||||
|
||||
detach_database = new QCheckBox(tr("&Detach databases at shutdown"));
|
||||
detach_database->setToolTip(tr("Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached."));
|
||||
layout->addWidget(detach_database);
|
||||
|
||||
layout->addStretch(1); // Extra space at bottom
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void MainOptionsPage::setMapper(MonitoredDataMapper *mapper)
|
||||
{
|
||||
// Map model to widgets
|
||||
mapper->addMapping(fee_edit, OptionsModel::Fee);
|
||||
mapper->addMapping(bitcoin_at_startup, OptionsModel::StartAtStartup);
|
||||
mapper->addMapping(detach_database, OptionsModel::DetachDatabases);
|
||||
}
|
||||
|
||||
/* Display options */
|
||||
DisplayOptionsPage::DisplayOptionsPage(QWidget *parent):
|
||||
OptionsPage(parent), restart_warning_displayed(false)
|
||||
{
|
||||
setWindowTitle(tr("Display"));
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
|
||||
QHBoxLayout *lang_hbox = new QHBoxLayout();
|
||||
lang_hbox->addSpacing(18);
|
||||
QLabel *lang_label = new QLabel(tr("User Interface &Language:"));
|
||||
lang_hbox->addWidget(lang_label);
|
||||
lang = new QValueComboBox(this);
|
||||
// Make list of languages
|
||||
QDir translations(":translations");
|
||||
lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
|
||||
foreach(const QString &langStr, translations.entryList())
|
||||
{
|
||||
lang->addItem(langStr, QVariant(langStr));
|
||||
}
|
||||
|
||||
lang->setToolTip(tr("The user interface language can be set here. This setting will only take effect after restarting Bitcoin."));
|
||||
connect(lang, SIGNAL(activated(int)), this, SLOT(showRestartWarning()));
|
||||
|
||||
lang_label->setBuddy(lang);
|
||||
lang_hbox->addWidget(lang);
|
||||
|
||||
layout->addLayout(lang_hbox);
|
||||
|
||||
QHBoxLayout *unit_hbox = new QHBoxLayout();
|
||||
unit_hbox->addSpacing(18);
|
||||
QLabel *unit_label = new QLabel(tr("&Unit to show amounts in:"));
|
||||
unit_hbox->addWidget(unit_label);
|
||||
unit = new QValueComboBox(this);
|
||||
unit->setModel(new BitcoinUnits(this));
|
||||
unit->setToolTip(tr("Choose the default subdivision unit to show in the interface, and when sending coins"));
|
||||
|
||||
unit_label->setBuddy(unit);
|
||||
unit_hbox->addWidget(unit);
|
||||
|
||||
layout->addLayout(unit_hbox);
|
||||
|
||||
display_addresses = new QCheckBox(tr("&Display addresses in transaction list"), this);
|
||||
display_addresses->setToolTip(tr("Whether to show Bitcoin addresses in the transaction list"));
|
||||
layout->addWidget(display_addresses);
|
||||
|
||||
layout->addStretch();
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void DisplayOptionsPage::setMapper(MonitoredDataMapper *mapper)
|
||||
{
|
||||
mapper->addMapping(lang, OptionsModel::Language);
|
||||
mapper->addMapping(unit, OptionsModel::DisplayUnit);
|
||||
mapper->addMapping(display_addresses, OptionsModel::DisplayAddresses);
|
||||
}
|
||||
|
||||
void DisplayOptionsPage::showRestartWarning()
|
||||
{
|
||||
if(!restart_warning_displayed)
|
||||
if(!fRestartWarningDisplayed_Proxy)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Bitcoin."), QMessageBox::Ok);
|
||||
restart_warning_displayed = true;
|
||||
fRestartWarningDisplayed_Proxy = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Window options */
|
||||
WindowOptionsPage::WindowOptionsPage(QWidget *parent):
|
||||
OptionsPage(parent)
|
||||
void OptionsDialog::showRestartWarning_Lang()
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
setWindowTitle(tr("Window"));
|
||||
|
||||
#ifndef Q_WS_MAC
|
||||
minimize_to_tray = new QCheckBox(tr("&Minimize to the tray instead of the taskbar"));
|
||||
minimize_to_tray->setToolTip(tr("Show only a tray icon after minimizing the window"));
|
||||
layout->addWidget(minimize_to_tray);
|
||||
|
||||
minimize_on_close = new QCheckBox(tr("M&inimize on close"));
|
||||
minimize_on_close->setToolTip(tr("Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu."));
|
||||
layout->addWidget(minimize_on_close);
|
||||
#endif
|
||||
|
||||
layout->addStretch(1); // Extra space at bottom
|
||||
setLayout(layout);
|
||||
if(!fRestartWarningDisplayed_Lang)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Bitcoin."), QMessageBox::Ok);
|
||||
fRestartWarningDisplayed_Lang = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowOptionsPage::setMapper(MonitoredDataMapper *mapper)
|
||||
void OptionsDialog::updateDisplayUnit()
|
||||
{
|
||||
// Map model to widgets
|
||||
#ifndef Q_WS_MAC
|
||||
mapper->addMapping(minimize_to_tray, OptionsModel::MinimizeToTray);
|
||||
#endif
|
||||
#ifndef Q_WS_MAC
|
||||
mapper->addMapping(minimize_on_close, OptionsModel::MinimizeOnClose);
|
||||
#endif
|
||||
if(model)
|
||||
{
|
||||
// Update transactionFee with the current unit
|
||||
ui->transactionFee->setDisplayUnit(model->getDisplayUnit());
|
||||
}
|
||||
}
|
||||
|
||||
/* Network options */
|
||||
NetworkOptionsPage::NetworkOptionsPage(QWidget *parent):
|
||||
OptionsPage(parent)
|
||||
bool OptionsDialog::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
setWindowTitle(tr("Network"));
|
||||
|
||||
map_port_upnp = new QCheckBox(tr("Map port using &UPnP"));
|
||||
map_port_upnp->setToolTip(tr("Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled."));
|
||||
layout->addWidget(map_port_upnp);
|
||||
|
||||
connect_socks4 = new QCheckBox(tr("&Connect through SOCKS4 proxy:"));
|
||||
connect_socks4->setToolTip(tr("Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)"));
|
||||
layout->addWidget(connect_socks4);
|
||||
|
||||
QHBoxLayout *proxy_hbox = new QHBoxLayout();
|
||||
proxy_hbox->addSpacing(18);
|
||||
QLabel *proxy_ip_label = new QLabel(tr("Proxy &IP:"));
|
||||
proxy_hbox->addWidget(proxy_ip_label);
|
||||
proxy_ip = new QLineEdit();
|
||||
proxy_ip->setMaximumWidth(140);
|
||||
proxy_ip->setEnabled(false);
|
||||
proxy_ip->setValidator(new QRegExpValidator(QRegExp("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"), this));
|
||||
proxy_ip->setToolTip(tr("IP address of the proxy (e.g. 127.0.0.1)"));
|
||||
proxy_ip_label->setBuddy(proxy_ip);
|
||||
proxy_hbox->addWidget(proxy_ip);
|
||||
QLabel *proxy_port_label = new QLabel(tr("&Port:"));
|
||||
proxy_hbox->addWidget(proxy_port_label);
|
||||
proxy_port = new QLineEdit();
|
||||
proxy_port->setMaximumWidth(55);
|
||||
proxy_port->setValidator(new QIntValidator(0, 65535, this));
|
||||
proxy_port->setEnabled(false);
|
||||
proxy_port->setToolTip(tr("Port of the proxy (e.g. 1234)"));
|
||||
proxy_port_label->setBuddy(proxy_port);
|
||||
proxy_hbox->addWidget(proxy_port);
|
||||
proxy_hbox->addStretch(1);
|
||||
layout->addLayout(proxy_hbox);
|
||||
|
||||
layout->addStretch(1); // Extra space at bottom
|
||||
setLayout(layout);
|
||||
|
||||
connect(connect_socks4, SIGNAL(toggled(bool)), proxy_ip, SLOT(setEnabled(bool)));
|
||||
connect(connect_socks4, SIGNAL(toggled(bool)), proxy_port, SLOT(setEnabled(bool)));
|
||||
|
||||
#ifndef USE_UPNP
|
||||
map_port_upnp->setDisabled(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NetworkOptionsPage::setMapper(MonitoredDataMapper *mapper)
|
||||
{
|
||||
// Map model to widgets
|
||||
mapper->addMapping(map_port_upnp, OptionsModel::MapPortUPnP);
|
||||
mapper->addMapping(connect_socks4, OptionsModel::ConnectSOCKS4);
|
||||
mapper->addMapping(proxy_ip, OptionsModel::ProxyIP);
|
||||
mapper->addMapping(proxy_port, OptionsModel::ProxyPort);
|
||||
if(object == ui->proxyIp && event->type() == QEvent::FocusOut)
|
||||
{
|
||||
// Check proxyIP for a valid IPv4/IPv6 address
|
||||
CService addr;
|
||||
if(!LookupNumeric(ui->proxyIp->text().toStdString().c_str(), addr))
|
||||
{
|
||||
ui->proxyIp->setValid(false);
|
||||
fProxyIpValid = false;
|
||||
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
|
||||
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
|
||||
emit proxyIpValid(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
fProxyIpValid = true;
|
||||
ui->statusLabel->clear();
|
||||
emit proxyIpValid(true);
|
||||
}
|
||||
}
|
||||
return QDialog::eventFilter(object, event);
|
||||
}
|
||||
|
|
|
@ -2,48 +2,53 @@
|
|||
#define OPTIONSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QList>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QStackedWidget;
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
class QPushButton;
|
||||
QT_END_NAMESPACE
|
||||
namespace Ui {
|
||||
class OptionsDialog;
|
||||
}
|
||||
class OptionsModel;
|
||||
class OptionsPage;
|
||||
class MonitoredDataMapper;
|
||||
|
||||
/** Preferences dialog. */
|
||||
class OptionsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OptionsDialog(QWidget *parent=0);
|
||||
explicit OptionsDialog(QWidget *parent = 0);
|
||||
~OptionsDialog();
|
||||
|
||||
void setModel(OptionsModel *model);
|
||||
void setMapper();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
/** Change the current page to \a index. */
|
||||
void changePage(int index);
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
private slots:
|
||||
void okClicked();
|
||||
void cancelClicked();
|
||||
void applyClicked();
|
||||
void enableApply();
|
||||
void disableApply();
|
||||
/* enable apply button and OK button */
|
||||
void enableSaveButtons();
|
||||
/* disable apply button and OK button */
|
||||
void disableSaveButtons();
|
||||
/* set apply button and OK button state (enabled / disabled) */
|
||||
void setSaveButtonState(bool fState);
|
||||
void on_okButton_clicked();
|
||||
void on_cancelButton_clicked();
|
||||
void on_applyButton_clicked();
|
||||
|
||||
void showRestartWarning_Proxy();
|
||||
void showRestartWarning_Lang();
|
||||
void updateDisplayUnit();
|
||||
|
||||
signals:
|
||||
void proxyIpValid(bool fValid);
|
||||
|
||||
private:
|
||||
QListWidget *contents_widget;
|
||||
QStackedWidget *pages_widget;
|
||||
Ui::OptionsDialog *ui;
|
||||
OptionsModel *model;
|
||||
MonitoredDataMapper *mapper;
|
||||
QPushButton *apply_button;
|
||||
|
||||
QList<OptionsPage*> pages;
|
||||
bool fRestartWarningDisplayed_Proxy;
|
||||
bool fRestartWarningDisplayed_Lang;
|
||||
bool fProxyIpValid;
|
||||
};
|
||||
|
||||
#endif // OPTIONSDIALOG_H
|
||||
|
|
|
@ -12,6 +12,30 @@ OptionsModel::OptionsModel(QObject *parent) :
|
|||
Init();
|
||||
}
|
||||
|
||||
bool static ApplyProxySettings()
|
||||
{
|
||||
QSettings settings;
|
||||
CService addrProxy(settings.value("addrProxy", "127.0.0.1:9050").toString().toStdString());
|
||||
int nSocksVersion(settings.value("nSocksVersion", 5).toInt());
|
||||
if (!settings.value("fUseProxy", false).toBool()) {
|
||||
addrProxy = CService();
|
||||
nSocksVersion = 0;
|
||||
return false;
|
||||
}
|
||||
if (nSocksVersion && !addrProxy.IsValid())
|
||||
return false;
|
||||
if (!IsLimited(NET_IPV4))
|
||||
SetProxy(NET_IPV4, addrProxy, nSocksVersion);
|
||||
if (nSocksVersion > 4) {
|
||||
#ifdef USE_IPV6
|
||||
if (!IsLimited(NET_IPV6))
|
||||
SetProxy(NET_IPV6, addrProxy, nSocksVersion);
|
||||
#endif
|
||||
SetNameProxy(addrProxy, nSocksVersion);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OptionsModel::Init()
|
||||
{
|
||||
QSettings settings;
|
||||
|
@ -30,6 +54,8 @@ void OptionsModel::Init()
|
|||
SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool());
|
||||
if (settings.contains("addrProxy") && settings.value("fUseProxy").toBool())
|
||||
SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString());
|
||||
if (settings.contains("nSocksVersion") && settings.value("fUseProxy").toBool())
|
||||
SoftSetArg("-socks", settings.value("nSocksVersion").toString().toStdString());
|
||||
if (settings.contains("detachDB"))
|
||||
SoftSetBoolArg("-detachdb", settings.value("detachDB").toBool());
|
||||
if (!language.isEmpty())
|
||||
|
@ -75,20 +101,21 @@ bool OptionsModel::Upgrade()
|
|||
CAddress addrProxyAddress;
|
||||
if (walletdb.ReadSetting("addrProxy", addrProxyAddress))
|
||||
{
|
||||
addrProxy = addrProxyAddress;
|
||||
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
|
||||
settings.setValue("addrProxy", addrProxyAddress.ToStringIPPort().c_str());
|
||||
walletdb.EraseSetting("addrProxy");
|
||||
}
|
||||
}
|
||||
catch (std::ios_base::failure &e)
|
||||
{
|
||||
// 0.6.0rc1 saved this as a CService, which causes failure when parsing as a CAddress
|
||||
CService addrProxy;
|
||||
if (walletdb.ReadSetting("addrProxy", addrProxy))
|
||||
{
|
||||
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
|
||||
walletdb.EraseSetting("addrProxy");
|
||||
}
|
||||
}
|
||||
ApplyProxySettings();
|
||||
Init();
|
||||
|
||||
return true;
|
||||
|
@ -115,12 +142,24 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
|
|||
return settings.value("fUseUPnP", GetBoolArg("-upnp", true));
|
||||
case MinimizeOnClose:
|
||||
return QVariant(fMinimizeOnClose);
|
||||
case ConnectSOCKS4:
|
||||
case ProxyUse:
|
||||
return settings.value("fUseProxy", false);
|
||||
case ProxyIP:
|
||||
case ProxySocksVersion:
|
||||
return settings.value("nSocksVersion", 5);
|
||||
case ProxyIP: {
|
||||
CService addrProxy;
|
||||
if (GetProxy(NET_IPV4, addrProxy))
|
||||
return QVariant(QString::fromStdString(addrProxy.ToStringIP()));
|
||||
case ProxyPort:
|
||||
else
|
||||
return QVariant(QString::fromStdString("127.0.0.1"));
|
||||
}
|
||||
case ProxyPort: {
|
||||
CService addrProxy;
|
||||
if (GetProxy(NET_IPV4, addrProxy))
|
||||
return QVariant(addrProxy.GetPort());
|
||||
else
|
||||
return 9050;
|
||||
}
|
||||
case Fee:
|
||||
return QVariant(nTransactionFee);
|
||||
case DisplayUnit:
|
||||
|
@ -137,7 +176,6 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
|
|||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
|
||||
{
|
||||
bool successful = true; /* set to false on parse error */
|
||||
|
@ -155,27 +193,33 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
|||
break;
|
||||
case MapPortUPnP:
|
||||
{
|
||||
bool bUseUPnP = value.toBool();
|
||||
settings.setValue("fUseUPnP", bUseUPnP);
|
||||
MapPort(bUseUPnP);
|
||||
fUseUPnP = value.toBool();
|
||||
settings.setValue("fUseUPnP", fUseUPnP);
|
||||
MapPort();
|
||||
}
|
||||
break;
|
||||
case MinimizeOnClose:
|
||||
fMinimizeOnClose = value.toBool();
|
||||
settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
|
||||
break;
|
||||
case ConnectSOCKS4:
|
||||
fUseProxy = value.toBool();
|
||||
settings.setValue("fUseProxy", fUseProxy);
|
||||
case ProxyUse:
|
||||
settings.setValue("fUseProxy", value.toBool());
|
||||
ApplyProxySettings();
|
||||
break;
|
||||
case ProxySocksVersion:
|
||||
settings.setValue("nSocksVersion", value.toInt());
|
||||
ApplyProxySettings();
|
||||
break;
|
||||
case ProxyIP:
|
||||
{
|
||||
// Use CAddress to parse and check IP
|
||||
CService addrProxy("127.0.0.1", 9050);
|
||||
GetProxy(NET_IPV4, addrProxy);
|
||||
CNetAddr addr(value.toString().toStdString());
|
||||
if (addr.IsValid())
|
||||
{
|
||||
addrProxy.SetIP(addr);
|
||||
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
|
||||
successful = ApplyProxySettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -185,11 +229,14 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
|||
break;
|
||||
case ProxyPort:
|
||||
{
|
||||
CService addrProxy("127.0.0.1", 9050);
|
||||
GetProxy(NET_IPV4, addrProxy);
|
||||
int nPort = atoi(value.toString().toAscii().data());
|
||||
if (nPort > 0 && nPort < std::numeric_limits<unsigned short>::max())
|
||||
{
|
||||
addrProxy.SetPort(nPort);
|
||||
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
|
||||
successful = ApplyProxySettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -20,7 +20,8 @@ public:
|
|||
MinimizeToTray, // bool
|
||||
MapPortUPnP, // bool
|
||||
MinimizeOnClose, // bool
|
||||
ConnectSOCKS4, // bool
|
||||
ProxyUse, // bool
|
||||
ProxySocksVersion, // int
|
||||
ProxyIP, // QString
|
||||
ProxyPort, // QString
|
||||
Fee, // qint64
|
||||
|
|
|
@ -94,7 +94,9 @@ OverviewPage::OverviewPage(QWidget *parent) :
|
|||
ui(new Ui::OverviewPage),
|
||||
currentBalance(-1),
|
||||
currentUnconfirmedBalance(-1),
|
||||
txdelegate(new TxViewDelegate()), filter(0)
|
||||
currentImmatureBalance(-1),
|
||||
txdelegate(new TxViewDelegate()),
|
||||
filter(0)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -125,13 +127,21 @@ OverviewPage::~OverviewPage()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance)
|
||||
void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
|
||||
{
|
||||
int unit = model->getOptionsModel()->getDisplayUnit();
|
||||
currentBalance = balance;
|
||||
currentUnconfirmedBalance = unconfirmedBalance;
|
||||
currentImmatureBalance = immatureBalance;
|
||||
ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
|
||||
ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance));
|
||||
ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance));
|
||||
|
||||
// only show immature (newly mined) balance if it's non-zero, so as not to complicate things
|
||||
// for the non-mining users
|
||||
bool showImmature = immatureBalance != 0;
|
||||
ui->labelImmature->setVisible(showImmature);
|
||||
ui->labelImmatureText->setVisible(showImmature);
|
||||
}
|
||||
|
||||
void OverviewPage::setNumTransactions(int count)
|
||||
|
@ -156,8 +166,8 @@ void OverviewPage::setModel(WalletModel *model)
|
|||
ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);
|
||||
|
||||
// Keep up to date with wallet
|
||||
setBalance(model->getBalance(), model->getUnconfirmedBalance());
|
||||
connect(model, SIGNAL(balanceChanged(qint64, qint64)), this, SLOT(setBalance(qint64, qint64)));
|
||||
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
|
||||
connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
|
||||
|
||||
setNumTransactions(model->getNumTransactions());
|
||||
connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int)));
|
||||
|
@ -171,7 +181,7 @@ void OverviewPage::displayUnitChanged()
|
|||
if(!model || !model->getOptionsModel())
|
||||
return;
|
||||
if(currentBalance != -1)
|
||||
setBalance(currentBalance, currentUnconfirmedBalance);
|
||||
setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance);
|
||||
|
||||
txdelegate->unit = model->getOptionsModel()->getDisplayUnit();
|
||||
ui->listTransactions->update();
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
void showOutOfSyncWarning(bool fShow);
|
||||
|
||||
public slots:
|
||||
void setBalance(qint64 balance, qint64 unconfirmedBalance);
|
||||
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
|
||||
void setNumTransactions(int count);
|
||||
|
||||
signals:
|
||||
|
@ -38,6 +38,7 @@ private:
|
|||
WalletModel *model;
|
||||
qint64 currentBalance;
|
||||
qint64 currentUnconfirmedBalance;
|
||||
qint64 currentImmatureBalance;
|
||||
|
||||
TxViewDelegate *txdelegate;
|
||||
TransactionFilterProxy *filter;
|
||||
|
|
|
@ -109,12 +109,9 @@ RPCConsole::RPCConsole(QWidget *parent) :
|
|||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef Q_WS_MAC
|
||||
ui->openDebugLogfileButton->setIcon(QIcon(":/icons/export"));
|
||||
#else
|
||||
// Show Debug logfile label and Open button only for Windows
|
||||
ui->labelDebugLogfile->setVisible(false);
|
||||
ui->openDebugLogfileButton->setVisible(false);
|
||||
ui->showCLOptionsButton->setIcon(QIcon(":/icons/options"));
|
||||
#endif
|
||||
|
||||
// Install event filter for up and down arrow
|
||||
|
@ -163,7 +160,7 @@ void RPCConsole::setClientModel(ClientModel *model)
|
|||
ui->clientVersion->setText(model->formatFullVersion());
|
||||
ui->clientName->setText(model->clientName());
|
||||
ui->buildDate->setText(model->formatBuildDate());
|
||||
ui->startupTime->setText(model->formatClientStartupTime().toString());
|
||||
ui->startupTime->setText(model->formatClientStartupTime());
|
||||
|
||||
setNumConnections(model->getNumConnections());
|
||||
ui->isTestNet->setChecked(model->isTestNet());
|
||||
|
@ -326,3 +323,9 @@ void RPCConsole::scrollToEnd()
|
|||
QScrollBar *scrollbar = ui->messagesWidget->verticalScrollBar();
|
||||
scrollbar->setValue(scrollbar->maximum());
|
||||
}
|
||||
|
||||
void RPCConsole::on_showCLOptionsButton_clicked()
|
||||
{
|
||||
GUIUtil::HelpMessageBox help;
|
||||
help.exec();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ private slots:
|
|||
void on_tabWidget_currentChanged(int index);
|
||||
/** open the debug.log from the current datadir */
|
||||
void on_openDebugLogfileButton_clicked();
|
||||
/** display messagebox with program parameters (same as bitcoin-qt --help) */
|
||||
void on_showCLOptionsButton_clicked();
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
|
|
|
@ -48,8 +48,8 @@ void SendCoinsDialog::setModel(WalletModel *model)
|
|||
}
|
||||
if(model)
|
||||
{
|
||||
setBalance(model->getBalance(), model->getUnconfirmedBalance());
|
||||
connect(model, SIGNAL(balanceChanged(qint64, qint64)), this, SLOT(setBalance(qint64, qint64)));
|
||||
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
|
||||
connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,20 +266,23 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv)
|
|||
entry->setValue(rv);
|
||||
}
|
||||
|
||||
|
||||
void SendCoinsDialog::handleURI(const QString &uri)
|
||||
bool SendCoinsDialog::handleURI(const QString &uri)
|
||||
{
|
||||
SendCoinsRecipient rv;
|
||||
if(!GUIUtil::parseBitcoinURI(uri, &rv))
|
||||
// URI has to be valid
|
||||
if (GUIUtil::parseBitcoinURI(uri, &rv))
|
||||
{
|
||||
return;
|
||||
}
|
||||
pasteEntry(rv);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance)
|
||||
void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
|
||||
{
|
||||
Q_UNUSED(unconfirmedBalance);
|
||||
Q_UNUSED(immatureBalance);
|
||||
if(!model || !model->getOptionsModel())
|
||||
return;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
QWidget *setupTabChain(QWidget *prev);
|
||||
|
||||
void pasteEntry(const SendCoinsRecipient &rv);
|
||||
void handleURI(const QString &uri);
|
||||
bool handleURI(const QString &uri);
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
|
@ -38,7 +38,7 @@ public slots:
|
|||
void accept();
|
||||
SendCoinsEntry *addEntry();
|
||||
void updateRemoveEnabled();
|
||||
void setBalance(qint64 balance, qint64 unconfirmedBalance);
|
||||
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
|
||||
|
||||
private:
|
||||
Ui::SendCoinsDialog *ui;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "wallet.h"
|
||||
#include "db.h"
|
||||
#include "ui_interface.h"
|
||||
#include "base58.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
|
@ -85,14 +86,14 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
|||
{
|
||||
if (wallet->IsMine(txout))
|
||||
{
|
||||
CBitcoinAddress address;
|
||||
if (ExtractAddress(txout.scriptPubKey, address) && wallet->HaveKey(address))
|
||||
CTxDestination address;
|
||||
if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
|
||||
{
|
||||
if (wallet->mapAddressBook.count(address))
|
||||
{
|
||||
strHTML += tr("<b>From:</b> ") + tr("unknown") + "<br>";
|
||||
strHTML += tr("<b>To:</b> ");
|
||||
strHTML += GUIUtil::HtmlEscape(address.ToString());
|
||||
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
|
||||
if (!wallet->mapAddressBook[address].empty())
|
||||
strHTML += tr(" (yours, label: ") + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")";
|
||||
else
|
||||
|
@ -115,8 +116,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
|||
// Online transaction
|
||||
strAddress = wtx.mapValue["to"];
|
||||
strHTML += tr("<b>To:</b> ");
|
||||
if (wallet->mapAddressBook.count(strAddress) && !wallet->mapAddressBook[strAddress].empty())
|
||||
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[strAddress]) + " ";
|
||||
CTxDestination dest = CBitcoinAddress(strAddress).Get();
|
||||
if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].empty())
|
||||
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest]) + " ";
|
||||
strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>";
|
||||
}
|
||||
|
||||
|
@ -170,13 +172,13 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
|||
if (wtx.mapValue["to"].empty())
|
||||
{
|
||||
// Offline transaction
|
||||
CBitcoinAddress address;
|
||||
if (ExtractAddress(txout.scriptPubKey, address))
|
||||
CTxDestination address;
|
||||
if (ExtractDestination(txout.scriptPubKey, address))
|
||||
{
|
||||
strHTML += tr("<b>To:</b> ");
|
||||
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty())
|
||||
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " ";
|
||||
strHTML += GUIUtil::HtmlEscape(address.ToString());
|
||||
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
|
||||
strHTML += "<br>";
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +226,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
|||
strHTML += QString("<b>") + tr("Transaction ID:") + "</b> " + wtx.GetHash().ToString().c_str() + "<br>";
|
||||
|
||||
if (wtx.IsCoinBase())
|
||||
strHTML += QString("<br>") + tr("Generated coins must wait 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "<br>";
|
||||
strHTML += QString("<br>") + tr("Generated coins must mature 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it's state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "<br>";
|
||||
|
||||
//
|
||||
// Debug view
|
||||
|
@ -260,12 +262,12 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
|||
{
|
||||
strHTML += "<li>";
|
||||
const CTxOut &vout = prev.vout[prevout.n];
|
||||
CBitcoinAddress address;
|
||||
if (ExtractAddress(vout.scriptPubKey, address))
|
||||
CTxDestination address;
|
||||
if (ExtractDestination(vout.scriptPubKey, address))
|
||||
{
|
||||
if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty())
|
||||
strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " ";
|
||||
strHTML += QString::fromStdString(address.ToString());
|
||||
strHTML += QString::fromStdString(CBitcoinAddress(address).ToString());
|
||||
}
|
||||
strHTML = strHTML + " Amount=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,vout.nValue);
|
||||
strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? "true" : "false") + "</li>";
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "transactionrecord.h"
|
||||
|
||||
#include "wallet.h"
|
||||
#include "base58.h"
|
||||
|
||||
/* Return positive answer if transaction should be shown in list.
|
||||
*/
|
||||
|
@ -50,7 +51,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
|
|||
if(wallet->IsMine(txout))
|
||||
{
|
||||
TransactionRecord sub(hash, nTime);
|
||||
CBitcoinAddress address;
|
||||
CTxDestination address;
|
||||
sub.idx = parts.size(); // sequence number
|
||||
sub.credit = txout.nValue;
|
||||
if (wtx.IsCoinBase())
|
||||
|
@ -58,11 +59,11 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
|
|||
// Generated
|
||||
sub.type = TransactionRecord::Generated;
|
||||
}
|
||||
else if (ExtractAddress(txout.scriptPubKey, address) && wallet->HaveKey(address))
|
||||
else if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
|
||||
{
|
||||
// Received by Bitcoin Address
|
||||
sub.type = TransactionRecord::RecvWithAddress;
|
||||
sub.address = address.ToString();
|
||||
sub.address = CBitcoinAddress(address).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -113,12 +114,12 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
|
|||
continue;
|
||||
}
|
||||
|
||||
CBitcoinAddress address;
|
||||
if (ExtractAddress(txout.scriptPubKey, address))
|
||||
CTxDestination address;
|
||||
if (ExtractDestination(txout.scriptPubKey, address))
|
||||
{
|
||||
// Sent to Bitcoin Address
|
||||
sub.type = TransactionRecord::SendToAddress;
|
||||
sub.address = address.ToString();
|
||||
sub.address = CBitcoinAddress(address).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -298,8 +298,7 @@ QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) cons
|
|||
switch(wtx->status.maturity)
|
||||
{
|
||||
case TransactionStatus::Immature:
|
||||
status += "\n" + tr("Mined balance will be available in %n more blocks", "",
|
||||
wtx->status.matures_in);
|
||||
status += "\n" + tr("Mined balance will be available when it matures in %n more block(s)", "", wtx->status.matures_in);
|
||||
break;
|
||||
case TransactionStatus::Mature:
|
||||
break;
|
||||
|
|
|
@ -4,34 +4,36 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QAbstractButton>
|
||||
#include <QClipboard>
|
||||
#include <QMessageBox>
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "main.h"
|
||||
#include "wallet.h"
|
||||
#include "walletmodel.h"
|
||||
#include "addresstablemodel.h"
|
||||
#include "guiutil.h"
|
||||
#include "base58.h"
|
||||
|
||||
VerifyMessageDialog::VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent) :
|
||||
VerifyMessageDialog::VerifyMessageDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::VerifyMessageDialog),
|
||||
model(addressModel)
|
||||
ui(new Ui::VerifyMessageDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
#if (QT_VERSION >= 0x040700)
|
||||
/* Do not move this to the XML file, Qt before 4.7 will choke on it */
|
||||
ui->lnAddress->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
|
||||
ui->lnSig->setPlaceholderText(tr("Enter Bitcoin signature"));
|
||||
ui->lnAddress->setPlaceholderText(tr("Click \"Verify Message\" to obtain address"));
|
||||
#endif
|
||||
|
||||
GUIUtil::setupAddressWidget(ui->lnAddress, this);
|
||||
ui->lnAddress->installEventFilter(this);
|
||||
|
||||
ui->edMessage->setFocus();
|
||||
ui->lnSig->setFont(GUIUtil::bitcoinAddressFont());
|
||||
|
||||
ui->lnAddress->setFocus();
|
||||
}
|
||||
|
||||
VerifyMessageDialog::~VerifyMessageDialog()
|
||||
|
@ -39,54 +41,65 @@ VerifyMessageDialog::~VerifyMessageDialog()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
bool VerifyMessageDialog::checkAddress()
|
||||
void VerifyMessageDialog::on_verifyMessage_clicked()
|
||||
{
|
||||
CBitcoinAddress addr(ui->lnAddress->text().toStdString());
|
||||
if (!addr.IsValid())
|
||||
{
|
||||
ui->lnAddress->setValid(false);
|
||||
ui->lblStatus->setStyleSheet("QLabel { color: red; }");
|
||||
ui->lblStatus->setText(tr("\"%1\" is not a valid address.").arg(ui->lnAddress->text()) + QString(" ") + tr("Please check the address and try again."));
|
||||
return;
|
||||
}
|
||||
CKeyID keyID;
|
||||
if (!addr.GetKeyID(keyID))
|
||||
{
|
||||
ui->lnAddress->setValid(false);
|
||||
ui->lblStatus->setStyleSheet("QLabel { color: red; }");
|
||||
ui->lblStatus->setText(tr("\"%1\" does not refer to a key.").arg(ui->lnAddress->text()) + QString(" ") + tr("Please check the address and try again."));
|
||||
return;
|
||||
}
|
||||
|
||||
bool fInvalid = false;
|
||||
std::vector<unsigned char> vchSig = DecodeBase64(ui->lnSig->text().toStdString().c_str(), &fInvalid);
|
||||
|
||||
if (fInvalid)
|
||||
{
|
||||
ui->lnSig->setValid(false);
|
||||
ui->lblStatus->setStyleSheet("QLabel { color: red; }");
|
||||
ui->lblStatus->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again."));
|
||||
return;
|
||||
}
|
||||
|
||||
CDataStream ss(SER_GETHASH, 0);
|
||||
ss << strMessageMagic;
|
||||
ss << ui->edMessage->document()->toPlainText().toStdString();
|
||||
uint256 hash = Hash(ss.begin(), ss.end());
|
||||
|
||||
bool invalid = true;
|
||||
std::vector<unsigned char> vchSig = DecodeBase64(ui->lnSig->text().toStdString().c_str(), &invalid);
|
||||
|
||||
if(invalid)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Signature"), tr("The signature could not be decoded. Please check the signature and try again."));
|
||||
return false;
|
||||
}
|
||||
|
||||
CKey key;
|
||||
if(!key.SetCompactSignature(hash, vchSig))
|
||||
if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Signature"), tr("The signature did not match the message digest. Please check the signature and try again."));
|
||||
return false;
|
||||
ui->lnSig->setValid(false);
|
||||
ui->lblStatus->setStyleSheet("QLabel { color: red; }");
|
||||
ui->lblStatus->setText(tr("The signature did not match the message digest.")+ QString(" ") + tr("Please check the signature and try again."));
|
||||
return;
|
||||
}
|
||||
|
||||
CBitcoinAddress address(key.GetPubKey());
|
||||
QString qStringAddress = QString::fromStdString(address.ToString());
|
||||
ui->lnAddress->setText(qStringAddress);
|
||||
ui->copyToClipboard->setEnabled(true);
|
||||
if (!(CBitcoinAddress(key.GetPubKey().GetID()) == addr))
|
||||
{
|
||||
ui->lblStatus->setStyleSheet("QLabel { color: red; }");
|
||||
ui->lblStatus->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
|
||||
return;
|
||||
}
|
||||
|
||||
QString label = model->labelForAddress(qStringAddress);
|
||||
ui->lblStatus->setText(label.isEmpty() ? tr("Address not found in address book.") : tr("Address found in address book: %1").arg(label));
|
||||
return true;
|
||||
}
|
||||
|
||||
void VerifyMessageDialog::on_verifyMessage_clicked()
|
||||
{
|
||||
checkAddress();
|
||||
}
|
||||
|
||||
void VerifyMessageDialog::on_copyToClipboard_clicked()
|
||||
{
|
||||
QApplication::clipboard()->setText(ui->lnAddress->text());
|
||||
ui->lblStatus->setStyleSheet("QLabel { color: green; }");
|
||||
ui->lblStatus->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
|
||||
}
|
||||
|
||||
void VerifyMessageDialog::on_clearButton_clicked()
|
||||
{
|
||||
ui->edMessage->clear();
|
||||
ui->lnSig->clear();
|
||||
ui->lnAddress->clear();
|
||||
ui->lnSig->clear();
|
||||
ui->edMessage->clear();
|
||||
ui->lblStatus->clear();
|
||||
|
||||
ui->edMessage->setFocus();
|
||||
|
@ -94,9 +107,11 @@ void VerifyMessageDialog::on_clearButton_clicked()
|
|||
|
||||
bool VerifyMessageDialog::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if(object == ui->lnAddress && (event->type() == QEvent::MouseButtonPress ||
|
||||
if (object == ui->lnAddress && (event->type() == QEvent::MouseButtonPress ||
|
||||
event->type() == QEvent::FocusIn))
|
||||
{
|
||||
// set lnAddress to valid, as QEvent::FocusIn would not reach QValidatedLineEdit::focusInEvent
|
||||
ui->lnAddress->setValid(true);
|
||||
ui->lnAddress->selectAll();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -16,21 +16,17 @@ class VerifyMessageDialog : public QDialog
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent = 0);
|
||||
explicit VerifyMessageDialog(QWidget *parent);
|
||||
~VerifyMessageDialog();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
private:
|
||||
bool checkAddress();
|
||||
|
||||
Ui::VerifyMessageDialog *ui;
|
||||
AddressTableModel *model;
|
||||
|
||||
private slots:
|
||||
void on_verifyMessage_clicked();
|
||||
void on_copyToClipboard_clicked();
|
||||
void on_clearButton_clicked();
|
||||
};
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue