commit f3307413ec112efdca3cedc5d9a2b5cb6a5185f8 Author: transcoder Date: Thu Jul 18 19:01:17 2013 -0600 Initial commit. diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..26d7549 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +src/version.cpp export-subst diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20ef5ff --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +src/*.exe +src/casinocoin +src/casinocoind +src/test_casinocoin +src/build.h +.*.swp +*.*~* +*.bak +*.rej +*.orig +*.o +*.patch +.bitcoin +#compilation and Qt preprocessor part +*.qm +Makefile +casinocoin-qt +#resources cpp +qrc_*.cpp +#qt creator +*.pro.user +#mac specific +.DS_Store +build +.cproject +.project +debug +release +.svn +object_script.casinocoin-qt.Debug +object_script.casinocoin-qt.Release +object_script.litecoin-qt.Debug +object_script.litecoin-qt.Release diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..a7dd716 --- /dev/null +++ b/COPYING @@ -0,0 +1,21 @@ +Copyright (c) 2009-2012 Bitcoin Developers +Copyright (c) 2011-2012 Litecoin Developers +Copyright (c) 2013 CasinoCoin Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..c1866de --- /dev/null +++ b/INSTALL @@ -0,0 +1,9 @@ +Building CasinoCoin + +See doc/readme-qt.rst for instructions on building CasinoCoin-QT, +the intended-for-end-users, nice-graphical-interface, reference +implementation of CasinoCoin. + +See doc/build-*.txt for instructions on building casinocoind, +the intended-for-services, no-graphical-interface, reference +implementation of CasinoCoin. diff --git a/Makefile.Debug b/Makefile.Debug new file mode 100644 index 0000000..8a8a203 --- /dev/null +++ b/Makefile.Debug @@ -0,0 +1,1711 @@ +############################################################################# +# Makefile for building: casinocoin-qt +# Generated by qmake (2.01a) (Qt 4.8.4) on: Wed Jul 17 17:29:56 2013 +# Project: casinocoin-qt.pro +# Template: app +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +DEFINES = -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_GUI -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -DUSE_IPV6 -D__NO_SYSTEM_INCLUDES -DWIN32 -D_MT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN +CFLAGS = -pipe -g -Wall -Wextra $(DEFINES) +CXXFLAGS = -pipe -g -frtti -fexceptions -mthreads -fdiagnostics-show-option -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEFINES) +INCPATH = -I"c:\QtSDK\4.8.4\include\QtCore" -I"c:\QtSDK\4.8.4\include\QtGui" -I"c:\QtSDK\4.8.4\include" -I"src" -I"src\json" -I"src\qt" -I"..\..\deps\boost_1_53_0" -I"..\..\deps\db-4.8.30.NC\build_unix" -I"..\..\deps\openssl-1.0.1b\include" -I"c:\QtSDK\4.8.4\include\ActiveQt" -I"build" -I"build" -I"c:\QtSDK\4.8.4\mkspecs\win32-g++" +LINK = g++ +LFLAGS = -mthreads -Wl,-subsystem,windows +LIBS = -L"c:\QtSDK\4.8.4\lib" -lmingwthrd -lmingw32 -lqtmaind build\bitcoin-qt_res.o -lshlwapi -LE:/crypto/deps/boost_1_53_0/stage/lib -LE:/crypto/deps/db-4.8.30.NC/build_unix -LE:/crypto/deps/openssl-1.0.1b -lssl -lcrypto -ldb_cxx -lws2_32 -lole32 -lmswsock -loleaut32 -luuid -lgdi32 -lboost_system-mgw46-mt-s-1_53 -lboost_filesystem-mgw46-mt-s-1_53 -lboost_program_options-mgw46-mt-s-1_53 -lboost_thread-mgw46-mt-s-1_53 -lQtGuid4 -lQtCored4 +QMAKE = c:\QtSDK\4.8.4\bin\qmake.exe +IDC = c:\QtSDK\4.8.4\bin\idc.exe +IDL = midl +ZIP = zip -r -9 +DEF_FILE = +RES_FILE = build\bitcoin-qt_res.o +COPY = copy /y +SED = +COPY_FILE = $(COPY) +COPY_DIR = xcopy /s /q /y /i +DEL_FILE = del +DEL_DIR = rmdir +MOVE = move +CHK_DIR_EXISTS= if not exist +MKDIR = mkdir +INSTALL_FILE = $(COPY_FILE) +INSTALL_PROGRAM = $(COPY_FILE) +INSTALL_DIR = $(COPY_DIR) + +####### Output directory + +OBJECTS_DIR = build + +####### Files + +SOURCES = src\qt\bitcoin.cpp \ + src\qt\bitcoingui.cpp \ + src\qt\transactiontablemodel.cpp \ + src\qt\addresstablemodel.cpp \ + src\qt\optionsdialog.cpp \ + src\qt\sendcoinsdialog.cpp \ + src\qt\addressbookpage.cpp \ + src\qt\signverifymessagedialog.cpp \ + src\qt\aboutdialog.cpp \ + src\qt\editaddressdialog.cpp \ + src\qt\bitcoinaddressvalidator.cpp \ + src\version.cpp \ + src\sync.cpp \ + src\util.cpp \ + src\netbase.cpp \ + src\key.cpp \ + src\script.cpp \ + src\main.cpp \ + src\init.cpp \ + src\net.cpp \ + src\irc.cpp \ + src\checkpoints.cpp \ + src\addrman.cpp \ + src\db.cpp \ + src\walletdb.cpp \ + src\json\json_spirit_writer.cpp \ + src\json\json_spirit_value.cpp \ + src\json\json_spirit_reader.cpp \ + src\qt\clientmodel.cpp \ + src\qt\guiutil.cpp \ + src\qt\transactionrecord.cpp \ + src\qt\optionsmodel.cpp \ + src\qt\monitoreddatamapper.cpp \ + src\qt\transactiondesc.cpp \ + src\qt\transactiondescdialog.cpp \ + src\qt\bitcoinstrings.cpp \ + src\qt\bitcoinamountfield.cpp \ + src\wallet.cpp \ + src\keystore.cpp \ + src\qt\transactionfilterproxy.cpp \ + src\qt\transactionview.cpp \ + src\qt\walletmodel.cpp \ + src\bitcoinrpc.cpp \ + src\rpcdump.cpp \ + src\rpcnet.cpp \ + src\rpcrawtransaction.cpp \ + src\qt\overviewpage.cpp \ + src\qt\csvmodelwriter.cpp \ + src\crypter.cpp \ + src\qt\sendcoinsentry.cpp \ + src\qt\qvalidatedlineedit.cpp \ + src\qt\bitcoinunits.cpp \ + src\qt\qvaluecombobox.cpp \ + src\qt\askpassphrasedialog.cpp \ + src\protocol.cpp \ + src\qt\notificator.cpp \ + src\qt\qtipcserver.cpp \ + src\qt\rpcconsole.cpp \ + src\scrypt.c \ + src\noui.cpp build\moc_bitcoingui.cpp \ + build\moc_transactiontablemodel.cpp \ + build\moc_addresstablemodel.cpp \ + build\moc_optionsdialog.cpp \ + build\moc_sendcoinsdialog.cpp \ + build\moc_addressbookpage.cpp \ + build\moc_signverifymessagedialog.cpp \ + build\moc_aboutdialog.cpp \ + build\moc_editaddressdialog.cpp \ + build\moc_bitcoinaddressvalidator.cpp \ + build\moc_clientmodel.cpp \ + build\moc_guiutil.cpp \ + build\moc_optionsmodel.cpp \ + build\moc_monitoreddatamapper.cpp \ + build\moc_transactiondesc.cpp \ + build\moc_transactiondescdialog.cpp \ + build\moc_bitcoinamountfield.cpp \ + build\moc_transactionfilterproxy.cpp \ + build\moc_transactionview.cpp \ + build\moc_walletmodel.cpp \ + build\moc_overviewpage.cpp \ + build\moc_csvmodelwriter.cpp \ + build\moc_sendcoinsentry.cpp \ + build\moc_qvalidatedlineedit.cpp \ + build\moc_qvaluecombobox.cpp \ + build\moc_askpassphrasedialog.cpp \ + build\moc_notificator.cpp \ + build\moc_rpcconsole.cpp \ + debug\qrc_bitcoin.cpp +OBJECTS = build/bitcoin.o \ + build/bitcoingui.o \ + build/transactiontablemodel.o \ + build/addresstablemodel.o \ + build/optionsdialog.o \ + build/sendcoinsdialog.o \ + build/addressbookpage.o \ + build/signverifymessagedialog.o \ + build/aboutdialog.o \ + build/editaddressdialog.o \ + build/bitcoinaddressvalidator.o \ + build/version.o \ + build/sync.o \ + build/util.o \ + build/netbase.o \ + build/key.o \ + build/script.o \ + build/main.o \ + build/init.o \ + build/net.o \ + build/irc.o \ + build/checkpoints.o \ + build/addrman.o \ + build/db.o \ + build/walletdb.o \ + build/json_spirit_writer.o \ + build/json_spirit_value.o \ + build/json_spirit_reader.o \ + build/clientmodel.o \ + build/guiutil.o \ + build/transactionrecord.o \ + build/optionsmodel.o \ + build/monitoreddatamapper.o \ + build/transactiondesc.o \ + build/transactiondescdialog.o \ + build/bitcoinstrings.o \ + build/bitcoinamountfield.o \ + build/wallet.o \ + build/keystore.o \ + build/transactionfilterproxy.o \ + build/transactionview.o \ + build/walletmodel.o \ + build/bitcoinrpc.o \ + build/rpcdump.o \ + build/rpcnet.o \ + build/rpcrawtransaction.o \ + build/overviewpage.o \ + build/csvmodelwriter.o \ + build/crypter.o \ + build/sendcoinsentry.o \ + build/qvalidatedlineedit.o \ + build/bitcoinunits.o \ + build/qvaluecombobox.o \ + build/askpassphrasedialog.o \ + build/protocol.o \ + build/notificator.o \ + build/qtipcserver.o \ + build/rpcconsole.o \ + build/scrypt.o \ + build/noui.o \ + build/moc_bitcoingui.o \ + build/moc_transactiontablemodel.o \ + build/moc_addresstablemodel.o \ + build/moc_optionsdialog.o \ + build/moc_sendcoinsdialog.o \ + build/moc_addressbookpage.o \ + build/moc_signverifymessagedialog.o \ + build/moc_aboutdialog.o \ + build/moc_editaddressdialog.o \ + build/moc_bitcoinaddressvalidator.o \ + build/moc_clientmodel.o \ + build/moc_guiutil.o \ + build/moc_optionsmodel.o \ + build/moc_monitoreddatamapper.o \ + build/moc_transactiondesc.o \ + build/moc_transactiondescdialog.o \ + build/moc_bitcoinamountfield.o \ + build/moc_transactionfilterproxy.o \ + build/moc_transactionview.o \ + build/moc_walletmodel.o \ + build/moc_overviewpage.o \ + build/moc_csvmodelwriter.o \ + build/moc_sendcoinsentry.o \ + build/moc_qvalidatedlineedit.o \ + build/moc_qvaluecombobox.o \ + build/moc_askpassphrasedialog.o \ + build/moc_notificator.o \ + build/moc_rpcconsole.o \ + build/qrc_bitcoin.o +DIST = +QMAKE_TARGET = casinocoin-qt +DESTDIR = debug\ #avoid trailing-slash linebreak +TARGET = casinocoin-qt.exe +DESTDIR_TARGET = debug\casinocoin-qt.exe + +####### Implicit rules + +.SUFFIXES: .cpp .cc .cxx .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +first: all +all: Makefile.Debug $(DESTDIR_TARGET) + +$(DESTDIR_TARGET): build/ui_sendcoinsdialog.h build/ui_addressbookpage.h build/ui_signverifymessagedialog.h build/ui_aboutdialog.h build/ui_editaddressdialog.h build/ui_transactiondescdialog.h build/ui_overviewpage.h build/ui_sendcoinsentry.h build/ui_askpassphrasedialog.h build/ui_rpcconsole.h build/ui_optionsdialog.h $(OBJECTS) build/bitcoin-qt_res.o + $(LINK) $(LFLAGS) -o $(DESTDIR_TARGET) object_script.casinocoin-qt.Debug $(LIBS) + +build/bitcoin-qt_res.o: src\qt\res\bitcoin-qt.rc + windres -i src\qt\res\bitcoin-qt.rc -o build\bitcoin-qt_res.o --include-dir=./src/qt/res $(DEFINES) + +qmake: FORCE + @$(QMAKE) USE_UPNP=- -o Makefile.Debug casinocoin-qt.pro + +dist: + $(ZIP) casinocoin-qt.zip $(SOURCES) $(DIST) casinocoin-qt.pro c:\QtSDK\4.8.4\mkspecs\features\device_config.prf c:\QtSDK\4.8.4\mkspecs\qconfig.pri c:\QtSDK\4.8.4\mkspecs\modules\qt_webkit_version.pri c:\QtSDK\4.8.4\mkspecs\features\qt_functions.prf c:\QtSDK\4.8.4\mkspecs\features\qt_config.prf c:\QtSDK\4.8.4\mkspecs\features\exclusive_builds.prf c:\QtSDK\4.8.4\mkspecs\features\default_pre.prf c:\QtSDK\4.8.4\mkspecs\features\win32\default_pre.prf c:\QtSDK\4.8.4\mkspecs\features\debug.prf c:\QtSDK\4.8.4\mkspecs\features\debug_and_release.prf c:\QtSDK\4.8.4\mkspecs\features\default_post.prf c:\QtSDK\4.8.4\mkspecs\features\win32\default_post.prf c:\QtSDK\4.8.4\mkspecs\features\build_pass.prf c:\QtSDK\4.8.4\mkspecs\features\win32\rtti.prf c:\QtSDK\4.8.4\mkspecs\features\win32\exceptions.prf c:\QtSDK\4.8.4\mkspecs\features\win32\stl.prf c:\QtSDK\4.8.4\mkspecs\features\shared.prf c:\QtSDK\4.8.4\mkspecs\features\warn_on.prf c:\QtSDK\4.8.4\mkspecs\features\qt.prf c:\QtSDK\4.8.4\mkspecs\features\win32\thread.prf c:\QtSDK\4.8.4\mkspecs\features\moc.prf c:\QtSDK\4.8.4\mkspecs\features\win32\windows.prf c:\QtSDK\4.8.4\mkspecs\features\resources.prf c:\QtSDK\4.8.4\mkspecs\features\uic.prf c:\QtSDK\4.8.4\mkspecs\features\yacc.prf c:\QtSDK\4.8.4\mkspecs\features\lex.prf c:\QtSDK\4.8.4\lib\qtmaind.prl src\qt\locale\bitcoin_bg.ts src\qt\locale\bitcoin_ca_ES.ts src\qt\locale\bitcoin_cs.ts src\qt\locale\bitcoin_da.ts src\qt\locale\bitcoin_de.ts src\qt\locale\bitcoin_el_GR.ts src\qt\locale\bitcoin_en.ts src\qt\locale\bitcoin_es.ts src\qt\locale\bitcoin_es_CL.ts src\qt\locale\bitcoin_et.ts src\qt\locale\bitcoin_eu_ES.ts src\qt\locale\bitcoin_fa.ts src\qt\locale\bitcoin_fa_IR.ts src\qt\locale\bitcoin_fi.ts src\qt\locale\bitcoin_fr.ts src\qt\locale\bitcoin_fr_CA.ts src\qt\locale\bitcoin_he.ts src\qt\locale\bitcoin_hr.ts src\qt\locale\bitcoin_hu.ts src\qt\locale\bitcoin_it.ts src\qt\locale\bitcoin_lt.ts src\qt\locale\bitcoin_nb.ts src\qt\locale\bitcoin_nl.ts src\qt\locale\bitcoin_pl.ts src\qt\locale\bitcoin_pt_BR.ts src\qt\locale\bitcoin_pt_PT.ts src\qt\locale\bitcoin_ro_RO.ts src\qt\locale\bitcoin_ru.ts src\qt\locale\bitcoin_sk.ts src\qt\locale\bitcoin_sr.ts src\qt\locale\bitcoin_sv.ts src\qt\locale\bitcoin_tr.ts src\qt\locale\bitcoin_uk.ts src\qt\locale\bitcoin_zh_CN.ts src\qt\locale\bitcoin_zh_TW.ts src\qt\locale\bitcoin_bg.ts src\qt\locale\bitcoin_ca_ES.ts src\qt\locale\bitcoin_cs.ts src\qt\locale\bitcoin_da.ts src\qt\locale\bitcoin_de.ts src\qt\locale\bitcoin_el_GR.ts src\qt\locale\bitcoin_en.ts src\qt\locale\bitcoin_es.ts src\qt\locale\bitcoin_es_CL.ts src\qt\locale\bitcoin_et.ts src\qt\locale\bitcoin_eu_ES.ts src\qt\locale\bitcoin_fa.ts src\qt\locale\bitcoin_fa_IR.ts src\qt\locale\bitcoin_fi.ts src\qt\locale\bitcoin_fr.ts src\qt\locale\bitcoin_fr_CA.ts src\qt\locale\bitcoin_he.ts src\qt\locale\bitcoin_hr.ts src\qt\locale\bitcoin_hu.ts src\qt\locale\bitcoin_it.ts src\qt\locale\bitcoin_lt.ts src\qt\locale\bitcoin_nb.ts src\qt\locale\bitcoin_nl.ts src\qt\locale\bitcoin_pl.ts src\qt\locale\bitcoin_pt_BR.ts src\qt\locale\bitcoin_pt_PT.ts src\qt\locale\bitcoin_ro_RO.ts src\qt\locale\bitcoin_ru.ts src\qt\locale\bitcoin_sk.ts src\qt\locale\bitcoin_sr.ts src\qt\locale\bitcoin_sv.ts src\qt\locale\bitcoin_tr.ts src\qt\locale\bitcoin_uk.ts src\qt\locale\bitcoin_zh_CN.ts src\qt\locale\bitcoin_zh_TW.ts TRANSLATIONS HEADERS RESOURCES IMAGES SOURCES OBJECTIVE_SOURCES FORMS YACCSOURCES YACCSOURCES LEXSOURCES + +clean: compiler_clean + -$(DEL_FILE) build\bitcoin.o build\bitcoingui.o build\transactiontablemodel.o build\addresstablemodel.o build\optionsdialog.o build\sendcoinsdialog.o build\addressbookpage.o build\signverifymessagedialog.o build\aboutdialog.o build\editaddressdialog.o build\bitcoinaddressvalidator.o build\version.o build\sync.o build\util.o build\netbase.o build\key.o build\script.o build\main.o build\init.o build\net.o build\irc.o build\checkpoints.o build\addrman.o build\db.o build\walletdb.o build\json_spirit_writer.o build\json_spirit_value.o build\json_spirit_reader.o build\clientmodel.o build\guiutil.o build\transactionrecord.o build\optionsmodel.o build\monitoreddatamapper.o build\transactiondesc.o build\transactiondescdialog.o build\bitcoinstrings.o build\bitcoinamountfield.o build\wallet.o build\keystore.o build\transactionfilterproxy.o build\transactionview.o build\walletmodel.o build\bitcoinrpc.o build\rpcdump.o build\rpcnet.o build\rpcrawtransaction.o build\overviewpage.o build\csvmodelwriter.o build\crypter.o build\sendcoinsentry.o build\qvalidatedlineedit.o build\bitcoinunits.o build\qvaluecombobox.o build\askpassphrasedialog.o build\protocol.o build\notificator.o build\qtipcserver.o build\rpcconsole.o build\scrypt.o build\noui.o build\moc_bitcoingui.o build\moc_transactiontablemodel.o build\moc_addresstablemodel.o build\moc_optionsdialog.o build\moc_sendcoinsdialog.o build\moc_addressbookpage.o build\moc_signverifymessagedialog.o build\moc_aboutdialog.o build\moc_editaddressdialog.o build\moc_bitcoinaddressvalidator.o build\moc_clientmodel.o build\moc_guiutil.o build\moc_optionsmodel.o build\moc_monitoreddatamapper.o build\moc_transactiondesc.o build\moc_transactiondescdialog.o build\moc_bitcoinamountfield.o build\moc_transactionfilterproxy.o build\moc_transactionview.o build\moc_walletmodel.o build\moc_overviewpage.o build\moc_csvmodelwriter.o build\moc_sendcoinsentry.o build\moc_qvalidatedlineedit.o build\moc_qvaluecombobox.o build\moc_askpassphrasedialog.o build\moc_notificator.o build\moc_rpcconsole.o + -$(DEL_FILE) build\qrc_bitcoin.o + -$(DEL_FILE) build\bitcoin-qt_res.o + +distclean: clean + -$(DEL_FILE) $(DESTDIR_TARGET) + -$(DEL_FILE) Makefile.Debug + +check: first + +mocclean: compiler_moc_header_clean compiler_moc_source_clean + +mocables: compiler_moc_header_make_all compiler_moc_source_make_all + +compiler_TSQM_make_all: src/qt/locale/bitcoin_bg.qm src/qt/locale/bitcoin_ca_ES.qm src/qt/locale/bitcoin_cs.qm src/qt/locale/bitcoin_da.qm src/qt/locale/bitcoin_de.qm src/qt/locale/bitcoin_el_GR.qm src/qt/locale/bitcoin_en.qm src/qt/locale/bitcoin_es.qm src/qt/locale/bitcoin_es_CL.qm src/qt/locale/bitcoin_et.qm src/qt/locale/bitcoin_eu_ES.qm src/qt/locale/bitcoin_fa.qm src/qt/locale/bitcoin_fa_IR.qm src/qt/locale/bitcoin_fi.qm src/qt/locale/bitcoin_fr.qm src/qt/locale/bitcoin_fr_CA.qm src/qt/locale/bitcoin_he.qm src/qt/locale/bitcoin_hr.qm src/qt/locale/bitcoin_hu.qm src/qt/locale/bitcoin_it.qm src/qt/locale/bitcoin_lt.qm src/qt/locale/bitcoin_nb.qm src/qt/locale/bitcoin_nl.qm src/qt/locale/bitcoin_pl.qm src/qt/locale/bitcoin_pt_BR.qm src/qt/locale/bitcoin_pt_PT.qm src/qt/locale/bitcoin_ro_RO.qm src/qt/locale/bitcoin_ru.qm src/qt/locale/bitcoin_sk.qm src/qt/locale/bitcoin_sr.qm src/qt/locale/bitcoin_sv.qm src/qt/locale/bitcoin_tr.qm src/qt/locale/bitcoin_uk.qm src/qt/locale/bitcoin_zh_CN.qm src/qt/locale/bitcoin_zh_TW.qm +compiler_TSQM_clean: + -$(DEL_FILE) src\qt\locale\bitcoin_bg.qm src\qt\locale\bitcoin_ca_ES.qm src\qt\locale\bitcoin_cs.qm src\qt\locale\bitcoin_da.qm src\qt\locale\bitcoin_de.qm src\qt\locale\bitcoin_el_GR.qm src\qt\locale\bitcoin_en.qm src\qt\locale\bitcoin_es.qm src\qt\locale\bitcoin_es_CL.qm src\qt\locale\bitcoin_et.qm src\qt\locale\bitcoin_eu_ES.qm src\qt\locale\bitcoin_fa.qm src\qt\locale\bitcoin_fa_IR.qm src\qt\locale\bitcoin_fi.qm src\qt\locale\bitcoin_fr.qm src\qt\locale\bitcoin_fr_CA.qm src\qt\locale\bitcoin_he.qm src\qt\locale\bitcoin_hr.qm src\qt\locale\bitcoin_hu.qm src\qt\locale\bitcoin_it.qm src\qt\locale\bitcoin_lt.qm src\qt\locale\bitcoin_nb.qm src\qt\locale\bitcoin_nl.qm src\qt\locale\bitcoin_pl.qm src\qt\locale\bitcoin_pt_BR.qm src\qt\locale\bitcoin_pt_PT.qm src\qt\locale\bitcoin_ro_RO.qm src\qt\locale\bitcoin_ru.qm src\qt\locale\bitcoin_sk.qm src\qt\locale\bitcoin_sr.qm src\qt\locale\bitcoin_sv.qm src\qt\locale\bitcoin_tr.qm src\qt\locale\bitcoin_uk.qm src\qt\locale\bitcoin_zh_CN.qm src\qt\locale\bitcoin_zh_TW.qm +src/qt/locale/bitcoin_bg.qm: src/qt/locale/bitcoin_bg.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_bg.ts -qm src\qt\locale\bitcoin_bg.qm + +src/qt/locale/bitcoin_ca_ES.qm: src/qt/locale/bitcoin_ca_ES.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_ca_ES.ts -qm src\qt\locale\bitcoin_ca_ES.qm + +src/qt/locale/bitcoin_cs.qm: src/qt/locale/bitcoin_cs.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_cs.ts -qm src\qt\locale\bitcoin_cs.qm + +src/qt/locale/bitcoin_da.qm: src/qt/locale/bitcoin_da.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_da.ts -qm src\qt\locale\bitcoin_da.qm + +src/qt/locale/bitcoin_de.qm: src/qt/locale/bitcoin_de.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_de.ts -qm src\qt\locale\bitcoin_de.qm + +src/qt/locale/bitcoin_el_GR.qm: src/qt/locale/bitcoin_el_GR.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_el_GR.ts -qm src\qt\locale\bitcoin_el_GR.qm + +src/qt/locale/bitcoin_en.qm: src/qt/locale/bitcoin_en.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_en.ts -qm src\qt\locale\bitcoin_en.qm + +src/qt/locale/bitcoin_es.qm: src/qt/locale/bitcoin_es.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_es.ts -qm src\qt\locale\bitcoin_es.qm + +src/qt/locale/bitcoin_es_CL.qm: src/qt/locale/bitcoin_es_CL.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_es_CL.ts -qm src\qt\locale\bitcoin_es_CL.qm + +src/qt/locale/bitcoin_et.qm: src/qt/locale/bitcoin_et.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_et.ts -qm src\qt\locale\bitcoin_et.qm + +src/qt/locale/bitcoin_eu_ES.qm: src/qt/locale/bitcoin_eu_ES.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_eu_ES.ts -qm src\qt\locale\bitcoin_eu_ES.qm + +src/qt/locale/bitcoin_fa.qm: src/qt/locale/bitcoin_fa.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fa.ts -qm src\qt\locale\bitcoin_fa.qm + +src/qt/locale/bitcoin_fa_IR.qm: src/qt/locale/bitcoin_fa_IR.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fa_IR.ts -qm src\qt\locale\bitcoin_fa_IR.qm + +src/qt/locale/bitcoin_fi.qm: src/qt/locale/bitcoin_fi.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fi.ts -qm src\qt\locale\bitcoin_fi.qm + +src/qt/locale/bitcoin_fr.qm: src/qt/locale/bitcoin_fr.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fr.ts -qm src\qt\locale\bitcoin_fr.qm + +src/qt/locale/bitcoin_fr_CA.qm: src/qt/locale/bitcoin_fr_CA.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fr_CA.ts -qm src\qt\locale\bitcoin_fr_CA.qm + +src/qt/locale/bitcoin_he.qm: src/qt/locale/bitcoin_he.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_he.ts -qm src\qt\locale\bitcoin_he.qm + +src/qt/locale/bitcoin_hr.qm: src/qt/locale/bitcoin_hr.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_hr.ts -qm src\qt\locale\bitcoin_hr.qm + +src/qt/locale/bitcoin_hu.qm: src/qt/locale/bitcoin_hu.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_hu.ts -qm src\qt\locale\bitcoin_hu.qm + +src/qt/locale/bitcoin_it.qm: src/qt/locale/bitcoin_it.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_it.ts -qm src\qt\locale\bitcoin_it.qm + +src/qt/locale/bitcoin_lt.qm: src/qt/locale/bitcoin_lt.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_lt.ts -qm src\qt\locale\bitcoin_lt.qm + +src/qt/locale/bitcoin_nb.qm: src/qt/locale/bitcoin_nb.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_nb.ts -qm src\qt\locale\bitcoin_nb.qm + +src/qt/locale/bitcoin_nl.qm: src/qt/locale/bitcoin_nl.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_nl.ts -qm src\qt\locale\bitcoin_nl.qm + +src/qt/locale/bitcoin_pl.qm: src/qt/locale/bitcoin_pl.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_pl.ts -qm src\qt\locale\bitcoin_pl.qm + +src/qt/locale/bitcoin_pt_BR.qm: src/qt/locale/bitcoin_pt_BR.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_pt_BR.ts -qm src\qt\locale\bitcoin_pt_BR.qm + +src/qt/locale/bitcoin_pt_PT.qm: src/qt/locale/bitcoin_pt_PT.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_pt_PT.ts -qm src\qt\locale\bitcoin_pt_PT.qm + +src/qt/locale/bitcoin_ro_RO.qm: src/qt/locale/bitcoin_ro_RO.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_ro_RO.ts -qm src\qt\locale\bitcoin_ro_RO.qm + +src/qt/locale/bitcoin_ru.qm: src/qt/locale/bitcoin_ru.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_ru.ts -qm src\qt\locale\bitcoin_ru.qm + +src/qt/locale/bitcoin_sk.qm: src/qt/locale/bitcoin_sk.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_sk.ts -qm src\qt\locale\bitcoin_sk.qm + +src/qt/locale/bitcoin_sr.qm: src/qt/locale/bitcoin_sr.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_sr.ts -qm src\qt\locale\bitcoin_sr.qm + +src/qt/locale/bitcoin_sv.qm: src/qt/locale/bitcoin_sv.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_sv.ts -qm src\qt\locale\bitcoin_sv.qm + +src/qt/locale/bitcoin_tr.qm: src/qt/locale/bitcoin_tr.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_tr.ts -qm src\qt\locale\bitcoin_tr.qm + +src/qt/locale/bitcoin_uk.qm: src/qt/locale/bitcoin_uk.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_uk.ts -qm src\qt\locale\bitcoin_uk.qm + +src/qt/locale/bitcoin_zh_CN.qm: src/qt/locale/bitcoin_zh_CN.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_zh_CN.ts -qm src\qt\locale\bitcoin_zh_CN.qm + +src/qt/locale/bitcoin_zh_TW.qm: src/qt/locale/bitcoin_zh_TW.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_zh_TW.ts -qm src\qt\locale\bitcoin_zh_TW.qm + +compiler_moc_header_make_all: build/moc_bitcoingui.cpp build/moc_transactiontablemodel.cpp build/moc_addresstablemodel.cpp build/moc_optionsdialog.cpp build/moc_sendcoinsdialog.cpp build/moc_addressbookpage.cpp build/moc_signverifymessagedialog.cpp build/moc_aboutdialog.cpp build/moc_editaddressdialog.cpp build/moc_bitcoinaddressvalidator.cpp build/moc_clientmodel.cpp build/moc_guiutil.cpp build/moc_optionsmodel.cpp build/moc_monitoreddatamapper.cpp build/moc_transactiondesc.cpp build/moc_transactiondescdialog.cpp build/moc_bitcoinamountfield.cpp build/moc_transactionfilterproxy.cpp build/moc_transactionview.cpp build/moc_walletmodel.cpp build/moc_overviewpage.cpp build/moc_csvmodelwriter.cpp build/moc_sendcoinsentry.cpp build/moc_qvalidatedlineedit.cpp build/moc_qvaluecombobox.cpp build/moc_askpassphrasedialog.cpp build/moc_notificator.cpp build/moc_rpcconsole.cpp +compiler_moc_header_clean: + -$(DEL_FILE) build\moc_bitcoingui.cpp build\moc_transactiontablemodel.cpp build\moc_addresstablemodel.cpp build\moc_optionsdialog.cpp build\moc_sendcoinsdialog.cpp build\moc_addressbookpage.cpp build\moc_signverifymessagedialog.cpp build\moc_aboutdialog.cpp build\moc_editaddressdialog.cpp build\moc_bitcoinaddressvalidator.cpp build\moc_clientmodel.cpp build\moc_guiutil.cpp build\moc_optionsmodel.cpp build\moc_monitoreddatamapper.cpp build\moc_transactiondesc.cpp build\moc_transactiondescdialog.cpp build\moc_bitcoinamountfield.cpp build\moc_transactionfilterproxy.cpp build\moc_transactionview.cpp build\moc_walletmodel.cpp build\moc_overviewpage.cpp build\moc_csvmodelwriter.cpp build\moc_sendcoinsentry.cpp build\moc_qvalidatedlineedit.cpp build\moc_qvaluecombobox.cpp build\moc_askpassphrasedialog.cpp build\moc_notificator.cpp build\moc_rpcconsole.cpp +build/moc_bitcoingui.cpp: src/qt/bitcoingui.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\bitcoingui.h -o build\moc_bitcoingui.cpp + +build/moc_transactiontablemodel.cpp: src/qt/transactiontablemodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactiontablemodel.h -o build\moc_transactiontablemodel.cpp + +build/moc_addresstablemodel.cpp: src/qt/addresstablemodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\addresstablemodel.h -o build\moc_addresstablemodel.cpp + +build/moc_optionsdialog.cpp: src/qt/optionsdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\optionsdialog.h -o build\moc_optionsdialog.cpp + +build/moc_sendcoinsdialog.cpp: src/qt/sendcoinsdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\sendcoinsdialog.h -o build\moc_sendcoinsdialog.cpp + +build/moc_addressbookpage.cpp: src/qt/addressbookpage.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\addressbookpage.h -o build\moc_addressbookpage.cpp + +build/moc_signverifymessagedialog.cpp: src/qt/signverifymessagedialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\signverifymessagedialog.h -o build\moc_signverifymessagedialog.cpp + +build/moc_aboutdialog.cpp: src/qt/aboutdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\aboutdialog.h -o build\moc_aboutdialog.cpp + +build/moc_editaddressdialog.cpp: src/qt/editaddressdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\editaddressdialog.h -o build\moc_editaddressdialog.cpp + +build/moc_bitcoinaddressvalidator.cpp: src/qt/bitcoinaddressvalidator.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\bitcoinaddressvalidator.h -o build\moc_bitcoinaddressvalidator.cpp + +build/moc_clientmodel.cpp: src/qt/clientmodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\clientmodel.h -o build\moc_clientmodel.cpp + +build/moc_guiutil.cpp: src/qt/guiutil.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\guiutil.h -o build\moc_guiutil.cpp + +build/moc_optionsmodel.cpp: src/qt/optionsmodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\optionsmodel.h -o build\moc_optionsmodel.cpp + +build/moc_monitoreddatamapper.cpp: src/qt/monitoreddatamapper.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\monitoreddatamapper.h -o build\moc_monitoreddatamapper.cpp + +build/moc_transactiondesc.cpp: src/qt/transactiondesc.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactiondesc.h -o build\moc_transactiondesc.cpp + +build/moc_transactiondescdialog.cpp: src/qt/transactiondescdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactiondescdialog.h -o build\moc_transactiondescdialog.cpp + +build/moc_bitcoinamountfield.cpp: src/qt/bitcoinamountfield.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\bitcoinamountfield.h -o build\moc_bitcoinamountfield.cpp + +build/moc_transactionfilterproxy.cpp: src/qt/transactionfilterproxy.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactionfilterproxy.h -o build\moc_transactionfilterproxy.cpp + +build/moc_transactionview.cpp: src/qt/transactionview.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactionview.h -o build\moc_transactionview.cpp + +build/moc_walletmodel.cpp: src/allocators.h \ + src/qt/walletmodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\walletmodel.h -o build\moc_walletmodel.cpp + +build/moc_overviewpage.cpp: src/qt/overviewpage.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\overviewpage.h -o build\moc_overviewpage.cpp + +build/moc_csvmodelwriter.cpp: src/qt/csvmodelwriter.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\csvmodelwriter.h -o build\moc_csvmodelwriter.cpp + +build/moc_sendcoinsentry.cpp: src/qt/sendcoinsentry.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\sendcoinsentry.h -o build\moc_sendcoinsentry.cpp + +build/moc_qvalidatedlineedit.cpp: src/qt/qvalidatedlineedit.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\qvalidatedlineedit.h -o build\moc_qvalidatedlineedit.cpp + +build/moc_qvaluecombobox.cpp: src/qt/qvaluecombobox.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\qvaluecombobox.h -o build\moc_qvaluecombobox.cpp + +build/moc_askpassphrasedialog.cpp: src/qt/askpassphrasedialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\askpassphrasedialog.h -o build\moc_askpassphrasedialog.cpp + +build/moc_notificator.cpp: src/qt/notificator.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\notificator.h -o build\moc_notificator.cpp + +build/moc_rpcconsole.cpp: src/qt/rpcconsole.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\rpcconsole.h -o build\moc_rpcconsole.cpp + +compiler_rcc_make_all: debug/qrc_bitcoin.cpp +compiler_rcc_clean: + -$(DEL_FILE) debug\qrc_bitcoin.cpp +debug/qrc_bitcoin.cpp: src/qt/bitcoin.qrc \ + src/qt/locale/bitcoin_fa_IR.qm \ + src/qt/locale/bitcoin_hr.qm \ + src/qt/locale/bitcoin_hu.qm \ + src/qt/locale/bitcoin_zh_CN.qm \ + src/qt/locale/bitcoin_bg.qm \ + src/qt/locale/bitcoin_eu_ES.qm \ + src/qt/locale/bitcoin_fr.qm \ + src/qt/locale/bitcoin_nb.qm \ + src/qt/locale/bitcoin_tr.qm \ + src/qt/locale/bitcoin_pl.qm \ + src/qt/locale/bitcoin_ru.qm \ + src/qt/locale/bitcoin_nl.qm \ + src/qt/locale/bitcoin_uk.qm \ + src/qt/locale/bitcoin_it.qm \ + src/qt/locale/bitcoin_ca_ES.qm \ + src/qt/locale/bitcoin_ro_RO.qm \ + src/qt/locale/bitcoin_sk.qm \ + src/qt/locale/bitcoin_en.qm \ + src/qt/locale/bitcoin_el_GR.qm \ + src/qt/locale/bitcoin_es_CL.qm \ + src/qt/locale/bitcoin_he.qm \ + src/qt/locale/bitcoin_fa.qm \ + src/qt/locale/bitcoin_zh_TW.qm \ + src/qt/locale/bitcoin_es.qm \ + src/qt/locale/bitcoin_et.qm \ + src/qt/locale/bitcoin_pt_BR.qm \ + src/qt/locale/bitcoin_sr.qm \ + src/qt/locale/bitcoin_lt.qm \ + src/qt/locale/bitcoin_da.qm \ + src/qt/locale/bitcoin_cs.qm \ + src/qt/locale/bitcoin_pt_PT.qm \ + src/qt/locale/bitcoin_sv.qm \ + src/qt/locale/bitcoin_fi.qm \ + src/qt/locale/bitcoin_fr_CA.qm \ + src/qt/locale/bitcoin_de.qm \ + src/qt/res/images/about.png \ + src/qt/res/images/splash2.jpg \ + src/qt/res/images/wallet.png \ + src/qt/res/movies/update_spinner.mng \ + src/qt/res/icons/add.png \ + src/qt/res/icons/connect0_16.png \ + src/qt/res/icons/connect1_16.png \ + src/qt/res/icons/quit.png \ + src/qt/res/icons/connect2_16.png \ + src/qt/res/icons/overview.png \ + src/qt/res/icons/tx_mined.png \ + src/qt/res/icons/connect3_16.png \ + src/qt/res/icons/connect4_16.png \ + src/qt/res/icons/address-book.png \ + src/qt/res/icons/send.png \ + src/qt/res/icons/configure.png \ + src/qt/res/icons/export.png \ + src/qt/res/icons/synced.png \ + src/qt/res/icons/history.png \ + src/qt/res/icons/filesave.png \ + src/qt/res/icons/transaction2.png \ + src/qt/res/icons/editpaste.png \ + src/qt/res/icons/edit.png \ + src/qt/res/icons/lock_closed.png \ + src/qt/res/icons/editcopy.png \ + src/qt/res/icons/receive.png \ + src/qt/res/icons/transaction0.png \ + src/qt/res/icons/clock1.png \ + src/qt/res/icons/clock2.png \ + src/qt/res/icons/clock3.png \ + src/qt/res/icons/clock4.png \ + src/qt/res/icons/clock5.png \ + src/qt/res/icons/qrcode.png \ + src/qt/res/icons/toolbar_testnet.png \ + src/qt/res/icons/bitcoin.png \ + src/qt/res/icons/key.png \ + src/qt/res/icons/tx_inout.png \ + src/qt/res/icons/remove.png \ + src/qt/res/icons/toolbar.png \ + src/qt/res/icons/lock_open.png \ + src/qt/res/icons/bitcoin_testnet.png \ + src/qt/res/icons/tx_input.png \ + src/qt/res/icons/debugwindow.png \ + src/qt/res/icons/tx_output.png + c:\QtSDK\4.8.4\bin\rcc.exe -name bitcoin src\qt\bitcoin.qrc -o debug\qrc_bitcoin.cpp + +compiler_image_collection_make_all: build/qmake_image_collection.cpp +compiler_image_collection_clean: + -$(DEL_FILE) build\qmake_image_collection.cpp +compiler_moc_source_make_all: build/overviewpage.moc build/rpcconsole.moc +compiler_moc_source_clean: + -$(DEL_FILE) build\overviewpage.moc build\rpcconsole.moc +build/overviewpage.moc: src/qt/overviewpage.h \ + build/ui_overviewpage.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/bitcoinunits.h \ + src/qt/optionsmodel.h \ + src/qt/transactiontablemodel.h \ + src/qt/transactionfilterproxy.h \ + src/qt/guiutil.h \ + src/qt/guiconstants.h \ + src/qt/overviewpage.cpp + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\overviewpage.cpp -o build\overviewpage.moc + +build/rpcconsole.moc: src/qt/rpcconsole.h \ + build/ui_rpcconsole.h \ + src/qt/clientmodel.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/qt/guiutil.h \ + src/qt/rpcconsole.cpp + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\rpcconsole.cpp -o build\rpcconsole.moc + +compiler_uic_make_all: build/ui_sendcoinsdialog.h build/ui_addressbookpage.h build/ui_signverifymessagedialog.h build/ui_aboutdialog.h build/ui_editaddressdialog.h build/ui_transactiondescdialog.h build/ui_overviewpage.h build/ui_sendcoinsentry.h build/ui_askpassphrasedialog.h build/ui_rpcconsole.h build/ui_optionsdialog.h +compiler_uic_clean: + -$(DEL_FILE) build\ui_sendcoinsdialog.h build\ui_addressbookpage.h build\ui_signverifymessagedialog.h build\ui_aboutdialog.h build\ui_editaddressdialog.h build\ui_transactiondescdialog.h build\ui_overviewpage.h build\ui_sendcoinsentry.h build\ui_askpassphrasedialog.h build\ui_rpcconsole.h build\ui_optionsdialog.h +build/ui_sendcoinsdialog.h: src/qt/forms/sendcoinsdialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\sendcoinsdialog.ui -o build\ui_sendcoinsdialog.h + +build/ui_addressbookpage.h: src/qt/forms/addressbookpage.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\addressbookpage.ui -o build\ui_addressbookpage.h + +build/ui_signverifymessagedialog.h: src/qt/forms/signverifymessagedialog.ui \ + src/qt/qvalidatedlineedit.h + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\signverifymessagedialog.ui -o build\ui_signverifymessagedialog.h + +build/ui_aboutdialog.h: src/qt/forms/aboutdialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\aboutdialog.ui -o build\ui_aboutdialog.h + +build/ui_editaddressdialog.h: src/qt/forms/editaddressdialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\editaddressdialog.ui -o build\ui_editaddressdialog.h + +build/ui_transactiondescdialog.h: src/qt/forms/transactiondescdialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\transactiondescdialog.ui -o build\ui_transactiondescdialog.h + +build/ui_overviewpage.h: src/qt/forms/overviewpage.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\overviewpage.ui -o build\ui_overviewpage.h + +build/ui_sendcoinsentry.h: src/qt/forms/sendcoinsentry.ui \ + src/qt/bitcoinamountfield.h \ + src/qt/qvalidatedlineedit.h + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\sendcoinsentry.ui -o build\ui_sendcoinsentry.h + +build/ui_askpassphrasedialog.h: src/qt/forms/askpassphrasedialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\askpassphrasedialog.ui -o build\ui_askpassphrasedialog.h + +build/ui_rpcconsole.h: src/qt/forms/rpcconsole.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\rpcconsole.ui -o build\ui_rpcconsole.h + +build/ui_optionsdialog.h: src/qt/forms/optionsdialog.ui \ + src/qt/bitcoinamountfield.h \ + src/qt/qvaluecombobox.h \ + src/qt/qvalidatedlineedit.h + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\optionsdialog.ui -o build\ui_optionsdialog.h + +compiler_yacc_decl_make_all: +compiler_yacc_decl_clean: +compiler_yacc_impl_make_all: +compiler_yacc_impl_clean: +compiler_lex_make_all: +compiler_lex_clean: +compiler_clean: compiler_TSQM_clean compiler_moc_header_clean compiler_rcc_clean compiler_moc_source_clean compiler_uic_clean + + + +####### Compile + +build/bitcoin.o: src/qt/bitcoin.cpp src/qt/bitcoingui.h \ + src/qt/clientmodel.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/optionsmodel.h \ + src/qt/guiutil.h \ + src/qt/guiconstants.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/qt/qtipcserver.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoin.o src\qt\bitcoin.cpp + +build/bitcoingui.o: src/qt/bitcoingui.cpp src/qt/bitcoingui.h \ + src/qt/transactiontablemodel.h \ + src/qt/addressbookpage.h \ + src/qt/sendcoinsdialog.h \ + src/qt/signverifymessagedialog.h \ + src/qt/optionsdialog.h \ + src/qt/aboutdialog.h \ + src/qt/clientmodel.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/editaddressdialog.h \ + src/qt/optionsmodel.h \ + src/qt/transactiondescdialog.h \ + src/qt/addresstablemodel.h \ + src/qt/transactionview.h \ + src/qt/overviewpage.h \ + src/qt/bitcoinunits.h \ + src/qt/guiconstants.h \ + src/qt/askpassphrasedialog.h \ + src/qt/notificator.h \ + src/qt/guiutil.h \ + src/qt/rpcconsole.h \ + src/qt/macdockiconhandler.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoingui.o src\qt\bitcoingui.cpp + +build/transactiontablemodel.o: src/qt/transactiontablemodel.cpp src/qt/transactiontablemodel.h \ + src/qt/guiutil.h \ + src/qt/transactionrecord.h \ + src/uint256.h \ + src/qt/guiconstants.h \ + src/qt/transactiondesc.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/optionsmodel.h \ + src/qt/addresstablemodel.h \ + src/qt/bitcoinunits.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactiontablemodel.o src\qt\transactiontablemodel.cpp + +build/addresstablemodel.o: src/qt/addresstablemodel.cpp src/qt/addresstablemodel.h \ + src/qt/guiutil.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\addresstablemodel.o src\qt\addresstablemodel.cpp + +build/optionsdialog.o: src/qt/optionsdialog.cpp src/qt/optionsdialog.h \ + build/ui_optionsdialog.h \ + src/qt/bitcoinamountfield.h \ + src/qt/bitcoinunits.h \ + src/qt/monitoreddatamapper.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/qt/optionsmodel.h \ + src/qt/qvalidatedlineedit.h \ + src/qt/qvaluecombobox.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\optionsdialog.o src\qt\optionsdialog.cpp + +build/sendcoinsdialog.o: src/qt/sendcoinsdialog.cpp src/qt/sendcoinsdialog.h \ + build/ui_sendcoinsdialog.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/bitcoinunits.h \ + src/qt/addressbookpage.h \ + src/qt/optionsmodel.h \ + src/qt/sendcoinsentry.h \ + src/qt/guiutil.h \ + src/qt/askpassphrasedialog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\sendcoinsdialog.o src\qt\sendcoinsdialog.cpp + +build/addressbookpage.o: src/qt/addressbookpage.cpp src/qt/addressbookpage.h \ + build/ui_addressbookpage.h \ + src/qt/addresstablemodel.h \ + src/qt/optionsmodel.h \ + src/qt/bitcoingui.h \ + src/qt/editaddressdialog.h \ + src/qt/csvmodelwriter.h \ + src/qt/guiutil.h \ + src/qt/qrcodedialog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\addressbookpage.o src\qt\addressbookpage.cpp + +build/signverifymessagedialog.o: src/qt/signverifymessagedialog.cpp src/qt/signverifymessagedialog.h \ + build/ui_signverifymessagedialog.h \ + src/qt/addressbookpage.h \ + src/base58.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/sync.h \ + src/qt/guiutil.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/qt/optionsmodel.h \ + src/qt/walletmodel.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\signverifymessagedialog.o src\qt\signverifymessagedialog.cpp + +build/aboutdialog.o: src/qt/aboutdialog.cpp src/qt/aboutdialog.h \ + build/ui_aboutdialog.h \ + src/qt/clientmodel.h \ + src/version.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\aboutdialog.o src\qt\aboutdialog.cpp + +build/editaddressdialog.o: src/qt/editaddressdialog.cpp src/qt/editaddressdialog.h \ + build/ui_editaddressdialog.h \ + src/qt/addresstablemodel.h \ + src/qt/guiutil.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\editaddressdialog.o src\qt\editaddressdialog.cpp + +build/bitcoinaddressvalidator.o: src/qt/bitcoinaddressvalidator.cpp src/qt/bitcoinaddressvalidator.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinaddressvalidator.o src\qt\bitcoinaddressvalidator.cpp + +build/version.o: src/version.cpp src/version.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\version.o src\version.cpp + +build/sync.o: src/sync.cpp src/sync.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\sync.o src\sync.cpp + +build/util.o: src/util.cpp src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/sync.h \ + src/strlcpy.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\util.o src\util.cpp + +build/netbase.o: src/netbase.cpp src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/util.h \ + src/uint256.h \ + src/strlcpy.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\netbase.o src\netbase.cpp + +build/key.o: src/key.cpp src/key.h \ + src/allocators.h \ + src/serialize.h \ + src/version.h \ + src/uint256.h \ + src/util.h \ + src/netbase.h \ + src/compat.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\key.o src\key.cpp + +build/script.o: src/script.cpp src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/allocators.h \ + src/key.h \ + src/serialize.h \ + src/version.h \ + src/uint256.h \ + src/util.h \ + src/netbase.h \ + src/compat.h \ + src/sync.h \ + src/bignum.h \ + src/main.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/db.h \ + src/scrypt.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\script.o src\script.cpp + +build/main.o: src/main.cpp src/checkpoints.h \ + src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\main.o src\main.cpp + +build/init.o: src/init.cpp src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/walletdb.h \ + src/base58.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\init.o src\init.cpp + +build/net.o: src/net.cpp src/irc.h \ + src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h \ + src/strlcpy.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\net.o src\net.cpp + +build/irc.o: src/irc.cpp src/irc.h \ + src/net.h \ + src/mruset.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/protocol.h \ + src/uint256.h \ + src/addrman.h \ + src/util.h \ + src/sync.h \ + src/strlcpy.h \ + src/base58.h \ + src/bignum.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\irc.o src\irc.cpp + +build/checkpoints.o: src/checkpoints.cpp src/checkpoints.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\checkpoints.o src\checkpoints.cpp + +build/addrman.o: src/addrman.cpp src/addrman.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/protocol.h \ + src/uint256.h \ + src/util.h \ + src/sync.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\addrman.o src\addrman.cpp + +build/db.o: src/db.cpp src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\db.o src\db.cpp + +build/walletdb.o: src/walletdb.cpp src/walletdb.h \ + src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/base58.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\walletdb.o src\walletdb.cpp + +build/json_spirit_writer.o: src/json/json_spirit_writer.cpp src/json/json_spirit_writer.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_writer_template.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\json_spirit_writer.o src\json\json_spirit_writer.cpp + +build/json_spirit_value.o: src/json/json_spirit_value.cpp src/json/json_spirit_value.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\json_spirit_value.o src\json\json_spirit_value.cpp + +build/json_spirit_reader.o: src/json/json_spirit_reader.cpp src/json/json_spirit_reader.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_reader_template.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\json_spirit_reader.o src\json\json_spirit_reader.cpp + +build/clientmodel.o: src/qt/clientmodel.cpp src/qt/clientmodel.h \ + src/qt/guiconstants.h \ + src/qt/optionsmodel.h \ + src/qt/addresstablemodel.h \ + src/qt/transactiontablemodel.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\clientmodel.o src\qt\clientmodel.cpp + +build/guiutil.o: src/qt/guiutil.cpp src/qt/guiutil.h \ + src/qt/bitcoinaddressvalidator.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/bitcoinunits.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\guiutil.o src\qt\guiutil.cpp + +build/transactionrecord.o: src/qt/transactionrecord.cpp src/qt/transactionrecord.h \ + src/uint256.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactionrecord.o src\qt\transactionrecord.cpp + +build/optionsmodel.o: src/qt/optionsmodel.cpp src/qt/optionsmodel.h \ + src/qt/bitcoinunits.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/walletdb.h \ + src/base58.h \ + src/qt/guiutil.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\optionsmodel.o src\qt\optionsmodel.cpp + +build/monitoreddatamapper.o: src/qt/monitoreddatamapper.cpp src/qt/monitoreddatamapper.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\monitoreddatamapper.o src\qt\monitoreddatamapper.cpp + +build/transactiondesc.o: src/qt/transactiondesc.cpp src/qt/transactiondesc.h \ + src/qt/guiutil.h \ + src/qt/bitcoinunits.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/wallet.h \ + src/ui_interface.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactiondesc.o src\qt\transactiondesc.cpp + +build/transactiondescdialog.o: src/qt/transactiondescdialog.cpp src/qt/transactiondescdialog.h \ + build/ui_transactiondescdialog.h \ + src/qt/transactiontablemodel.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactiondescdialog.o src\qt\transactiondescdialog.cpp + +build/bitcoinstrings.o: src/qt/bitcoinstrings.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinstrings.o src\qt\bitcoinstrings.cpp + +build/bitcoinamountfield.o: src/qt/bitcoinamountfield.cpp src/qt/bitcoinamountfield.h \ + src/qt/qvaluecombobox.h \ + src/qt/bitcoinunits.h \ + src/qt/guiconstants.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinamountfield.o src\qt\bitcoinamountfield.cpp + +build/wallet.o: src/wallet.cpp src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/walletdb.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\wallet.o src\wallet.cpp + +build/keystore.o: src/keystore.cpp src/keystore.h \ + src/crypter.h \ + src/allocators.h \ + src/key.h \ + src/serialize.h \ + src/version.h \ + src/uint256.h \ + src/util.h \ + src/netbase.h \ + src/compat.h \ + src/sync.h \ + src/script.h \ + src/bignum.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\keystore.o src\keystore.cpp + +build/transactionfilterproxy.o: src/qt/transactionfilterproxy.cpp src/qt/transactionfilterproxy.h \ + src/qt/transactiontablemodel.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactionfilterproxy.o src\qt\transactionfilterproxy.cpp + +build/transactionview.o: src/qt/transactionview.cpp src/qt/transactionview.h \ + src/qt/transactionfilterproxy.h \ + src/qt/transactionrecord.h \ + src/uint256.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/addresstablemodel.h \ + src/qt/transactiontablemodel.h \ + src/qt/bitcoinunits.h \ + src/qt/csvmodelwriter.h \ + src/qt/transactiondescdialog.h \ + src/qt/editaddressdialog.h \ + src/qt/optionsmodel.h \ + src/qt/guiutil.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactionview.o src\qt\transactionview.cpp + +build/walletmodel.o: src/qt/walletmodel.cpp src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/guiconstants.h \ + src/qt/optionsmodel.h \ + src/qt/addresstablemodel.h \ + src/qt/transactiontablemodel.h \ + src/ui_interface.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/walletdb.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\walletmodel.o src\qt\walletmodel.cpp + +build/bitcoinrpc.o: src/bitcoinrpc.cpp src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/wallet.h \ + src/ui_interface.h \ + src/walletdb.h \ + src/base58.h \ + src/init.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinrpc.o src\bitcoinrpc.cpp + +build/rpcdump.o: src/rpcdump.cpp src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\rpcdump.o src\rpcdump.cpp + +build/rpcnet.o: src/rpcnet.cpp src/net.h \ + src/mruset.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/protocol.h \ + src/uint256.h \ + src/addrman.h \ + src/util.h \ + src/sync.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\rpcnet.o src\rpcnet.cpp + +build/rpcrawtransaction.o: src/rpcrawtransaction.cpp src/base58.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/sync.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/db.h \ + src/main.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\rpcrawtransaction.o src\rpcrawtransaction.cpp + +build/overviewpage.o: src/qt/overviewpage.cpp src/qt/overviewpage.h \ + build/ui_overviewpage.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/bitcoinunits.h \ + src/qt/optionsmodel.h \ + src/qt/transactiontablemodel.h \ + src/qt/transactionfilterproxy.h \ + src/qt/guiutil.h \ + src/qt/guiconstants.h \ + build/overviewpage.moc + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\overviewpage.o src\qt\overviewpage.cpp + +build/csvmodelwriter.o: src/qt/csvmodelwriter.cpp src/qt/csvmodelwriter.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\csvmodelwriter.o src\qt\csvmodelwriter.cpp + +build/crypter.o: src/crypter.cpp src/crypter.h \ + src/allocators.h \ + src/key.h \ + src/serialize.h \ + src/version.h \ + src/uint256.h \ + src/util.h \ + src/netbase.h \ + src/compat.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\crypter.o src\crypter.cpp + +build/sendcoinsentry.o: src/qt/sendcoinsentry.cpp src/qt/sendcoinsentry.h \ + build/ui_sendcoinsentry.h \ + src/qt/guiutil.h \ + src/qt/bitcoinunits.h \ + src/qt/addressbookpage.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/optionsmodel.h \ + src/qt/addresstablemodel.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\sendcoinsentry.o src\qt\sendcoinsentry.cpp + +build/qvalidatedlineedit.o: src/qt/qvalidatedlineedit.cpp src/qt/qvalidatedlineedit.h \ + src/qt/guiconstants.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\qvalidatedlineedit.o src\qt\qvalidatedlineedit.cpp + +build/bitcoinunits.o: src/qt/bitcoinunits.cpp src/qt/bitcoinunits.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinunits.o src\qt\bitcoinunits.cpp + +build/qvaluecombobox.o: src/qt/qvaluecombobox.cpp src/qt/qvaluecombobox.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\qvaluecombobox.o src\qt\qvaluecombobox.cpp + +build/askpassphrasedialog.o: src/qt/askpassphrasedialog.cpp src/qt/askpassphrasedialog.h \ + build/ui_askpassphrasedialog.h \ + src/qt/guiconstants.h \ + src/qt/walletmodel.h \ + src/allocators.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\askpassphrasedialog.o src\qt\askpassphrasedialog.cpp + +build/protocol.o: src/protocol.cpp src/protocol.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/netbase.h \ + src/compat.h \ + src/uint256.h \ + src/util.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\protocol.o src\protocol.cpp + +build/notificator.o: src/qt/notificator.cpp src/qt/notificator.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\notificator.o src\qt\notificator.cpp + +build/qtipcserver.o: src/qt/qtipcserver.cpp src/qt/qtipcserver.h \ + src/qt/guiconstants.h \ + src/ui_interface.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\qtipcserver.o src\qt\qtipcserver.cpp + +build/rpcconsole.o: src/qt/rpcconsole.cpp src/qt/rpcconsole.h \ + build/ui_rpcconsole.h \ + src/qt/clientmodel.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/qt/guiutil.h \ + build/rpcconsole.moc + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\rpcconsole.o src\qt\rpcconsole.cpp + +build/scrypt.o: src/scrypt.c src/scrypt.h + $(CC) -c $(CFLAGS) $(INCPATH) -o build\scrypt.o src\scrypt.c + +build/noui.o: src/noui.cpp src/ui_interface.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\noui.o src\noui.cpp + +build/moc_bitcoingui.o: build/moc_bitcoingui.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_bitcoingui.o build\moc_bitcoingui.cpp + +build/moc_transactiontablemodel.o: build/moc_transactiontablemodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactiontablemodel.o build\moc_transactiontablemodel.cpp + +build/moc_addresstablemodel.o: build/moc_addresstablemodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_addresstablemodel.o build\moc_addresstablemodel.cpp + +build/moc_optionsdialog.o: build/moc_optionsdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_optionsdialog.o build\moc_optionsdialog.cpp + +build/moc_sendcoinsdialog.o: build/moc_sendcoinsdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_sendcoinsdialog.o build\moc_sendcoinsdialog.cpp + +build/moc_addressbookpage.o: build/moc_addressbookpage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_addressbookpage.o build\moc_addressbookpage.cpp + +build/moc_signverifymessagedialog.o: build/moc_signverifymessagedialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_signverifymessagedialog.o build\moc_signverifymessagedialog.cpp + +build/moc_aboutdialog.o: build/moc_aboutdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_aboutdialog.o build\moc_aboutdialog.cpp + +build/moc_editaddressdialog.o: build/moc_editaddressdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_editaddressdialog.o build\moc_editaddressdialog.cpp + +build/moc_bitcoinaddressvalidator.o: build/moc_bitcoinaddressvalidator.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_bitcoinaddressvalidator.o build\moc_bitcoinaddressvalidator.cpp + +build/moc_clientmodel.o: build/moc_clientmodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_clientmodel.o build\moc_clientmodel.cpp + +build/moc_guiutil.o: build/moc_guiutil.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_guiutil.o build\moc_guiutil.cpp + +build/moc_optionsmodel.o: build/moc_optionsmodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_optionsmodel.o build\moc_optionsmodel.cpp + +build/moc_monitoreddatamapper.o: build/moc_monitoreddatamapper.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_monitoreddatamapper.o build\moc_monitoreddatamapper.cpp + +build/moc_transactiondesc.o: build/moc_transactiondesc.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactiondesc.o build\moc_transactiondesc.cpp + +build/moc_transactiondescdialog.o: build/moc_transactiondescdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactiondescdialog.o build\moc_transactiondescdialog.cpp + +build/moc_bitcoinamountfield.o: build/moc_bitcoinamountfield.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_bitcoinamountfield.o build\moc_bitcoinamountfield.cpp + +build/moc_transactionfilterproxy.o: build/moc_transactionfilterproxy.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactionfilterproxy.o build\moc_transactionfilterproxy.cpp + +build/moc_transactionview.o: build/moc_transactionview.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactionview.o build\moc_transactionview.cpp + +build/moc_walletmodel.o: build/moc_walletmodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_walletmodel.o build\moc_walletmodel.cpp + +build/moc_overviewpage.o: build/moc_overviewpage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_overviewpage.o build\moc_overviewpage.cpp + +build/moc_csvmodelwriter.o: build/moc_csvmodelwriter.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_csvmodelwriter.o build\moc_csvmodelwriter.cpp + +build/moc_sendcoinsentry.o: build/moc_sendcoinsentry.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_sendcoinsentry.o build\moc_sendcoinsentry.cpp + +build/moc_qvalidatedlineedit.o: build/moc_qvalidatedlineedit.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_qvalidatedlineedit.o build\moc_qvalidatedlineedit.cpp + +build/moc_qvaluecombobox.o: build/moc_qvaluecombobox.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_qvaluecombobox.o build\moc_qvaluecombobox.cpp + +build/moc_askpassphrasedialog.o: build/moc_askpassphrasedialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_askpassphrasedialog.o build\moc_askpassphrasedialog.cpp + +build/moc_notificator.o: build/moc_notificator.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_notificator.o build\moc_notificator.cpp + +build/moc_rpcconsole.o: build/moc_rpcconsole.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_rpcconsole.o build\moc_rpcconsole.cpp + +build/qrc_bitcoin.o: debug/qrc_bitcoin.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\qrc_bitcoin.o debug\qrc_bitcoin.cpp + +####### Install + +install: FORCE + +uninstall: FORCE + +FORCE: + diff --git a/Makefile.Release b/Makefile.Release new file mode 100644 index 0000000..656e1a5 --- /dev/null +++ b/Makefile.Release @@ -0,0 +1,1711 @@ +############################################################################# +# Makefile for building: casinocoin-qt +# Generated by qmake (2.01a) (Qt 4.8.4) on: Wed Jul 17 17:29:57 2013 +# Project: casinocoin-qt.pro +# Template: app +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +DEFINES = -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_GUI -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -DUSE_IPV6 -D__NO_SYSTEM_INCLUDES -DWIN32 -D_MT -DQT_DLL -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN +CFLAGS = -pipe -O2 -Wall -Wextra $(DEFINES) +CXXFLAGS = -pipe -O2 -frtti -fexceptions -mthreads -fdiagnostics-show-option -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEFINES) +INCPATH = -I"c:\QtSDK\4.8.4\include\QtCore" -I"c:\QtSDK\4.8.4\include\QtGui" -I"c:\QtSDK\4.8.4\include" -I"src" -I"src\json" -I"src\qt" -I"..\..\deps\boost_1_53_0" -I"..\..\deps\db-4.8.30.NC\build_unix" -I"..\..\deps\openssl-1.0.1b\include" -I"c:\QtSDK\4.8.4\include\ActiveQt" -I"build" -I"build" -I"c:\QtSDK\4.8.4\mkspecs\win32-g++" +LINK = g++ +LFLAGS = -Wl,-s -mthreads -Wl,-subsystem,windows +LIBS = -L"c:\QtSDK\4.8.4\lib" -lmingwthrd -lmingw32 -lqtmain build\bitcoin-qt_res.o -lshlwapi -LE:/crypto/deps/boost_1_53_0/stage/lib -LE:/crypto/deps/db-4.8.30.NC/build_unix -LE:/crypto/deps/openssl-1.0.1b -lssl -lcrypto -ldb_cxx -lws2_32 -lole32 -lmswsock -loleaut32 -luuid -lgdi32 -lboost_system-mgw46-mt-s-1_53 -lboost_filesystem-mgw46-mt-s-1_53 -lboost_program_options-mgw46-mt-s-1_53 -lboost_thread-mgw46-mt-s-1_53 -lQtGui4 -lQtCore4 +QMAKE = c:\QtSDK\4.8.4\bin\qmake.exe +IDC = c:\QtSDK\4.8.4\bin\idc.exe +IDL = midl +ZIP = zip -r -9 +DEF_FILE = +RES_FILE = build\bitcoin-qt_res.o +COPY = copy /y +SED = +COPY_FILE = $(COPY) +COPY_DIR = xcopy /s /q /y /i +DEL_FILE = del +DEL_DIR = rmdir +MOVE = move +CHK_DIR_EXISTS= if not exist +MKDIR = mkdir +INSTALL_FILE = $(COPY_FILE) +INSTALL_PROGRAM = $(COPY_FILE) +INSTALL_DIR = $(COPY_DIR) + +####### Output directory + +OBJECTS_DIR = build + +####### Files + +SOURCES = src\qt\bitcoin.cpp \ + src\qt\bitcoingui.cpp \ + src\qt\transactiontablemodel.cpp \ + src\qt\addresstablemodel.cpp \ + src\qt\optionsdialog.cpp \ + src\qt\sendcoinsdialog.cpp \ + src\qt\addressbookpage.cpp \ + src\qt\signverifymessagedialog.cpp \ + src\qt\aboutdialog.cpp \ + src\qt\editaddressdialog.cpp \ + src\qt\bitcoinaddressvalidator.cpp \ + src\version.cpp \ + src\sync.cpp \ + src\util.cpp \ + src\netbase.cpp \ + src\key.cpp \ + src\script.cpp \ + src\main.cpp \ + src\init.cpp \ + src\net.cpp \ + src\irc.cpp \ + src\checkpoints.cpp \ + src\addrman.cpp \ + src\db.cpp \ + src\walletdb.cpp \ + src\json\json_spirit_writer.cpp \ + src\json\json_spirit_value.cpp \ + src\json\json_spirit_reader.cpp \ + src\qt\clientmodel.cpp \ + src\qt\guiutil.cpp \ + src\qt\transactionrecord.cpp \ + src\qt\optionsmodel.cpp \ + src\qt\monitoreddatamapper.cpp \ + src\qt\transactiondesc.cpp \ + src\qt\transactiondescdialog.cpp \ + src\qt\bitcoinstrings.cpp \ + src\qt\bitcoinamountfield.cpp \ + src\wallet.cpp \ + src\keystore.cpp \ + src\qt\transactionfilterproxy.cpp \ + src\qt\transactionview.cpp \ + src\qt\walletmodel.cpp \ + src\bitcoinrpc.cpp \ + src\rpcdump.cpp \ + src\rpcnet.cpp \ + src\rpcrawtransaction.cpp \ + src\qt\overviewpage.cpp \ + src\qt\csvmodelwriter.cpp \ + src\crypter.cpp \ + src\qt\sendcoinsentry.cpp \ + src\qt\qvalidatedlineedit.cpp \ + src\qt\bitcoinunits.cpp \ + src\qt\qvaluecombobox.cpp \ + src\qt\askpassphrasedialog.cpp \ + src\protocol.cpp \ + src\qt\notificator.cpp \ + src\qt\qtipcserver.cpp \ + src\qt\rpcconsole.cpp \ + src\scrypt.c \ + src\noui.cpp build\moc_bitcoingui.cpp \ + build\moc_transactiontablemodel.cpp \ + build\moc_addresstablemodel.cpp \ + build\moc_optionsdialog.cpp \ + build\moc_sendcoinsdialog.cpp \ + build\moc_addressbookpage.cpp \ + build\moc_signverifymessagedialog.cpp \ + build\moc_aboutdialog.cpp \ + build\moc_editaddressdialog.cpp \ + build\moc_bitcoinaddressvalidator.cpp \ + build\moc_clientmodel.cpp \ + build\moc_guiutil.cpp \ + build\moc_optionsmodel.cpp \ + build\moc_monitoreddatamapper.cpp \ + build\moc_transactiondesc.cpp \ + build\moc_transactiondescdialog.cpp \ + build\moc_bitcoinamountfield.cpp \ + build\moc_transactionfilterproxy.cpp \ + build\moc_transactionview.cpp \ + build\moc_walletmodel.cpp \ + build\moc_overviewpage.cpp \ + build\moc_csvmodelwriter.cpp \ + build\moc_sendcoinsentry.cpp \ + build\moc_qvalidatedlineedit.cpp \ + build\moc_qvaluecombobox.cpp \ + build\moc_askpassphrasedialog.cpp \ + build\moc_notificator.cpp \ + build\moc_rpcconsole.cpp \ + release\qrc_bitcoin.cpp +OBJECTS = build/bitcoin.o \ + build/bitcoingui.o \ + build/transactiontablemodel.o \ + build/addresstablemodel.o \ + build/optionsdialog.o \ + build/sendcoinsdialog.o \ + build/addressbookpage.o \ + build/signverifymessagedialog.o \ + build/aboutdialog.o \ + build/editaddressdialog.o \ + build/bitcoinaddressvalidator.o \ + build/version.o \ + build/sync.o \ + build/util.o \ + build/netbase.o \ + build/key.o \ + build/script.o \ + build/main.o \ + build/init.o \ + build/net.o \ + build/irc.o \ + build/checkpoints.o \ + build/addrman.o \ + build/db.o \ + build/walletdb.o \ + build/json_spirit_writer.o \ + build/json_spirit_value.o \ + build/json_spirit_reader.o \ + build/clientmodel.o \ + build/guiutil.o \ + build/transactionrecord.o \ + build/optionsmodel.o \ + build/monitoreddatamapper.o \ + build/transactiondesc.o \ + build/transactiondescdialog.o \ + build/bitcoinstrings.o \ + build/bitcoinamountfield.o \ + build/wallet.o \ + build/keystore.o \ + build/transactionfilterproxy.o \ + build/transactionview.o \ + build/walletmodel.o \ + build/bitcoinrpc.o \ + build/rpcdump.o \ + build/rpcnet.o \ + build/rpcrawtransaction.o \ + build/overviewpage.o \ + build/csvmodelwriter.o \ + build/crypter.o \ + build/sendcoinsentry.o \ + build/qvalidatedlineedit.o \ + build/bitcoinunits.o \ + build/qvaluecombobox.o \ + build/askpassphrasedialog.o \ + build/protocol.o \ + build/notificator.o \ + build/qtipcserver.o \ + build/rpcconsole.o \ + build/scrypt.o \ + build/noui.o \ + build/moc_bitcoingui.o \ + build/moc_transactiontablemodel.o \ + build/moc_addresstablemodel.o \ + build/moc_optionsdialog.o \ + build/moc_sendcoinsdialog.o \ + build/moc_addressbookpage.o \ + build/moc_signverifymessagedialog.o \ + build/moc_aboutdialog.o \ + build/moc_editaddressdialog.o \ + build/moc_bitcoinaddressvalidator.o \ + build/moc_clientmodel.o \ + build/moc_guiutil.o \ + build/moc_optionsmodel.o \ + build/moc_monitoreddatamapper.o \ + build/moc_transactiondesc.o \ + build/moc_transactiondescdialog.o \ + build/moc_bitcoinamountfield.o \ + build/moc_transactionfilterproxy.o \ + build/moc_transactionview.o \ + build/moc_walletmodel.o \ + build/moc_overviewpage.o \ + build/moc_csvmodelwriter.o \ + build/moc_sendcoinsentry.o \ + build/moc_qvalidatedlineedit.o \ + build/moc_qvaluecombobox.o \ + build/moc_askpassphrasedialog.o \ + build/moc_notificator.o \ + build/moc_rpcconsole.o \ + build/qrc_bitcoin.o +DIST = +QMAKE_TARGET = casinocoin-qt +DESTDIR = release\ #avoid trailing-slash linebreak +TARGET = casinocoin-qt.exe +DESTDIR_TARGET = release\casinocoin-qt.exe + +####### Implicit rules + +.SUFFIXES: .cpp .cc .cxx .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +first: all +all: Makefile.Release $(DESTDIR_TARGET) + +$(DESTDIR_TARGET): build/ui_sendcoinsdialog.h build/ui_addressbookpage.h build/ui_signverifymessagedialog.h build/ui_aboutdialog.h build/ui_editaddressdialog.h build/ui_transactiondescdialog.h build/ui_overviewpage.h build/ui_sendcoinsentry.h build/ui_askpassphrasedialog.h build/ui_rpcconsole.h build/ui_optionsdialog.h $(OBJECTS) build/bitcoin-qt_res.o + $(LINK) $(LFLAGS) -o $(DESTDIR_TARGET) object_script.casinocoin-qt.Release $(LIBS) + +build/bitcoin-qt_res.o: src\qt\res\bitcoin-qt.rc + windres -i src\qt\res\bitcoin-qt.rc -o build\bitcoin-qt_res.o --include-dir=./src/qt/res $(DEFINES) + +qmake: FORCE + @$(QMAKE) USE_UPNP=- -o Makefile.Release casinocoin-qt.pro + +dist: + $(ZIP) casinocoin-qt.zip $(SOURCES) $(DIST) casinocoin-qt.pro c:\QtSDK\4.8.4\mkspecs\features\device_config.prf c:\QtSDK\4.8.4\mkspecs\qconfig.pri c:\QtSDK\4.8.4\mkspecs\modules\qt_webkit_version.pri c:\QtSDK\4.8.4\mkspecs\features\qt_functions.prf c:\QtSDK\4.8.4\mkspecs\features\qt_config.prf c:\QtSDK\4.8.4\mkspecs\features\exclusive_builds.prf c:\QtSDK\4.8.4\mkspecs\features\default_pre.prf c:\QtSDK\4.8.4\mkspecs\features\win32\default_pre.prf c:\QtSDK\4.8.4\mkspecs\features\release.prf c:\QtSDK\4.8.4\mkspecs\features\debug_and_release.prf c:\QtSDK\4.8.4\mkspecs\features\default_post.prf c:\QtSDK\4.8.4\mkspecs\features\win32\default_post.prf c:\QtSDK\4.8.4\mkspecs\features\build_pass.prf c:\QtSDK\4.8.4\mkspecs\features\win32\rtti.prf c:\QtSDK\4.8.4\mkspecs\features\win32\exceptions.prf c:\QtSDK\4.8.4\mkspecs\features\win32\stl.prf c:\QtSDK\4.8.4\mkspecs\features\shared.prf c:\QtSDK\4.8.4\mkspecs\features\warn_on.prf c:\QtSDK\4.8.4\mkspecs\features\qt.prf c:\QtSDK\4.8.4\mkspecs\features\win32\thread.prf c:\QtSDK\4.8.4\mkspecs\features\moc.prf c:\QtSDK\4.8.4\mkspecs\features\win32\windows.prf c:\QtSDK\4.8.4\mkspecs\features\resources.prf c:\QtSDK\4.8.4\mkspecs\features\uic.prf c:\QtSDK\4.8.4\mkspecs\features\yacc.prf c:\QtSDK\4.8.4\mkspecs\features\lex.prf c:\QtSDK\4.8.4\lib\qtmain.prl src\qt\locale\bitcoin_bg.ts src\qt\locale\bitcoin_ca_ES.ts src\qt\locale\bitcoin_cs.ts src\qt\locale\bitcoin_da.ts src\qt\locale\bitcoin_de.ts src\qt\locale\bitcoin_el_GR.ts src\qt\locale\bitcoin_en.ts src\qt\locale\bitcoin_es.ts src\qt\locale\bitcoin_es_CL.ts src\qt\locale\bitcoin_et.ts src\qt\locale\bitcoin_eu_ES.ts src\qt\locale\bitcoin_fa.ts src\qt\locale\bitcoin_fa_IR.ts src\qt\locale\bitcoin_fi.ts src\qt\locale\bitcoin_fr.ts src\qt\locale\bitcoin_fr_CA.ts src\qt\locale\bitcoin_he.ts src\qt\locale\bitcoin_hr.ts src\qt\locale\bitcoin_hu.ts src\qt\locale\bitcoin_it.ts src\qt\locale\bitcoin_lt.ts src\qt\locale\bitcoin_nb.ts src\qt\locale\bitcoin_nl.ts src\qt\locale\bitcoin_pl.ts src\qt\locale\bitcoin_pt_BR.ts src\qt\locale\bitcoin_pt_PT.ts src\qt\locale\bitcoin_ro_RO.ts src\qt\locale\bitcoin_ru.ts src\qt\locale\bitcoin_sk.ts src\qt\locale\bitcoin_sr.ts src\qt\locale\bitcoin_sv.ts src\qt\locale\bitcoin_tr.ts src\qt\locale\bitcoin_uk.ts src\qt\locale\bitcoin_zh_CN.ts src\qt\locale\bitcoin_zh_TW.ts src\qt\locale\bitcoin_bg.ts src\qt\locale\bitcoin_ca_ES.ts src\qt\locale\bitcoin_cs.ts src\qt\locale\bitcoin_da.ts src\qt\locale\bitcoin_de.ts src\qt\locale\bitcoin_el_GR.ts src\qt\locale\bitcoin_en.ts src\qt\locale\bitcoin_es.ts src\qt\locale\bitcoin_es_CL.ts src\qt\locale\bitcoin_et.ts src\qt\locale\bitcoin_eu_ES.ts src\qt\locale\bitcoin_fa.ts src\qt\locale\bitcoin_fa_IR.ts src\qt\locale\bitcoin_fi.ts src\qt\locale\bitcoin_fr.ts src\qt\locale\bitcoin_fr_CA.ts src\qt\locale\bitcoin_he.ts src\qt\locale\bitcoin_hr.ts src\qt\locale\bitcoin_hu.ts src\qt\locale\bitcoin_it.ts src\qt\locale\bitcoin_lt.ts src\qt\locale\bitcoin_nb.ts src\qt\locale\bitcoin_nl.ts src\qt\locale\bitcoin_pl.ts src\qt\locale\bitcoin_pt_BR.ts src\qt\locale\bitcoin_pt_PT.ts src\qt\locale\bitcoin_ro_RO.ts src\qt\locale\bitcoin_ru.ts src\qt\locale\bitcoin_sk.ts src\qt\locale\bitcoin_sr.ts src\qt\locale\bitcoin_sv.ts src\qt\locale\bitcoin_tr.ts src\qt\locale\bitcoin_uk.ts src\qt\locale\bitcoin_zh_CN.ts src\qt\locale\bitcoin_zh_TW.ts TRANSLATIONS HEADERS RESOURCES IMAGES SOURCES OBJECTIVE_SOURCES FORMS YACCSOURCES YACCSOURCES LEXSOURCES + +clean: compiler_clean + -$(DEL_FILE) build\bitcoin.o build\bitcoingui.o build\transactiontablemodel.o build\addresstablemodel.o build\optionsdialog.o build\sendcoinsdialog.o build\addressbookpage.o build\signverifymessagedialog.o build\aboutdialog.o build\editaddressdialog.o build\bitcoinaddressvalidator.o build\version.o build\sync.o build\util.o build\netbase.o build\key.o build\script.o build\main.o build\init.o build\net.o build\irc.o build\checkpoints.o build\addrman.o build\db.o build\walletdb.o build\json_spirit_writer.o build\json_spirit_value.o build\json_spirit_reader.o build\clientmodel.o build\guiutil.o build\transactionrecord.o build\optionsmodel.o build\monitoreddatamapper.o build\transactiondesc.o build\transactiondescdialog.o build\bitcoinstrings.o build\bitcoinamountfield.o build\wallet.o build\keystore.o build\transactionfilterproxy.o build\transactionview.o build\walletmodel.o build\bitcoinrpc.o build\rpcdump.o build\rpcnet.o build\rpcrawtransaction.o build\overviewpage.o build\csvmodelwriter.o build\crypter.o build\sendcoinsentry.o build\qvalidatedlineedit.o build\bitcoinunits.o build\qvaluecombobox.o build\askpassphrasedialog.o build\protocol.o build\notificator.o build\qtipcserver.o build\rpcconsole.o build\scrypt.o build\noui.o build\moc_bitcoingui.o build\moc_transactiontablemodel.o build\moc_addresstablemodel.o build\moc_optionsdialog.o build\moc_sendcoinsdialog.o build\moc_addressbookpage.o build\moc_signverifymessagedialog.o build\moc_aboutdialog.o build\moc_editaddressdialog.o build\moc_bitcoinaddressvalidator.o build\moc_clientmodel.o build\moc_guiutil.o build\moc_optionsmodel.o build\moc_monitoreddatamapper.o build\moc_transactiondesc.o build\moc_transactiondescdialog.o build\moc_bitcoinamountfield.o build\moc_transactionfilterproxy.o build\moc_transactionview.o build\moc_walletmodel.o build\moc_overviewpage.o build\moc_csvmodelwriter.o build\moc_sendcoinsentry.o build\moc_qvalidatedlineedit.o build\moc_qvaluecombobox.o build\moc_askpassphrasedialog.o build\moc_notificator.o build\moc_rpcconsole.o + -$(DEL_FILE) build\qrc_bitcoin.o + -$(DEL_FILE) build\bitcoin-qt_res.o + +distclean: clean + -$(DEL_FILE) $(DESTDIR_TARGET) + -$(DEL_FILE) Makefile.Release + +check: first + +mocclean: compiler_moc_header_clean compiler_moc_source_clean + +mocables: compiler_moc_header_make_all compiler_moc_source_make_all + +compiler_TSQM_make_all: src/qt/locale/bitcoin_bg.qm src/qt/locale/bitcoin_ca_ES.qm src/qt/locale/bitcoin_cs.qm src/qt/locale/bitcoin_da.qm src/qt/locale/bitcoin_de.qm src/qt/locale/bitcoin_el_GR.qm src/qt/locale/bitcoin_en.qm src/qt/locale/bitcoin_es.qm src/qt/locale/bitcoin_es_CL.qm src/qt/locale/bitcoin_et.qm src/qt/locale/bitcoin_eu_ES.qm src/qt/locale/bitcoin_fa.qm src/qt/locale/bitcoin_fa_IR.qm src/qt/locale/bitcoin_fi.qm src/qt/locale/bitcoin_fr.qm src/qt/locale/bitcoin_fr_CA.qm src/qt/locale/bitcoin_he.qm src/qt/locale/bitcoin_hr.qm src/qt/locale/bitcoin_hu.qm src/qt/locale/bitcoin_it.qm src/qt/locale/bitcoin_lt.qm src/qt/locale/bitcoin_nb.qm src/qt/locale/bitcoin_nl.qm src/qt/locale/bitcoin_pl.qm src/qt/locale/bitcoin_pt_BR.qm src/qt/locale/bitcoin_pt_PT.qm src/qt/locale/bitcoin_ro_RO.qm src/qt/locale/bitcoin_ru.qm src/qt/locale/bitcoin_sk.qm src/qt/locale/bitcoin_sr.qm src/qt/locale/bitcoin_sv.qm src/qt/locale/bitcoin_tr.qm src/qt/locale/bitcoin_uk.qm src/qt/locale/bitcoin_zh_CN.qm src/qt/locale/bitcoin_zh_TW.qm +compiler_TSQM_clean: + -$(DEL_FILE) src\qt\locale\bitcoin_bg.qm src\qt\locale\bitcoin_ca_ES.qm src\qt\locale\bitcoin_cs.qm src\qt\locale\bitcoin_da.qm src\qt\locale\bitcoin_de.qm src\qt\locale\bitcoin_el_GR.qm src\qt\locale\bitcoin_en.qm src\qt\locale\bitcoin_es.qm src\qt\locale\bitcoin_es_CL.qm src\qt\locale\bitcoin_et.qm src\qt\locale\bitcoin_eu_ES.qm src\qt\locale\bitcoin_fa.qm src\qt\locale\bitcoin_fa_IR.qm src\qt\locale\bitcoin_fi.qm src\qt\locale\bitcoin_fr.qm src\qt\locale\bitcoin_fr_CA.qm src\qt\locale\bitcoin_he.qm src\qt\locale\bitcoin_hr.qm src\qt\locale\bitcoin_hu.qm src\qt\locale\bitcoin_it.qm src\qt\locale\bitcoin_lt.qm src\qt\locale\bitcoin_nb.qm src\qt\locale\bitcoin_nl.qm src\qt\locale\bitcoin_pl.qm src\qt\locale\bitcoin_pt_BR.qm src\qt\locale\bitcoin_pt_PT.qm src\qt\locale\bitcoin_ro_RO.qm src\qt\locale\bitcoin_ru.qm src\qt\locale\bitcoin_sk.qm src\qt\locale\bitcoin_sr.qm src\qt\locale\bitcoin_sv.qm src\qt\locale\bitcoin_tr.qm src\qt\locale\bitcoin_uk.qm src\qt\locale\bitcoin_zh_CN.qm src\qt\locale\bitcoin_zh_TW.qm +src/qt/locale/bitcoin_bg.qm: src/qt/locale/bitcoin_bg.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_bg.ts -qm src\qt\locale\bitcoin_bg.qm + +src/qt/locale/bitcoin_ca_ES.qm: src/qt/locale/bitcoin_ca_ES.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_ca_ES.ts -qm src\qt\locale\bitcoin_ca_ES.qm + +src/qt/locale/bitcoin_cs.qm: src/qt/locale/bitcoin_cs.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_cs.ts -qm src\qt\locale\bitcoin_cs.qm + +src/qt/locale/bitcoin_da.qm: src/qt/locale/bitcoin_da.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_da.ts -qm src\qt\locale\bitcoin_da.qm + +src/qt/locale/bitcoin_de.qm: src/qt/locale/bitcoin_de.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_de.ts -qm src\qt\locale\bitcoin_de.qm + +src/qt/locale/bitcoin_el_GR.qm: src/qt/locale/bitcoin_el_GR.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_el_GR.ts -qm src\qt\locale\bitcoin_el_GR.qm + +src/qt/locale/bitcoin_en.qm: src/qt/locale/bitcoin_en.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_en.ts -qm src\qt\locale\bitcoin_en.qm + +src/qt/locale/bitcoin_es.qm: src/qt/locale/bitcoin_es.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_es.ts -qm src\qt\locale\bitcoin_es.qm + +src/qt/locale/bitcoin_es_CL.qm: src/qt/locale/bitcoin_es_CL.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_es_CL.ts -qm src\qt\locale\bitcoin_es_CL.qm + +src/qt/locale/bitcoin_et.qm: src/qt/locale/bitcoin_et.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_et.ts -qm src\qt\locale\bitcoin_et.qm + +src/qt/locale/bitcoin_eu_ES.qm: src/qt/locale/bitcoin_eu_ES.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_eu_ES.ts -qm src\qt\locale\bitcoin_eu_ES.qm + +src/qt/locale/bitcoin_fa.qm: src/qt/locale/bitcoin_fa.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fa.ts -qm src\qt\locale\bitcoin_fa.qm + +src/qt/locale/bitcoin_fa_IR.qm: src/qt/locale/bitcoin_fa_IR.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fa_IR.ts -qm src\qt\locale\bitcoin_fa_IR.qm + +src/qt/locale/bitcoin_fi.qm: src/qt/locale/bitcoin_fi.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fi.ts -qm src\qt\locale\bitcoin_fi.qm + +src/qt/locale/bitcoin_fr.qm: src/qt/locale/bitcoin_fr.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fr.ts -qm src\qt\locale\bitcoin_fr.qm + +src/qt/locale/bitcoin_fr_CA.qm: src/qt/locale/bitcoin_fr_CA.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_fr_CA.ts -qm src\qt\locale\bitcoin_fr_CA.qm + +src/qt/locale/bitcoin_he.qm: src/qt/locale/bitcoin_he.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_he.ts -qm src\qt\locale\bitcoin_he.qm + +src/qt/locale/bitcoin_hr.qm: src/qt/locale/bitcoin_hr.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_hr.ts -qm src\qt\locale\bitcoin_hr.qm + +src/qt/locale/bitcoin_hu.qm: src/qt/locale/bitcoin_hu.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_hu.ts -qm src\qt\locale\bitcoin_hu.qm + +src/qt/locale/bitcoin_it.qm: src/qt/locale/bitcoin_it.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_it.ts -qm src\qt\locale\bitcoin_it.qm + +src/qt/locale/bitcoin_lt.qm: src/qt/locale/bitcoin_lt.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_lt.ts -qm src\qt\locale\bitcoin_lt.qm + +src/qt/locale/bitcoin_nb.qm: src/qt/locale/bitcoin_nb.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_nb.ts -qm src\qt\locale\bitcoin_nb.qm + +src/qt/locale/bitcoin_nl.qm: src/qt/locale/bitcoin_nl.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_nl.ts -qm src\qt\locale\bitcoin_nl.qm + +src/qt/locale/bitcoin_pl.qm: src/qt/locale/bitcoin_pl.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_pl.ts -qm src\qt\locale\bitcoin_pl.qm + +src/qt/locale/bitcoin_pt_BR.qm: src/qt/locale/bitcoin_pt_BR.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_pt_BR.ts -qm src\qt\locale\bitcoin_pt_BR.qm + +src/qt/locale/bitcoin_pt_PT.qm: src/qt/locale/bitcoin_pt_PT.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_pt_PT.ts -qm src\qt\locale\bitcoin_pt_PT.qm + +src/qt/locale/bitcoin_ro_RO.qm: src/qt/locale/bitcoin_ro_RO.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_ro_RO.ts -qm src\qt\locale\bitcoin_ro_RO.qm + +src/qt/locale/bitcoin_ru.qm: src/qt/locale/bitcoin_ru.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_ru.ts -qm src\qt\locale\bitcoin_ru.qm + +src/qt/locale/bitcoin_sk.qm: src/qt/locale/bitcoin_sk.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_sk.ts -qm src\qt\locale\bitcoin_sk.qm + +src/qt/locale/bitcoin_sr.qm: src/qt/locale/bitcoin_sr.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_sr.ts -qm src\qt\locale\bitcoin_sr.qm + +src/qt/locale/bitcoin_sv.qm: src/qt/locale/bitcoin_sv.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_sv.ts -qm src\qt\locale\bitcoin_sv.qm + +src/qt/locale/bitcoin_tr.qm: src/qt/locale/bitcoin_tr.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_tr.ts -qm src\qt\locale\bitcoin_tr.qm + +src/qt/locale/bitcoin_uk.qm: src/qt/locale/bitcoin_uk.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_uk.ts -qm src\qt\locale\bitcoin_uk.qm + +src/qt/locale/bitcoin_zh_CN.qm: src/qt/locale/bitcoin_zh_CN.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_zh_CN.ts -qm src\qt\locale\bitcoin_zh_CN.qm + +src/qt/locale/bitcoin_zh_TW.qm: src/qt/locale/bitcoin_zh_TW.ts + c:\QtSDK\4.8.4\bin\lrelease.exe src\qt\locale\bitcoin_zh_TW.ts -qm src\qt\locale\bitcoin_zh_TW.qm + +compiler_moc_header_make_all: build/moc_bitcoingui.cpp build/moc_transactiontablemodel.cpp build/moc_addresstablemodel.cpp build/moc_optionsdialog.cpp build/moc_sendcoinsdialog.cpp build/moc_addressbookpage.cpp build/moc_signverifymessagedialog.cpp build/moc_aboutdialog.cpp build/moc_editaddressdialog.cpp build/moc_bitcoinaddressvalidator.cpp build/moc_clientmodel.cpp build/moc_guiutil.cpp build/moc_optionsmodel.cpp build/moc_monitoreddatamapper.cpp build/moc_transactiondesc.cpp build/moc_transactiondescdialog.cpp build/moc_bitcoinamountfield.cpp build/moc_transactionfilterproxy.cpp build/moc_transactionview.cpp build/moc_walletmodel.cpp build/moc_overviewpage.cpp build/moc_csvmodelwriter.cpp build/moc_sendcoinsentry.cpp build/moc_qvalidatedlineedit.cpp build/moc_qvaluecombobox.cpp build/moc_askpassphrasedialog.cpp build/moc_notificator.cpp build/moc_rpcconsole.cpp +compiler_moc_header_clean: + -$(DEL_FILE) build\moc_bitcoingui.cpp build\moc_transactiontablemodel.cpp build\moc_addresstablemodel.cpp build\moc_optionsdialog.cpp build\moc_sendcoinsdialog.cpp build\moc_addressbookpage.cpp build\moc_signverifymessagedialog.cpp build\moc_aboutdialog.cpp build\moc_editaddressdialog.cpp build\moc_bitcoinaddressvalidator.cpp build\moc_clientmodel.cpp build\moc_guiutil.cpp build\moc_optionsmodel.cpp build\moc_monitoreddatamapper.cpp build\moc_transactiondesc.cpp build\moc_transactiondescdialog.cpp build\moc_bitcoinamountfield.cpp build\moc_transactionfilterproxy.cpp build\moc_transactionview.cpp build\moc_walletmodel.cpp build\moc_overviewpage.cpp build\moc_csvmodelwriter.cpp build\moc_sendcoinsentry.cpp build\moc_qvalidatedlineedit.cpp build\moc_qvaluecombobox.cpp build\moc_askpassphrasedialog.cpp build\moc_notificator.cpp build\moc_rpcconsole.cpp +build/moc_bitcoingui.cpp: src/qt/bitcoingui.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\bitcoingui.h -o build\moc_bitcoingui.cpp + +build/moc_transactiontablemodel.cpp: src/qt/transactiontablemodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactiontablemodel.h -o build\moc_transactiontablemodel.cpp + +build/moc_addresstablemodel.cpp: src/qt/addresstablemodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\addresstablemodel.h -o build\moc_addresstablemodel.cpp + +build/moc_optionsdialog.cpp: src/qt/optionsdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\optionsdialog.h -o build\moc_optionsdialog.cpp + +build/moc_sendcoinsdialog.cpp: src/qt/sendcoinsdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\sendcoinsdialog.h -o build\moc_sendcoinsdialog.cpp + +build/moc_addressbookpage.cpp: src/qt/addressbookpage.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\addressbookpage.h -o build\moc_addressbookpage.cpp + +build/moc_signverifymessagedialog.cpp: src/qt/signverifymessagedialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\signverifymessagedialog.h -o build\moc_signverifymessagedialog.cpp + +build/moc_aboutdialog.cpp: src/qt/aboutdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\aboutdialog.h -o build\moc_aboutdialog.cpp + +build/moc_editaddressdialog.cpp: src/qt/editaddressdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\editaddressdialog.h -o build\moc_editaddressdialog.cpp + +build/moc_bitcoinaddressvalidator.cpp: src/qt/bitcoinaddressvalidator.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\bitcoinaddressvalidator.h -o build\moc_bitcoinaddressvalidator.cpp + +build/moc_clientmodel.cpp: src/qt/clientmodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\clientmodel.h -o build\moc_clientmodel.cpp + +build/moc_guiutil.cpp: src/qt/guiutil.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\guiutil.h -o build\moc_guiutil.cpp + +build/moc_optionsmodel.cpp: src/qt/optionsmodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\optionsmodel.h -o build\moc_optionsmodel.cpp + +build/moc_monitoreddatamapper.cpp: src/qt/monitoreddatamapper.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\monitoreddatamapper.h -o build\moc_monitoreddatamapper.cpp + +build/moc_transactiondesc.cpp: src/qt/transactiondesc.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactiondesc.h -o build\moc_transactiondesc.cpp + +build/moc_transactiondescdialog.cpp: src/qt/transactiondescdialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactiondescdialog.h -o build\moc_transactiondescdialog.cpp + +build/moc_bitcoinamountfield.cpp: src/qt/bitcoinamountfield.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\bitcoinamountfield.h -o build\moc_bitcoinamountfield.cpp + +build/moc_transactionfilterproxy.cpp: src/qt/transactionfilterproxy.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactionfilterproxy.h -o build\moc_transactionfilterproxy.cpp + +build/moc_transactionview.cpp: src/qt/transactionview.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\transactionview.h -o build\moc_transactionview.cpp + +build/moc_walletmodel.cpp: src/allocators.h \ + src/qt/walletmodel.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\walletmodel.h -o build\moc_walletmodel.cpp + +build/moc_overviewpage.cpp: src/qt/overviewpage.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\overviewpage.h -o build\moc_overviewpage.cpp + +build/moc_csvmodelwriter.cpp: src/qt/csvmodelwriter.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\csvmodelwriter.h -o build\moc_csvmodelwriter.cpp + +build/moc_sendcoinsentry.cpp: src/qt/sendcoinsentry.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\sendcoinsentry.h -o build\moc_sendcoinsentry.cpp + +build/moc_qvalidatedlineedit.cpp: src/qt/qvalidatedlineedit.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\qvalidatedlineedit.h -o build\moc_qvalidatedlineedit.cpp + +build/moc_qvaluecombobox.cpp: src/qt/qvaluecombobox.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\qvaluecombobox.h -o build\moc_qvaluecombobox.cpp + +build/moc_askpassphrasedialog.cpp: src/qt/askpassphrasedialog.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\askpassphrasedialog.h -o build\moc_askpassphrasedialog.cpp + +build/moc_notificator.cpp: src/qt/notificator.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\notificator.h -o build\moc_notificator.cpp + +build/moc_rpcconsole.cpp: src/qt/rpcconsole.h + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\rpcconsole.h -o build\moc_rpcconsole.cpp + +compiler_rcc_make_all: release/qrc_bitcoin.cpp +compiler_rcc_clean: + -$(DEL_FILE) release\qrc_bitcoin.cpp +release/qrc_bitcoin.cpp: src/qt/bitcoin.qrc \ + src/qt/locale/bitcoin_fa_IR.qm \ + src/qt/locale/bitcoin_hr.qm \ + src/qt/locale/bitcoin_hu.qm \ + src/qt/locale/bitcoin_zh_CN.qm \ + src/qt/locale/bitcoin_bg.qm \ + src/qt/locale/bitcoin_eu_ES.qm \ + src/qt/locale/bitcoin_fr.qm \ + src/qt/locale/bitcoin_nb.qm \ + src/qt/locale/bitcoin_tr.qm \ + src/qt/locale/bitcoin_pl.qm \ + src/qt/locale/bitcoin_ru.qm \ + src/qt/locale/bitcoin_nl.qm \ + src/qt/locale/bitcoin_uk.qm \ + src/qt/locale/bitcoin_it.qm \ + src/qt/locale/bitcoin_ca_ES.qm \ + src/qt/locale/bitcoin_ro_RO.qm \ + src/qt/locale/bitcoin_sk.qm \ + src/qt/locale/bitcoin_en.qm \ + src/qt/locale/bitcoin_el_GR.qm \ + src/qt/locale/bitcoin_es_CL.qm \ + src/qt/locale/bitcoin_he.qm \ + src/qt/locale/bitcoin_fa.qm \ + src/qt/locale/bitcoin_zh_TW.qm \ + src/qt/locale/bitcoin_es.qm \ + src/qt/locale/bitcoin_et.qm \ + src/qt/locale/bitcoin_pt_BR.qm \ + src/qt/locale/bitcoin_sr.qm \ + src/qt/locale/bitcoin_lt.qm \ + src/qt/locale/bitcoin_da.qm \ + src/qt/locale/bitcoin_cs.qm \ + src/qt/locale/bitcoin_pt_PT.qm \ + src/qt/locale/bitcoin_sv.qm \ + src/qt/locale/bitcoin_fi.qm \ + src/qt/locale/bitcoin_fr_CA.qm \ + src/qt/locale/bitcoin_de.qm \ + src/qt/res/images/about.png \ + src/qt/res/images/splash2.jpg \ + src/qt/res/images/wallet.png \ + src/qt/res/movies/update_spinner.mng \ + src/qt/res/icons/add.png \ + src/qt/res/icons/connect0_16.png \ + src/qt/res/icons/connect1_16.png \ + src/qt/res/icons/quit.png \ + src/qt/res/icons/connect2_16.png \ + src/qt/res/icons/overview.png \ + src/qt/res/icons/tx_mined.png \ + src/qt/res/icons/connect3_16.png \ + src/qt/res/icons/connect4_16.png \ + src/qt/res/icons/address-book.png \ + src/qt/res/icons/send.png \ + src/qt/res/icons/configure.png \ + src/qt/res/icons/export.png \ + src/qt/res/icons/synced.png \ + src/qt/res/icons/history.png \ + src/qt/res/icons/filesave.png \ + src/qt/res/icons/transaction2.png \ + src/qt/res/icons/editpaste.png \ + src/qt/res/icons/edit.png \ + src/qt/res/icons/lock_closed.png \ + src/qt/res/icons/editcopy.png \ + src/qt/res/icons/receive.png \ + src/qt/res/icons/transaction0.png \ + src/qt/res/icons/clock1.png \ + src/qt/res/icons/clock2.png \ + src/qt/res/icons/clock3.png \ + src/qt/res/icons/clock4.png \ + src/qt/res/icons/clock5.png \ + src/qt/res/icons/qrcode.png \ + src/qt/res/icons/toolbar_testnet.png \ + src/qt/res/icons/bitcoin.png \ + src/qt/res/icons/key.png \ + src/qt/res/icons/tx_inout.png \ + src/qt/res/icons/remove.png \ + src/qt/res/icons/toolbar.png \ + src/qt/res/icons/lock_open.png \ + src/qt/res/icons/bitcoin_testnet.png \ + src/qt/res/icons/tx_input.png \ + src/qt/res/icons/debugwindow.png \ + src/qt/res/icons/tx_output.png + c:\QtSDK\4.8.4\bin\rcc.exe -name bitcoin src\qt\bitcoin.qrc -o release\qrc_bitcoin.cpp + +compiler_image_collection_make_all: build/qmake_image_collection.cpp +compiler_image_collection_clean: + -$(DEL_FILE) build\qmake_image_collection.cpp +compiler_moc_source_make_all: build/overviewpage.moc build/rpcconsole.moc +compiler_moc_source_clean: + -$(DEL_FILE) build\overviewpage.moc build\rpcconsole.moc +build/overviewpage.moc: src/qt/overviewpage.h \ + build/ui_overviewpage.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/bitcoinunits.h \ + src/qt/optionsmodel.h \ + src/qt/transactiontablemodel.h \ + src/qt/transactionfilterproxy.h \ + src/qt/guiutil.h \ + src/qt/guiconstants.h \ + src/qt/overviewpage.cpp + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\overviewpage.cpp -o build\overviewpage.moc + +build/rpcconsole.moc: src/qt/rpcconsole.h \ + build/ui_rpcconsole.h \ + src/qt/clientmodel.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/qt/guiutil.h \ + src/qt/rpcconsole.cpp + C:\QtSDK\4.8.4\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 src\qt\rpcconsole.cpp -o build\rpcconsole.moc + +compiler_uic_make_all: build/ui_sendcoinsdialog.h build/ui_addressbookpage.h build/ui_signverifymessagedialog.h build/ui_aboutdialog.h build/ui_editaddressdialog.h build/ui_transactiondescdialog.h build/ui_overviewpage.h build/ui_sendcoinsentry.h build/ui_askpassphrasedialog.h build/ui_rpcconsole.h build/ui_optionsdialog.h +compiler_uic_clean: + -$(DEL_FILE) build\ui_sendcoinsdialog.h build\ui_addressbookpage.h build\ui_signverifymessagedialog.h build\ui_aboutdialog.h build\ui_editaddressdialog.h build\ui_transactiondescdialog.h build\ui_overviewpage.h build\ui_sendcoinsentry.h build\ui_askpassphrasedialog.h build\ui_rpcconsole.h build\ui_optionsdialog.h +build/ui_sendcoinsdialog.h: src/qt/forms/sendcoinsdialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\sendcoinsdialog.ui -o build\ui_sendcoinsdialog.h + +build/ui_addressbookpage.h: src/qt/forms/addressbookpage.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\addressbookpage.ui -o build\ui_addressbookpage.h + +build/ui_signverifymessagedialog.h: src/qt/forms/signverifymessagedialog.ui \ + src/qt/qvalidatedlineedit.h + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\signverifymessagedialog.ui -o build\ui_signverifymessagedialog.h + +build/ui_aboutdialog.h: src/qt/forms/aboutdialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\aboutdialog.ui -o build\ui_aboutdialog.h + +build/ui_editaddressdialog.h: src/qt/forms/editaddressdialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\editaddressdialog.ui -o build\ui_editaddressdialog.h + +build/ui_transactiondescdialog.h: src/qt/forms/transactiondescdialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\transactiondescdialog.ui -o build\ui_transactiondescdialog.h + +build/ui_overviewpage.h: src/qt/forms/overviewpage.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\overviewpage.ui -o build\ui_overviewpage.h + +build/ui_sendcoinsentry.h: src/qt/forms/sendcoinsentry.ui \ + src/qt/bitcoinamountfield.h \ + src/qt/qvalidatedlineedit.h + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\sendcoinsentry.ui -o build\ui_sendcoinsentry.h + +build/ui_askpassphrasedialog.h: src/qt/forms/askpassphrasedialog.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\askpassphrasedialog.ui -o build\ui_askpassphrasedialog.h + +build/ui_rpcconsole.h: src/qt/forms/rpcconsole.ui + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\rpcconsole.ui -o build\ui_rpcconsole.h + +build/ui_optionsdialog.h: src/qt/forms/optionsdialog.ui \ + src/qt/bitcoinamountfield.h \ + src/qt/qvaluecombobox.h \ + src/qt/qvalidatedlineedit.h + c:\QtSDK\4.8.4\bin\uic.exe src\qt\forms\optionsdialog.ui -o build\ui_optionsdialog.h + +compiler_yacc_decl_make_all: +compiler_yacc_decl_clean: +compiler_yacc_impl_make_all: +compiler_yacc_impl_clean: +compiler_lex_make_all: +compiler_lex_clean: +compiler_clean: compiler_TSQM_clean compiler_moc_header_clean compiler_rcc_clean compiler_moc_source_clean compiler_uic_clean + + + +####### Compile + +build/bitcoin.o: src/qt/bitcoin.cpp src/qt/bitcoingui.h \ + src/qt/clientmodel.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/optionsmodel.h \ + src/qt/guiutil.h \ + src/qt/guiconstants.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/qt/qtipcserver.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoin.o src\qt\bitcoin.cpp + +build/bitcoingui.o: src/qt/bitcoingui.cpp src/qt/bitcoingui.h \ + src/qt/transactiontablemodel.h \ + src/qt/addressbookpage.h \ + src/qt/sendcoinsdialog.h \ + src/qt/signverifymessagedialog.h \ + src/qt/optionsdialog.h \ + src/qt/aboutdialog.h \ + src/qt/clientmodel.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/editaddressdialog.h \ + src/qt/optionsmodel.h \ + src/qt/transactiondescdialog.h \ + src/qt/addresstablemodel.h \ + src/qt/transactionview.h \ + src/qt/overviewpage.h \ + src/qt/bitcoinunits.h \ + src/qt/guiconstants.h \ + src/qt/askpassphrasedialog.h \ + src/qt/notificator.h \ + src/qt/guiutil.h \ + src/qt/rpcconsole.h \ + src/qt/macdockiconhandler.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoingui.o src\qt\bitcoingui.cpp + +build/transactiontablemodel.o: src/qt/transactiontablemodel.cpp src/qt/transactiontablemodel.h \ + src/qt/guiutil.h \ + src/qt/transactionrecord.h \ + src/uint256.h \ + src/qt/guiconstants.h \ + src/qt/transactiondesc.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/optionsmodel.h \ + src/qt/addresstablemodel.h \ + src/qt/bitcoinunits.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactiontablemodel.o src\qt\transactiontablemodel.cpp + +build/addresstablemodel.o: src/qt/addresstablemodel.cpp src/qt/addresstablemodel.h \ + src/qt/guiutil.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\addresstablemodel.o src\qt\addresstablemodel.cpp + +build/optionsdialog.o: src/qt/optionsdialog.cpp src/qt/optionsdialog.h \ + build/ui_optionsdialog.h \ + src/qt/bitcoinamountfield.h \ + src/qt/bitcoinunits.h \ + src/qt/monitoreddatamapper.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/qt/optionsmodel.h \ + src/qt/qvalidatedlineedit.h \ + src/qt/qvaluecombobox.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\optionsdialog.o src\qt\optionsdialog.cpp + +build/sendcoinsdialog.o: src/qt/sendcoinsdialog.cpp src/qt/sendcoinsdialog.h \ + build/ui_sendcoinsdialog.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/bitcoinunits.h \ + src/qt/addressbookpage.h \ + src/qt/optionsmodel.h \ + src/qt/sendcoinsentry.h \ + src/qt/guiutil.h \ + src/qt/askpassphrasedialog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\sendcoinsdialog.o src\qt\sendcoinsdialog.cpp + +build/addressbookpage.o: src/qt/addressbookpage.cpp src/qt/addressbookpage.h \ + build/ui_addressbookpage.h \ + src/qt/addresstablemodel.h \ + src/qt/optionsmodel.h \ + src/qt/bitcoingui.h \ + src/qt/editaddressdialog.h \ + src/qt/csvmodelwriter.h \ + src/qt/guiutil.h \ + src/qt/qrcodedialog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\addressbookpage.o src\qt\addressbookpage.cpp + +build/signverifymessagedialog.o: src/qt/signverifymessagedialog.cpp src/qt/signverifymessagedialog.h \ + build/ui_signverifymessagedialog.h \ + src/qt/addressbookpage.h \ + src/base58.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/sync.h \ + src/qt/guiutil.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/qt/optionsmodel.h \ + src/qt/walletmodel.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\signverifymessagedialog.o src\qt\signverifymessagedialog.cpp + +build/aboutdialog.o: src/qt/aboutdialog.cpp src/qt/aboutdialog.h \ + build/ui_aboutdialog.h \ + src/qt/clientmodel.h \ + src/version.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\aboutdialog.o src\qt\aboutdialog.cpp + +build/editaddressdialog.o: src/qt/editaddressdialog.cpp src/qt/editaddressdialog.h \ + build/ui_editaddressdialog.h \ + src/qt/addresstablemodel.h \ + src/qt/guiutil.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\editaddressdialog.o src\qt\editaddressdialog.cpp + +build/bitcoinaddressvalidator.o: src/qt/bitcoinaddressvalidator.cpp src/qt/bitcoinaddressvalidator.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinaddressvalidator.o src\qt\bitcoinaddressvalidator.cpp + +build/version.o: src/version.cpp src/version.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\version.o src\version.cpp + +build/sync.o: src/sync.cpp src/sync.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\sync.o src\sync.cpp + +build/util.o: src/util.cpp src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/sync.h \ + src/strlcpy.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\util.o src\util.cpp + +build/netbase.o: src/netbase.cpp src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/util.h \ + src/uint256.h \ + src/strlcpy.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\netbase.o src\netbase.cpp + +build/key.o: src/key.cpp src/key.h \ + src/allocators.h \ + src/serialize.h \ + src/version.h \ + src/uint256.h \ + src/util.h \ + src/netbase.h \ + src/compat.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\key.o src\key.cpp + +build/script.o: src/script.cpp src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/allocators.h \ + src/key.h \ + src/serialize.h \ + src/version.h \ + src/uint256.h \ + src/util.h \ + src/netbase.h \ + src/compat.h \ + src/sync.h \ + src/bignum.h \ + src/main.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/db.h \ + src/scrypt.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\script.o src\script.cpp + +build/main.o: src/main.cpp src/checkpoints.h \ + src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\main.o src\main.cpp + +build/init.o: src/init.cpp src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/walletdb.h \ + src/base58.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\init.o src\init.cpp + +build/net.o: src/net.cpp src/irc.h \ + src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h \ + src/strlcpy.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\net.o src\net.cpp + +build/irc.o: src/irc.cpp src/irc.h \ + src/net.h \ + src/mruset.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/protocol.h \ + src/uint256.h \ + src/addrman.h \ + src/util.h \ + src/sync.h \ + src/strlcpy.h \ + src/base58.h \ + src/bignum.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\irc.o src\irc.cpp + +build/checkpoints.o: src/checkpoints.cpp src/checkpoints.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\checkpoints.o src\checkpoints.cpp + +build/addrman.o: src/addrman.cpp src/addrman.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/protocol.h \ + src/uint256.h \ + src/util.h \ + src/sync.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\addrman.o src\addrman.cpp + +build/db.o: src/db.cpp src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\db.o src\db.cpp + +build/walletdb.o: src/walletdb.cpp src/walletdb.h \ + src/db.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/scrypt.h \ + src/base58.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\walletdb.o src\walletdb.cpp + +build/json_spirit_writer.o: src/json/json_spirit_writer.cpp src/json/json_spirit_writer.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_writer_template.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\json_spirit_writer.o src\json\json_spirit_writer.cpp + +build/json_spirit_value.o: src/json/json_spirit_value.cpp src/json/json_spirit_value.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\json_spirit_value.o src\json\json_spirit_value.cpp + +build/json_spirit_reader.o: src/json/json_spirit_reader.cpp src/json/json_spirit_reader.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_reader_template.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\json_spirit_reader.o src\json\json_spirit_reader.cpp + +build/clientmodel.o: src/qt/clientmodel.cpp src/qt/clientmodel.h \ + src/qt/guiconstants.h \ + src/qt/optionsmodel.h \ + src/qt/addresstablemodel.h \ + src/qt/transactiontablemodel.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\clientmodel.o src\qt\clientmodel.cpp + +build/guiutil.o: src/qt/guiutil.cpp src/qt/guiutil.h \ + src/qt/bitcoinaddressvalidator.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/bitcoinunits.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\guiutil.o src\qt\guiutil.cpp + +build/transactionrecord.o: src/qt/transactionrecord.cpp src/qt/transactionrecord.h \ + src/uint256.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactionrecord.o src\qt\transactionrecord.cpp + +build/optionsmodel.o: src/qt/optionsmodel.cpp src/qt/optionsmodel.h \ + src/qt/bitcoinunits.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/walletdb.h \ + src/base58.h \ + src/qt/guiutil.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\optionsmodel.o src\qt\optionsmodel.cpp + +build/monitoreddatamapper.o: src/qt/monitoreddatamapper.cpp src/qt/monitoreddatamapper.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\monitoreddatamapper.o src\qt\monitoreddatamapper.cpp + +build/transactiondesc.o: src/qt/transactiondesc.cpp src/qt/transactiondesc.h \ + src/qt/guiutil.h \ + src/qt/bitcoinunits.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/wallet.h \ + src/ui_interface.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactiondesc.o src\qt\transactiondesc.cpp + +build/transactiondescdialog.o: src/qt/transactiondescdialog.cpp src/qt/transactiondescdialog.h \ + build/ui_transactiondescdialog.h \ + src/qt/transactiontablemodel.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactiondescdialog.o src\qt\transactiondescdialog.cpp + +build/bitcoinstrings.o: src/qt/bitcoinstrings.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinstrings.o src\qt\bitcoinstrings.cpp + +build/bitcoinamountfield.o: src/qt/bitcoinamountfield.cpp src/qt/bitcoinamountfield.h \ + src/qt/qvaluecombobox.h \ + src/qt/bitcoinunits.h \ + src/qt/guiconstants.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinamountfield.o src\qt\bitcoinamountfield.cpp + +build/wallet.o: src/wallet.cpp src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/walletdb.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\wallet.o src\wallet.cpp + +build/keystore.o: src/keystore.cpp src/keystore.h \ + src/crypter.h \ + src/allocators.h \ + src/key.h \ + src/serialize.h \ + src/version.h \ + src/uint256.h \ + src/util.h \ + src/netbase.h \ + src/compat.h \ + src/sync.h \ + src/script.h \ + src/bignum.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\keystore.o src\keystore.cpp + +build/transactionfilterproxy.o: src/qt/transactionfilterproxy.cpp src/qt/transactionfilterproxy.h \ + src/qt/transactiontablemodel.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactionfilterproxy.o src\qt\transactionfilterproxy.cpp + +build/transactionview.o: src/qt/transactionview.cpp src/qt/transactionview.h \ + src/qt/transactionfilterproxy.h \ + src/qt/transactionrecord.h \ + src/uint256.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/addresstablemodel.h \ + src/qt/transactiontablemodel.h \ + src/qt/bitcoinunits.h \ + src/qt/csvmodelwriter.h \ + src/qt/transactiondescdialog.h \ + src/qt/editaddressdialog.h \ + src/qt/optionsmodel.h \ + src/qt/guiutil.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\transactionview.o src\qt\transactionview.cpp + +build/walletmodel.o: src/qt/walletmodel.cpp src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/guiconstants.h \ + src/qt/optionsmodel.h \ + src/qt/addresstablemodel.h \ + src/qt/transactiontablemodel.h \ + src/ui_interface.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/version.h \ + src/compat.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/walletdb.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\walletmodel.o src\qt\walletmodel.cpp + +build/bitcoinrpc.o: src/bitcoinrpc.cpp src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/wallet.h \ + src/ui_interface.h \ + src/walletdb.h \ + src/base58.h \ + src/init.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinrpc.o src\bitcoinrpc.cpp + +build/rpcdump.o: src/rpcdump.cpp src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/ui_interface.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/base58.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\rpcdump.o src\rpcdump.cpp + +build/rpcnet.o: src/rpcnet.cpp src/net.h \ + src/mruset.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/protocol.h \ + src/uint256.h \ + src/addrman.h \ + src/util.h \ + src/sync.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\rpcnet.o src\rpcnet.cpp + +build/rpcrawtransaction.o: src/rpcrawtransaction.cpp src/base58.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/sync.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/db.h \ + src/main.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/scrypt.h \ + src/init.h \ + src/wallet.h \ + src/ui_interface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\rpcrawtransaction.o src\rpcrawtransaction.cpp + +build/overviewpage.o: src/qt/overviewpage.cpp src/qt/overviewpage.h \ + build/ui_overviewpage.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/bitcoinunits.h \ + src/qt/optionsmodel.h \ + src/qt/transactiontablemodel.h \ + src/qt/transactionfilterproxy.h \ + src/qt/guiutil.h \ + src/qt/guiconstants.h \ + build/overviewpage.moc + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\overviewpage.o src\qt\overviewpage.cpp + +build/csvmodelwriter.o: src/qt/csvmodelwriter.cpp src/qt/csvmodelwriter.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\csvmodelwriter.o src\qt\csvmodelwriter.cpp + +build/crypter.o: src/crypter.cpp src/crypter.h \ + src/allocators.h \ + src/key.h \ + src/serialize.h \ + src/version.h \ + src/uint256.h \ + src/util.h \ + src/netbase.h \ + src/compat.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\crypter.o src\crypter.cpp + +build/sendcoinsentry.o: src/qt/sendcoinsentry.cpp src/qt/sendcoinsentry.h \ + build/ui_sendcoinsentry.h \ + src/qt/guiutil.h \ + src/qt/bitcoinunits.h \ + src/qt/addressbookpage.h \ + src/qt/walletmodel.h \ + src/allocators.h \ + src/qt/optionsmodel.h \ + src/qt/addresstablemodel.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\sendcoinsentry.o src\qt\sendcoinsentry.cpp + +build/qvalidatedlineedit.o: src/qt/qvalidatedlineedit.cpp src/qt/qvalidatedlineedit.h \ + src/qt/guiconstants.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\qvalidatedlineedit.o src\qt\qvalidatedlineedit.cpp + +build/bitcoinunits.o: src/qt/bitcoinunits.cpp src/qt/bitcoinunits.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\bitcoinunits.o src\qt\bitcoinunits.cpp + +build/qvaluecombobox.o: src/qt/qvaluecombobox.cpp src/qt/qvaluecombobox.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\qvaluecombobox.o src\qt\qvaluecombobox.cpp + +build/askpassphrasedialog.o: src/qt/askpassphrasedialog.cpp src/qt/askpassphrasedialog.h \ + build/ui_askpassphrasedialog.h \ + src/qt/guiconstants.h \ + src/qt/walletmodel.h \ + src/allocators.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\askpassphrasedialog.o src\qt\askpassphrasedialog.cpp + +build/protocol.o: src/protocol.cpp src/protocol.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/netbase.h \ + src/compat.h \ + src/uint256.h \ + src/util.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\protocol.o src\protocol.cpp + +build/notificator.o: src/qt/notificator.cpp src/qt/notificator.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\notificator.o src\qt\notificator.cpp + +build/qtipcserver.o: src/qt/qtipcserver.cpp src/qt/qtipcserver.h \ + src/qt/guiconstants.h \ + src/ui_interface.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\qtipcserver.o src\qt\qtipcserver.cpp + +build/rpcconsole.o: src/qt/rpcconsole.cpp src/qt/rpcconsole.h \ + build/ui_rpcconsole.h \ + src/qt/clientmodel.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h \ + src/qt/guiutil.h \ + build/rpcconsole.moc + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\rpcconsole.o src\qt\rpcconsole.cpp + +build/scrypt.o: src/scrypt.c src/scrypt.h + $(CC) -c $(CFLAGS) $(INCPATH) -o build\scrypt.o src\scrypt.c + +build/noui.o: src/noui.cpp src/ui_interface.h \ + src/util.h \ + src/uint256.h \ + src/netbase.h \ + src/serialize.h \ + src/allocators.h \ + src/version.h \ + src/compat.h \ + src/init.h \ + src/wallet.h \ + src/main.h \ + src/bignum.h \ + src/net.h \ + src/mruset.h \ + src/protocol.h \ + src/addrman.h \ + src/sync.h \ + src/key.h \ + src/script.h \ + src/keystore.h \ + src/crypter.h \ + src/db.h \ + src/scrypt.h \ + src/bitcoinrpc.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_utils.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\noui.o src\noui.cpp + +build/moc_bitcoingui.o: build/moc_bitcoingui.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_bitcoingui.o build\moc_bitcoingui.cpp + +build/moc_transactiontablemodel.o: build/moc_transactiontablemodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactiontablemodel.o build\moc_transactiontablemodel.cpp + +build/moc_addresstablemodel.o: build/moc_addresstablemodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_addresstablemodel.o build\moc_addresstablemodel.cpp + +build/moc_optionsdialog.o: build/moc_optionsdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_optionsdialog.o build\moc_optionsdialog.cpp + +build/moc_sendcoinsdialog.o: build/moc_sendcoinsdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_sendcoinsdialog.o build\moc_sendcoinsdialog.cpp + +build/moc_addressbookpage.o: build/moc_addressbookpage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_addressbookpage.o build\moc_addressbookpage.cpp + +build/moc_signverifymessagedialog.o: build/moc_signverifymessagedialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_signverifymessagedialog.o build\moc_signverifymessagedialog.cpp + +build/moc_aboutdialog.o: build/moc_aboutdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_aboutdialog.o build\moc_aboutdialog.cpp + +build/moc_editaddressdialog.o: build/moc_editaddressdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_editaddressdialog.o build\moc_editaddressdialog.cpp + +build/moc_bitcoinaddressvalidator.o: build/moc_bitcoinaddressvalidator.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_bitcoinaddressvalidator.o build\moc_bitcoinaddressvalidator.cpp + +build/moc_clientmodel.o: build/moc_clientmodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_clientmodel.o build\moc_clientmodel.cpp + +build/moc_guiutil.o: build/moc_guiutil.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_guiutil.o build\moc_guiutil.cpp + +build/moc_optionsmodel.o: build/moc_optionsmodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_optionsmodel.o build\moc_optionsmodel.cpp + +build/moc_monitoreddatamapper.o: build/moc_monitoreddatamapper.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_monitoreddatamapper.o build\moc_monitoreddatamapper.cpp + +build/moc_transactiondesc.o: build/moc_transactiondesc.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactiondesc.o build\moc_transactiondesc.cpp + +build/moc_transactiondescdialog.o: build/moc_transactiondescdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactiondescdialog.o build\moc_transactiondescdialog.cpp + +build/moc_bitcoinamountfield.o: build/moc_bitcoinamountfield.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_bitcoinamountfield.o build\moc_bitcoinamountfield.cpp + +build/moc_transactionfilterproxy.o: build/moc_transactionfilterproxy.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactionfilterproxy.o build\moc_transactionfilterproxy.cpp + +build/moc_transactionview.o: build/moc_transactionview.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_transactionview.o build\moc_transactionview.cpp + +build/moc_walletmodel.o: build/moc_walletmodel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_walletmodel.o build\moc_walletmodel.cpp + +build/moc_overviewpage.o: build/moc_overviewpage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_overviewpage.o build\moc_overviewpage.cpp + +build/moc_csvmodelwriter.o: build/moc_csvmodelwriter.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_csvmodelwriter.o build\moc_csvmodelwriter.cpp + +build/moc_sendcoinsentry.o: build/moc_sendcoinsentry.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_sendcoinsentry.o build\moc_sendcoinsentry.cpp + +build/moc_qvalidatedlineedit.o: build/moc_qvalidatedlineedit.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_qvalidatedlineedit.o build\moc_qvalidatedlineedit.cpp + +build/moc_qvaluecombobox.o: build/moc_qvaluecombobox.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_qvaluecombobox.o build\moc_qvaluecombobox.cpp + +build/moc_askpassphrasedialog.o: build/moc_askpassphrasedialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_askpassphrasedialog.o build\moc_askpassphrasedialog.cpp + +build/moc_notificator.o: build/moc_notificator.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_notificator.o build\moc_notificator.cpp + +build/moc_rpcconsole.o: build/moc_rpcconsole.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\moc_rpcconsole.o build\moc_rpcconsole.cpp + +build/qrc_bitcoin.o: release/qrc_bitcoin.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o build\qrc_bitcoin.o release\qrc_bitcoin.cpp + +####### Install + +install: FORCE + +uninstall: FORCE + +FORCE: + diff --git a/README b/README new file mode 100644 index 0000000..42061c0 --- /dev/null +++ b/README @@ -0,0 +1 @@ +README.md \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e7aa3d2 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ + +

+ +CasinoCoin: An open source, peer-to-peer Internet currency specifically designed for online casino gaming. + +

+ +Since April 15th, 2011, a day dubbed as 'Black Friday' by the online gaming community, it has become increasingly difficult to deposit funds for online casino gaming due to deposit restrictions between centralized financial institutions and online casino platforms. Avid online players have since not been able to enjoy the same conveniences and the ease of accessibility that they were once afforded. Those days are no more with the advent of CasinoCoin. + +As a decentralized crypto currency, CasinoCoin offers the solution to help fill this void. Consider CasinoCoin as a universal casino chip that is easily transferable between online casino gaming applications, exchanges and peers. Imagine using CasinoCoin at your favorite online poker sites, then transferring your winnings over to your favorite online casino to play Blackjack. How about a friendly wager over a game of chess? This is all possible with CasinoCoin. + +CasinoCoin is an open source, peer-to-peer Internet currency specifically designed for online casino gaming. It is a platform independent crypto currency that is easily transferable between gaming applications, exchanges and peers. CasinoCoin can simply be summed up as universal casino chips. + +By itself, CasinoCoin has no value. Within casino gaming applications, it can be used to play games of skill and chance. On the exchanges, CasinoCoin is worth what the market values it at and it can be bought, sold and exchanged to fiat currencies such as US dollars or exchanged to other crypto currencies such as Bitcoin. + +CasinoCoin is based on the strengths of crypto currency protocols such as Bitcoin, Litecoin, Feathercoin and digitalcoin, giving it a second movers advantage. It leverages the security of Bitcoin, the accessibility of Litecoin, the abundance of Feathercoin, and the speed of digitalcoin. While CasinoCoin can be used as a general purpose currency, it serves a specific purpose and is marketed exclusively for online casino gaming and rewards redemption. + + +Mission Statement +================= + +The goal of CasinoCoin is to help make online casino gaming accessible to all by removing barriers. The success and strength of CasinoCoin rely on three main pillars: active and talented developers, fostering community, and trust through transparency. + + +Get active! Join the CasinoCoin community by visiting the links below. + + + +Technical Specifications +======================== + + - scrypt proof-of-work algorithm + - 30 second block time targets + - ~336 million total coins + - 720 blocks to retarget difficulty + - 50 coins per block, halves every 3,153,600 blocks (~3 years) + - fair launch, absolutely no premine + + +Links +====== + +Website: http://casinoco.in + + +Forum: http://forum.casinoco.in + + +Source: https://github.com/transcoder/CasinoCoin + + diff --git a/casinocoin-qt.pro b/casinocoin-qt.pro new file mode 100644 index 0000000..fef44de --- /dev/null +++ b/casinocoin-qt.pro @@ -0,0 +1,366 @@ +TEMPLATE = app +TARGET = +VERSION = 1.0.0.3 +INCLUDEPATH += src src/json src/qt +DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE USE_IPV6 __NO_SYSTEM_INCLUDES +CONFIG += no_include_pwd + +# for boost 1.37, add -mt to the boost libraries +# use: qmake BOOST_LIB_SUFFIX=-mt +# for boost thread win32 with _win32 sufix +# use: BOOST_THREAD_LIB_SUFFIX=_win32-... +# or when linking against a specific BerkelyDB version: BDB_LIB_SUFFIX=-4.8 + +# Dependency library locations can be customized with: +# BOOST_INCLUDE_PATH, BOOST_LIB_PATH, BDB_INCLUDE_PATH, +# BDB_LIB_PATH, OPENSSL_INCLUDE_PATH and OPENSSL_LIB_PATH respectively + +BOOST_INCLUDE_PATH=E:/crypto/deps/boost_1_53_0 +BOOST_LIB_PATH=E:/crypto/deps/boost_1_53_0/stage/lib +BDB_INCLUDE_PATH=E:/crypto/deps/db-4.8.30.NC/build_unix +BDB_LIB_PATH=E:/crypto/deps/db-4.8.30.NC/build_unix +OPENSSL_INCLUDE_PATH=E:/crypto/deps/openssl-1.0.1b/include +OPENSSL_LIB_PATH=E:/crypto/deps/openssl-1.0.1b + +OBJECTS_DIR = build +MOC_DIR = build +UI_DIR = build + +# use: qmake "RELEASE=1" +contains(RELEASE, 1) { + # Mac: compile for maximum compatibility (10.5, 32-bit) + macx:QMAKE_CXXFLAGS += -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk + macx:QMAKE_CFLAGS += -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk + macx:QMAKE_LFLAGS += -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk + + !windows:!macx { + # Linux: static link + LIBS += -Wl,-Bstatic + } +} + +# use: qmake "USE_QRCODE=1" +# libqrencode (http://fukuchi.org/works/qrencode/index.en.html) must be installed for support +contains(USE_QRCODE, 1) { + message(Building with QRCode support) + DEFINES += USE_QRCODE + LIBS += -lqrencode +} + +# use: qmake "USE_UPNP=1" ( enabled by default; default) +# or: qmake "USE_UPNP=0" (disabled by default) +# or: qmake "USE_UPNP=-" (not supported) +# miniupnpc (http://miniupnp.free.fr/files/) must be installed for support +contains(USE_UPNP, -) { + message(Building without UPNP support) +} else { + message(Building with UPNP support) + count(USE_UPNP, 0) { + USE_UPNP=1 + } + DEFINES += USE_UPNP=$$USE_UPNP STATICLIB + INCLUDEPATH += $$MINIUPNPC_INCLUDE_PATH + LIBS += $$join(MINIUPNPC_LIB_PATH,,-L,) -lminiupnpc + win32:LIBS += -liphlpapi +} + +# use: qmake "USE_DBUS=1" +contains(USE_DBUS, 1) { + message(Building with DBUS (Freedesktop notifications) support) + DEFINES += USE_DBUS + QT += dbus +} + +# use: qmake "FIRST_CLASS_MESSAGING=1" +contains(FIRST_CLASS_MESSAGING, 1) { + message(Building with first-class messaging) + DEFINES += FIRST_CLASS_MESSAGING +} + +contains(BITCOIN_NEED_QT_PLUGINS, 1) { + DEFINES += BITCOIN_NEED_QT_PLUGINS + QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs qtaccessiblewidgets +} + +!windows { + # for extra security against potential buffer overflows + QMAKE_CXXFLAGS += -fstack-protector + QMAKE_LFLAGS += -fstack-protector + # do not enable this on windows, as it will result in a non-working executable! +} + +# regenerate src/build.h +!windows|contains(USE_BUILD_INFO, 1) { + genbuild.depends = FORCE + genbuild.commands = cd $$PWD; /bin/sh share/genbuild.sh $$OUT_PWD/build/build.h + genbuild.target = $$OUT_PWD/build/build.h + PRE_TARGETDEPS += $$OUT_PWD/build/build.h + QMAKE_EXTRA_TARGETS += genbuild + DEFINES += HAVE_BUILD_INFO +} + +QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter + +# Input +DEPENDPATH += src src/json src/qt +HEADERS += src/qt/bitcoingui.h \ + src/qt/transactiontablemodel.h \ + src/qt/addresstablemodel.h \ + src/qt/optionsdialog.h \ + src/qt/sendcoinsdialog.h \ + src/qt/addressbookpage.h \ + src/qt/signverifymessagedialog.h \ + src/qt/aboutdialog.h \ + src/qt/editaddressdialog.h \ + src/qt/bitcoinaddressvalidator.h \ + src/addrman.h \ + src/base58.h \ + src/bignum.h \ + src/checkpoints.h \ + src/compat.h \ + src/sync.h \ + src/util.h \ + src/uint256.h \ + src/serialize.h \ + src/strlcpy.h \ + src/main.h \ + src/net.h \ + src/key.h \ + src/db.h \ + src/walletdb.h \ + src/script.h \ + src/init.h \ + src/irc.h \ + src/mruset.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_writer.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_utils.h \ + src/json/json_spirit_stream_reader.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_reader.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit.h \ + src/qt/clientmodel.h \ + src/qt/guiutil.h \ + src/qt/transactionrecord.h \ + src/qt/guiconstants.h \ + src/qt/optionsmodel.h \ + src/qt/monitoreddatamapper.h \ + src/qt/transactiondesc.h \ + src/qt/transactiondescdialog.h \ + src/qt/bitcoinamountfield.h \ + src/wallet.h \ + src/keystore.h \ + src/qt/transactionfilterproxy.h \ + src/qt/transactionview.h \ + src/qt/walletmodel.h \ + src/bitcoinrpc.h \ + src/qt/overviewpage.h \ + src/qt/csvmodelwriter.h \ + src/crypter.h \ + src/qt/sendcoinsentry.h \ + src/qt/qvalidatedlineedit.h \ + src/qt/bitcoinunits.h \ + src/qt/qvaluecombobox.h \ + src/qt/askpassphrasedialog.h \ + src/protocol.h \ + src/qt/notificator.h \ + src/qt/qtipcserver.h \ + src/allocators.h \ + src/ui_interface.h \ + src/scrypt.h \ + src/version.h \ + src/qt/rpcconsole.h + +SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ + src/qt/transactiontablemodel.cpp \ + src/qt/addresstablemodel.cpp \ + src/qt/optionsdialog.cpp \ + src/qt/sendcoinsdialog.cpp \ + src/qt/addressbookpage.cpp \ + src/qt/signverifymessagedialog.cpp \ + src/qt/aboutdialog.cpp \ + src/qt/editaddressdialog.cpp \ + src/qt/bitcoinaddressvalidator.cpp \ + src/version.cpp \ + src/sync.cpp \ + src/util.cpp \ + src/netbase.cpp \ + src/key.cpp \ + src/script.cpp \ + src/main.cpp \ + src/init.cpp \ + src/net.cpp \ + src/irc.cpp \ + src/checkpoints.cpp \ + src/addrman.cpp \ + src/db.cpp \ + src/walletdb.cpp \ + src/json/json_spirit_writer.cpp \ + src/json/json_spirit_value.cpp \ + src/json/json_spirit_reader.cpp \ + src/qt/clientmodel.cpp \ + src/qt/guiutil.cpp \ + src/qt/transactionrecord.cpp \ + src/qt/optionsmodel.cpp \ + src/qt/monitoreddatamapper.cpp \ + src/qt/transactiondesc.cpp \ + src/qt/transactiondescdialog.cpp \ + src/qt/bitcoinstrings.cpp \ + src/qt/bitcoinamountfield.cpp \ + src/wallet.cpp \ + src/keystore.cpp \ + src/qt/transactionfilterproxy.cpp \ + src/qt/transactionview.cpp \ + src/qt/walletmodel.cpp \ + src/bitcoinrpc.cpp \ + src/rpcdump.cpp \ + src/rpcnet.cpp \ + src/rpcrawtransaction.cpp \ + src/qt/overviewpage.cpp \ + src/qt/csvmodelwriter.cpp \ + src/crypter.cpp \ + src/qt/sendcoinsentry.cpp \ + src/qt/qvalidatedlineedit.cpp \ + src/qt/bitcoinunits.cpp \ + src/qt/qvaluecombobox.cpp \ + src/qt/askpassphrasedialog.cpp \ + src/protocol.cpp \ + src/qt/notificator.cpp \ + src/qt/qtipcserver.cpp \ + src/qt/rpcconsole.cpp \ + src/scrypt.c \ + src/noui.cpp + +RESOURCES += \ + src/qt/bitcoin.qrc + +FORMS += \ + src/qt/forms/sendcoinsdialog.ui \ + src/qt/forms/addressbookpage.ui \ + src/qt/forms/signverifymessagedialog.ui \ + src/qt/forms/aboutdialog.ui \ + src/qt/forms/editaddressdialog.ui \ + src/qt/forms/transactiondescdialog.ui \ + src/qt/forms/overviewpage.ui \ + src/qt/forms/sendcoinsentry.ui \ + src/qt/forms/askpassphrasedialog.ui \ + src/qt/forms/rpcconsole.ui \ + src/qt/forms/optionsdialog.ui + +contains(USE_QRCODE, 1) { +HEADERS += src/qt/qrcodedialog.h +SOURCES += src/qt/qrcodedialog.cpp +FORMS += src/qt/forms/qrcodedialog.ui +} + +contains(BITCOIN_QT_TEST, 1) { +SOURCES += src/qt/test/test_main.cpp \ + src/qt/test/uritests.cpp +HEADERS += src/qt/test/uritests.h +DEPENDPATH += src/qt/test +QT += testlib +TARGET = bitcoin-qt_test +DEFINES += BITCOIN_QT_TEST +} + +CODECFORTR = UTF-8 + +# for lrelease/lupdate +# also add new translations to src/qt/bitcoin.qrc under translations/ +TRANSLATIONS = $$files(src/qt/locale/bitcoin_*.ts) + +isEmpty(QMAKE_LRELEASE) { + win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\\lrelease.exe + else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease +} +isEmpty(QM_DIR):QM_DIR = $$PWD/src/qt/locale +# automatically build translations, so they can be included in resource file +TSQM.name = lrelease ${QMAKE_FILE_IN} +TSQM.input = TRANSLATIONS +TSQM.output = $$QM_DIR/${QMAKE_FILE_BASE}.qm +TSQM.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +TSQM.CONFIG = no_link +QMAKE_EXTRA_COMPILERS += TSQM + +# "Other files" to show in Qt Creator +OTHER_FILES += \ + contrib/gitian-descriptors/* doc/*.rst doc/*.txt doc/README README.md res/bitcoin-qt.rc \ + share/setup.nsi + +# platform specific defaults, if not overridden on command line +isEmpty(BOOST_LIB_SUFFIX) { + macx:BOOST_LIB_SUFFIX = -mt + windows:BOOST_LIB_SUFFIX = -mgw46-mt-s-1_53 +} + +isEmpty(BOOST_THREAD_LIB_SUFFIX) { + BOOST_THREAD_LIB_SUFFIX = $$BOOST_LIB_SUFFIX +} + +isEmpty(BDB_LIB_PATH) { + macx:BDB_LIB_PATH = /opt/local/lib/db48 +} + +isEmpty(BDB_LIB_SUFFIX) { + macx:BDB_LIB_SUFFIX = -4.8 +} + +isEmpty(BDB_INCLUDE_PATH) { + macx:BDB_INCLUDE_PATH = /opt/local/include/db48 +} + +isEmpty(BOOST_LIB_PATH) { + macx:BOOST_LIB_PATH = /opt/local/lib +} + +isEmpty(BOOST_INCLUDE_PATH) { + macx:BOOST_INCLUDE_PATH = /opt/local/include +} + +windows:LIBS += -lshlwapi +windows:DEFINES += WIN32 +windows:RC_FILE = src/qt/res/bitcoin-qt.rc + +windows:!contains(MINGW_THREAD_BUGFIX, 0) { + # At least qmake's win32-g++-cross profile is missing the -lmingwthrd + # thread-safety flag. GCC has -mthreads to enable this, but it doesn't + # work with static linking. -lmingwthrd must come BEFORE -lmingw, so + # it is prepended to QMAKE_LIBS_QT_ENTRY. + # It can be turned off with MINGW_THREAD_BUGFIX=0, just in case it causes + # any problems on some untested qmake profile now or in the future. + DEFINES += _MT + QMAKE_LIBS_QT_ENTRY = -lmingwthrd $$QMAKE_LIBS_QT_ENTRY +} + +!windows:!mac { + DEFINES += LINUX + LIBS += -lrt +} + +macx:HEADERS += src/qt/macdockiconhandler.h +macx:OBJECTIVE_SOURCES += src/qt/macdockiconhandler.mm +macx:LIBS += -framework Foundation -framework ApplicationServices -framework AppKit +macx:DEFINES += MAC_OSX MSG_NOSIGNAL=0 +macx:ICON = src/qt/res/icons/bitcoin.icns +macx:TARGET = "CasinoCoin-Qt" + +# Set libraries and includes at end, to use platform-defined defaults if not overridden +INCLUDEPATH += $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH $$QRENCODE_INCLUDE_PATH +LIBS += $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,) $$join(QRENCODE_LIB_PATH,,-L,) +LIBS += -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX +# -lgdi32 has to happen after -lcrypto (see #681) +windows:LIBS += -lws2_32 -lole32 -lmswsock -loleaut32 -luuid -lgdi32 +LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_THREAD_LIB_SUFFIX + +contains(RELEASE, 1) { + !windows:!macx { + # Linux: turn dynamic linking back on for c/c++ runtime libraries + LIBS += -Wl,-Bdynamic + } +} + +system($$QMAKE_LRELEASE -silent $$_PRO_FILE_) + + diff --git a/contrib/bitcoind.bash-completion b/contrib/bitcoind.bash-completion new file mode 100644 index 0000000..dd6c1ce --- /dev/null +++ b/contrib/bitcoind.bash-completion @@ -0,0 +1,115 @@ +# bash programmable completion for bitcoind(1) +# Copyright (c) 2012 Christian von Roques +# 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 diff --git a/contrib/bitrpc/bitrpc.py b/contrib/bitrpc/bitrpc.py new file mode 100644 index 0000000..b02b299 --- /dev/null +++ b/contrib/bitrpc/bitrpc.py @@ -0,0 +1,324 @@ +from jsonrpc import ServiceProxy +import sys +import string + +# ===== BEGIN USER SETTINGS ===== +# if you do not set these you will be prompted for a password for every command +rpcuser = "" +rpcpass = "" +# ====== END USER SETTINGS ====== + + +if rpcpass == "": + access = ServiceProxy("http://127.0.0.1:8332") +else: + access = ServiceProxy("http://"+rpcuser+":"+rpcpass+"@127.0.0.1:8332") +cmd = sys.argv[1].lower() + +if cmd == "backupwallet": + try: + path = raw_input("Enter destination path/filename: ") + print access.backupwallet(path) + except: + print "\n---An error occurred---\n" + +elif cmd == "getaccount": + try: + addr = raw_input("Enter a Bitcoin address: ") + print access.getaccount(addr) + except: + print "\n---An error occurred---\n" + +elif cmd == "getaccountaddress": + try: + acct = raw_input("Enter an account name: ") + print access.getaccountaddress(acct) + except: + print "\n---An error occurred---\n" + +elif cmd == "getaddressesbyaccount": + try: + acct = raw_input("Enter an account name: ") + print access.getaddressesbyaccount(acct) + except: + print "\n---An error occurred---\n" + +elif cmd == "getbalance": + try: + acct = raw_input("Enter an account (optional): ") + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.getbalance(acct, mc) + except: + print access.getbalance() + except: + print "\n---An error occurred---\n" + +elif cmd == "getblockbycount": + try: + height = raw_input("Height: ") + print access.getblockbycount(height) + except: + print "\n---An error occurred---\n" + +elif cmd == "getblockcount": + try: + print access.getblockcount() + except: + print "\n---An error occurred---\n" + +elif cmd == "getblocknumber": + try: + print access.getblocknumber() + except: + print "\n---An error occurred---\n" + +elif cmd == "getconnectioncount": + try: + print access.getconnectioncount() + except: + print "\n---An error occurred---\n" + +elif cmd == "getdifficulty": + try: + print access.getdifficulty() + except: + print "\n---An error occurred---\n" + +elif cmd == "getgenerate": + try: + print access.getgenerate() + except: + print "\n---An error occurred---\n" + +elif cmd == "gethashespersec": + try: + print access.gethashespersec() + except: + print "\n---An error occurred---\n" + +elif cmd == "getinfo": + try: + print access.getinfo() + except: + print "\n---An error occurred---\n" + +elif cmd == "getnewaddress": + try: + acct = raw_input("Enter an account name: ") + try: + print access.getnewaddress(acct) + except: + print access.getnewaddress() + except: + print "\n---An error occurred---\n" + +elif cmd == "getreceivedbyaccount": + try: + acct = raw_input("Enter an account (optional): ") + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.getreceivedbyaccount(acct, mc) + except: + print access.getreceivedbyaccount() + except: + print "\n---An error occurred---\n" + +elif cmd == "getreceivedbyaddress": + try: + addr = raw_input("Enter a Bitcoin address (optional): ") + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.getreceivedbyaddress(addr, mc) + except: + print access.getreceivedbyaddress() + except: + print "\n---An error occurred---\n" + +elif cmd == "gettransaction": + try: + txid = raw_input("Enter a transaction ID: ") + print access.gettransaction(txid) + except: + print "\n---An error occurred---\n" + +elif cmd == "getwork": + try: + data = raw_input("Data (optional): ") + try: + print access.gettransaction(data) + except: + print access.gettransaction() + except: + print "\n---An error occurred---\n" + +elif cmd == "help": + try: + cmd = raw_input("Command (optional): ") + try: + print access.help(cmd) + except: + print access.help() + except: + print "\n---An error occurred---\n" + +elif cmd == "listaccounts": + try: + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.listaccounts(mc) + except: + print access.listaccounts() + except: + print "\n---An error occurred---\n" + +elif cmd == "listreceivedbyaccount": + try: + mc = raw_input("Minimum confirmations (optional): ") + incemp = raw_input("Include empty? (true/false, optional): ") + try: + print access.listreceivedbyaccount(mc, incemp) + except: + print access.listreceivedbyaccount() + except: + print "\n---An error occurred---\n" + +elif cmd == "listreceivedbyaddress": + try: + mc = raw_input("Minimum confirmations (optional): ") + incemp = raw_input("Include empty? (true/false, optional): ") + try: + print access.listreceivedbyaddress(mc, incemp) + except: + print access.listreceivedbyaddress() + except: + print "\n---An error occurred---\n" + +elif cmd == "listtransactions": + try: + acct = raw_input("Account (optional): ") + count = raw_input("Number of transactions (optional): ") + frm = raw_input("Skip (optional):") + try: + print access.listtransactions(acct, count, frm) + except: + print access.listtransactions() + except: + print "\n---An error occurred---\n" + +elif cmd == "move": + try: + frm = raw_input("From: ") + to = raw_input("To: ") + amt = raw_input("Amount:") + mc = raw_input("Minimum confirmations (optional): ") + comment = raw_input("Comment (optional): ") + try: + print access.move(frm, to, amt, mc, comment) + except: + print access.move(frm, to, amt) + except: + print "\n---An error occurred---\n" + +elif cmd == "sendfrom": + try: + frm = raw_input("From: ") + to = raw_input("To: ") + amt = raw_input("Amount:") + mc = raw_input("Minimum confirmations (optional): ") + comment = raw_input("Comment (optional): ") + commentto = raw_input("Comment-to (optional): ") + try: + print access.sendfrom(frm, to, amt, mc, comment, commentto) + except: + print access.sendfrom(frm, to, amt) + except: + print "\n---An error occurred---\n" + +elif cmd == "sendmany": + try: + frm = raw_input("From: ") + to = raw_input("To (in format address1:amount1,address2:amount2,...): ") + mc = raw_input("Minimum confirmations (optional): ") + comment = raw_input("Comment (optional): ") + try: + print access.sendmany(frm,to,mc,comment) + except: + print access.sendmany(frm,to) + except: + print "\n---An error occurred---\n" + +elif cmd == "sendtoaddress": + try: + to = raw_input("To (in format address1:amount1,address2:amount2,...): ") + amt = raw_input("Amount:") + comment = raw_input("Comment (optional): ") + commentto = raw_input("Comment-to (optional): ") + try: + print access.sendtoaddress(to,amt,comment,commentto) + except: + print access.sendtoaddress(to,amt) + except: + print "\n---An error occurred---\n" + +elif cmd == "setaccount": + try: + addr = raw_input("Address: ") + acct = raw_input("Account:") + print access.setaccount(addr,acct) + except: + print "\n---An error occurred---\n" + +elif cmd == "setgenerate": + try: + gen= raw_input("Generate? (true/false): ") + cpus = raw_input("Max processors/cores (-1 for unlimited, optional):") + try: + print access.setgenerate(gen, cpus) + except: + print access.setgenerate(gen) + except: + print "\n---An error occurred---\n" + +elif cmd == "settxfee": + try: + amt = raw_input("Amount:") + print access.settxfee(amt) + except: + print "\n---An error occurred---\n" + +elif cmd == "stop": + try: + print access.stop() + except: + print "\n---An error occurred---\n" + +elif cmd == "validateaddress": + try: + addr = raw_input("Address: ") + print access.validateaddress(addr) + except: + print "\n---An error occurred---\n" + +elif cmd == "walletpassphrase": + try: + pwd = raw_input("Enter wallet passphrase: ") + access.walletpassphrase(pwd, 60) + print "\n---Wallet unlocked---\n" + except: + print "\n---An error occurred---\n" + +elif cmd == "walletpassphrasechange": + try: + pwd = raw_input("Enter old wallet passphrase: ") + pwd2 = raw_input("Enter new wallet passphrase: ") + access.walletpassphrasechange(pwd, pwd2) + print + print "\n---Passphrase changed---\n" + except: + print + print "\n---An error occurred---\n" + print + +else: + print "Command not found or not supported" \ No newline at end of file diff --git a/contrib/debian/bin/bitcoind b/contrib/debian/bin/bitcoind new file mode 100644 index 0000000..a2f55a9 --- /dev/null +++ b/contrib/debian/bin/bitcoind @@ -0,0 +1,14 @@ +#!/bin/sh + +set -e + +umask 077 + +basedir=~/.bitcoin +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" + +exec /usr/lib/bitcoin/bitcoind "$@" diff --git a/contrib/debian/bitcoin-qt.desktop b/contrib/debian/bitcoin-qt.desktop new file mode 100644 index 0000000..7cb00a2 --- /dev/null +++ b/contrib/debian/bitcoin-qt.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Bitcoin +Comment=Bitcoin P2P Cryptocurrency +Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair +Comment[tr]=Bitcoin, eşten eşe kriptografik sanal para birimi +Exec=/usr/bin/bitcoin-qt +Terminal=false +Type=Application +Icon=/usr/share/pixmaps/bitcoin80.xpm +MimeType=x-scheme-handler/bitcoin; +Categories=Office; diff --git a/contrib/debian/bitcoin-qt.install b/contrib/debian/bitcoin-qt.install new file mode 100644 index 0000000..ba40713 --- /dev/null +++ b/contrib/debian/bitcoin-qt.install @@ -0,0 +1,5 @@ +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 +debian/bitcoin-qt.protocol usr/share/kde4/services/ diff --git a/contrib/debian/bitcoin-qt.lintian-overrides b/contrib/debian/bitcoin-qt.lintian-overrides new file mode 100644 index 0000000..7fb230e --- /dev/null +++ b/contrib/debian/bitcoin-qt.lintian-overrides @@ -0,0 +1,2 @@ +# Linked code is Expat - only Debian packaging is GPL-2+ +bitcoin-qt: possible-gpl-code-linked-with-openssl diff --git a/contrib/debian/bitcoin-qt.protocol b/contrib/debian/bitcoin-qt.protocol new file mode 100644 index 0000000..014588d --- /dev/null +++ b/contrib/debian/bitcoin-qt.protocol @@ -0,0 +1,11 @@ +[Protocol] +exec=bitcoin-qt '%u' +protocol=bitcoin +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false diff --git a/contrib/debian/bitcoind.bash-completion b/contrib/debian/bitcoind.bash-completion new file mode 100644 index 0000000..0f84707 --- /dev/null +++ b/contrib/debian/bitcoind.bash-completion @@ -0,0 +1 @@ +contrib/bitcoind.bash-completion bitcoind diff --git a/contrib/debian/bitcoind.examples b/contrib/debian/bitcoind.examples new file mode 100644 index 0000000..4ded67d --- /dev/null +++ b/contrib/debian/bitcoind.examples @@ -0,0 +1 @@ +debian/examples/bitcoin.conf diff --git a/contrib/debian/bitcoind.install b/contrib/debian/bitcoind.install new file mode 100644 index 0000000..e978c44 --- /dev/null +++ b/contrib/debian/bitcoind.install @@ -0,0 +1,2 @@ +debian/bin/bitcoind usr/bin +src/bitcoind usr/lib/bitcoin diff --git a/contrib/debian/bitcoind.lintian-overrides b/contrib/debian/bitcoind.lintian-overrides new file mode 100644 index 0000000..3f9f140 --- /dev/null +++ b/contrib/debian/bitcoind.lintian-overrides @@ -0,0 +1,2 @@ +# Linked code is Expat - only Debian packaging is GPL-2+ +bitcoind: possible-gpl-code-linked-with-openssl diff --git a/contrib/debian/bitcoind.manpages b/contrib/debian/bitcoind.manpages new file mode 100644 index 0000000..3e4ca63 --- /dev/null +++ b/contrib/debian/bitcoind.manpages @@ -0,0 +1,2 @@ +debian/manpages/bitcoind.1 +debian/manpages/bitcoin.conf.5 diff --git a/contrib/debian/changelog b/contrib/debian/changelog new file mode 100644 index 0000000..52d0e59 --- /dev/null +++ b/contrib/debian/changelog @@ -0,0 +1,325 @@ +bitcoin (0.6.3-natty1) natty; urgency=low + + * New upstream release. + + -- Matt Corallo Mon, 25 Jun 2012 23:47:00 +0200 + +bitcoin (0.6.2-natty1) natty; urgency=low + + * Update package description and launch scripts. + + -- Matt Corallo Sat, 2 Jun 2012 16:41:00 +0200 + +bitcoin (0.6.2-natty0) natty; urgency=low + + * New upstream release. + + -- Matt Corallo Tue, 8 May 2012 16:27:00 -0500 + +bitcoin (0.6.1-natty0) natty; urgency=low + + * New upstream release. + + -- Matt Corallo Sun, 6 May 2012 20:09:00 -0500 + +bitcoin (0.6.0-natty0) natty; urgency=low + + * New upstream release. + * Add GNOME/KDE support for bitcoin-qt's bitcoin: URI support. + Thanks to luke-jr for the KDE .protocol file. + + -- Matt Corallo Sat, 31 Mar 2012 15:35:00 -0500 + +bitcoin (0.5.3-natty1) natty; urgency=low + + * Mark for upload to PPA. + + -- Matt Corallo Wed, 14 Mar 2012 23:06:00 -0400 + +bitcoin (0.5.3-natty0) natty; urgency=low + + * New upstream release. + + -- Luke Dashjr Tue, 10 Jan 2012 15:57:00 -0500 + +bitcoin (0.5.2-natty1) natty; urgency=low + + * Remove mentions on anonymity in package descriptions and manpage. + These should never have been there, bitcoin isnt anonymous without + a ton of work that virtually no users will ever be willing and + capable of doing + + -- Matt Corallo Sat, 7 Jan 2012 13:37:00 -0500 + +bitcoin (0.5.2-natty0) natty; urgency=low + + * New upstream release. + + -- Luke Dashjr Fri, 16 Dec 2011 17:57:00 -0500 + +bitcoin (0.5.1-natty0) natty; urgency=low + + * New upstream release. + + -- Matt Corallo Fri, 16 Dec 2011 13:27:00 -0500 + +bitcoin (0.5.0-natty0) natty; urgency=low + + * New upstream release. + + -- Matt Corallo Mon, 21 Nov 2011 11:32:00 -0500 + +bitcoin (0.5.0~rc7-natty0) natty; urgency=low + + * New upstream release candidate. + + -- Matt Corallo Sun, 20 Nov 2011 17:08:00 -0500 + +bitcoin (0.5.0~rc3-natty0) natty; urgency=low + + * New upstream release candidate. + * Don't set rpcpassword for bitcoin-qt. + + -- Matt Corallo Tue, 8 Nov 2011 11:56:00 -0400 + +bitcoin (0.5.0~rc1-natty1) natty; urgency=low + + * Add test_bitcoin to build test + * Fix clean + * Remove uneccessary build-dependancies + + -- Matt Corallo Wed, 26 Oct 2011 14:37:18 -0400 + +bitcoin (0.5.0~rc1-natty0) natty; urgency=low + + * Mark for natty + * Fix broken build + * Fix copyright listing + * Remove bitcoin: URL handler until bitcoin actually has support for it (Oops) + + -- Matt Corallo Wed, 26 Oct 2011 14:37:18 -0400 + +bitcoin (0.5.0~rc1-2) experimental; urgency=low + + * Add bitcoin-qt + + -- Matt Corallo Tue, 25 Oct 2011 15:24:18 -0400 + +bitcoin (0.5.0~rc1-1) experimental; urgency=low + + * New upstream prerelease. + * Add Github as alternate upstream source in watch file. + * Stop build-depending on libcrypto++-dev, and drop patch 1000: + Upstream no longer use crypto++. + * Drop patch 1003: Upstream builds dynamic by default now. + * Update copyright file: Drop notes on longer included sources. + + -- Jonas Smedegaard Fri, 14 Oct 2011 00:16:18 +0200 + +bitcoin (0.4.0-1) unstable; urgency=low + + * New upstream release. + * Stop repackaging source tarballs: No DFSG-violating stripping left. + * Update copyright file: + + Add Github URL to Source. + * Drop dpkg-source local-options hint: Declared options are default + since dpkg-source 1.16.1. + + Add irc URL to Upstream-Contact. + + Add comment on Bitcoin Developers to catch-all Files section. + + Add Files sections for newly readded src/cryptopp/* (new custom + BSD-like license), and newly added doc/build-osx.txt and + src/makefile.osx (Expat). + * Bump debhelper compatibility level to 7. + * Suppress binary icns and gpg files. + * Enable regression tests: + + Build-depend on libboost-test-dev. + + Extend patch 1003 to also dynamically link test binary. + + Build and invoke test binary unless tests are disabled. + * Tighten build-dependency on cdbs: Recent version needed to support + debhelper 7. + * Relax build-depend unversioned on debhelper: needed version + satisfied even in oldstable. + * Stop suppress optional build-dependencies: Satisfied in stable. + Build-depend on devscripts (enabling copyright-check). + + -- Jonas Smedegaard Wed, 05 Oct 2011 01:48:53 +0200 + +bitcoin (0.3.24~dfsg-1) unstable; urgency=low + + * New upstream release. + + [ Jonas Smedegaard ] + * Improve various usage hints: + + Explicitly mention in long description that bitcoind contains + daemon and command-line interface. + + Extend README.Debian with section on lack of GUI, and add primary + headline. + + Avoid installing upstream README: contains no parts relevant for + Debian usage. + Thanks to richard for suggestions (see bug#629443). + * Favor final releases over prereleases in rules and watch file. + Thanks to Jan Dittberner. + * Track -src (not -linux) tarballs in rules and watch file. + Thanks to Jan Dittberner. + * Drop patches 1004 and 1005 (integrated upstream) and simplify + CXXFLAGS in rules file. + * Stop stripping no longer included source-less binaries from upstream + tarballs. + + [ Jan Dittberner ] + * refresh debian/patches/1000_use_system_crypto++.patch + + -- Jonas Smedegaard Tue, 19 Jul 2011 15:08:54 +0200 + +bitcoin (0.3.21~dfsg-2) unstable; urgency=low + + * Enable UPNP support: + + Drop patch 1006. + + Build-depend on libminiupnpc-dev. + Thanks to Matt Corallo. + + -- Jonas Smedegaard Sat, 28 May 2011 15:52:44 +0200 + +bitcoin (0.3.21~dfsg-1) unstable; urgency=low + + * New upstream release. + * Refresh patches. + * Drop patch 1002: no longer needed, as upstream use pkgconfig now. + * Add patch 1006 to really unset USE_UPNP as aparently intended. + * Adjust cleanup rule to preserve .gitignore files. + * Update copyright file: + + Bump format to draft 174 of DEP-5. + + Shorten comments. + * Bump policy compliance to standards-version 3.9.2. + * Shorten Vcs-Browser paragraph in control file. + * Fix mention daemon (not CLI tools) in short description. + * Stop conflicting with or replace bitcoin-cli: Only transitional, no + longer needed. + * Link against unversioned berkeleydb. Update NEWS and README.Debian + accordingly (and improve wording while at it). + Closes: Bug#621425. Thanks to Ondřej Surý. + * This release also implicitly updates linkage against libcrypto++, + which closes: bug#626953, #627024. + * Disable linkage against not yet Debian packaged MiniUPnP. + * Silence seemingly harmless noise about unused variables. + + -- Jonas Smedegaard Tue, 17 May 2011 15:31:24 +0200 + +bitcoin (0.3.20.2~dfsg-2) unstable; urgency=medium + + * Fix have wrapper script execute real binary (not loop executing + itself). + Closes: bug#617290. Thanks to Philippe Gauthier and Etienne Laurin. + * Set urgency=medium as the only (user-exposed) binary is useless + without this fix and has been for some time. + + -- Jonas Smedegaard Wed, 16 Mar 2011 09:11:06 +0100 + +bitcoin (0.3.20.2~dfsg-1) unstable; urgency=low + + * New upstream release. + * Fix provide and replace former package name bitcoin-cli. + Closes: bug#618439. Thanks to Shane Wegner. + + -- Jonas Smedegaard Tue, 15 Mar 2011 11:41:43 +0100 + +bitcoin (0.3.20.01~dfsg-1) unstable; urgency=low + + * New upstream release. + + [ Micah Anderson ] + * Add myself as uploader. + + [ Jonas Smedegaard ] + * Add wrapper for bitcoind to ease initial startup. + * Update patches: + + Drop patch 2002: Applied upstream. + + Add patch 1005 to add phtread linker option. + Closes: bug#615619. Thanks to Shane Wegner. + + Refresh patches. + * Extend copyright years in rules file header. + * Rewrite copyright file using draft svn166 of DEP5 format. + * Rename binary package to bitcoind (from bincoin-cli). + Closes: bug#614025. Thanks to Luke-Jr. + + -- Jonas Smedegaard Tue, 01 Mar 2011 15:55:04 +0100 + +bitcoin (0.3.19~dfsg-6) unstable; urgency=low + + * Fix override agressive optimizations. + * Fix tighten build-dependencies to really fit backporting to Lenny: + + Add fallback build-dependency on libdb4.6++-dev. + + Tighten unversioned Boost build-dependencies to recent versions, + To force use of versioned Boost when backporting to Lenny. + ...needs more love, though: actual build fails. + + -- Jonas Smedegaard Mon, 17 Jan 2011 19:48:35 +0100 + +bitcoin (0.3.19~dfsg-5) unstable; urgency=low + + * Fix lower Boost fallback-build-dependencies to 1.35, really + available in Lenny. + * Correct comment in rules file regarding reason for versioned Boost + fallback-build-dependency. + * Add patch 2002 adding -mt decoration to Boost flags, to ease + backporting to Lenny. + * Respect DEB_BUILD_OPTIONS, and suppress arch-specific optimizations: + + Add patch 1004 to allow overriding optimization flags. + + Set optimization flags conditionally at build time. + + Drop patch 2002 unconditionally suppressing arch-optimizations. + + -- Jonas Smedegaard Mon, 17 Jan 2011 16:04:48 +0100 + +bitcoin (0.3.19~dfsg-4) unstable; urgency=low + + [ Micah Anderson ] + * Provide example bitcoin.conf. + * Add bitcoind(1) and bitcoin.conf(5) man pages. + + [ Jonas Smedegaard ] + * Ease backporting: + + Suppress optional build-dependencies. + + Add fallback build-dependencies on the most recent Boost libs + available in Lenny (where unversioned Boost libs are missing). + * Add Micah as copyright holder for manpages, licensed as GPL-3+. + * Bump copyright format to Subversion candidate draft 162 of DEP5. + + -- Jonas Smedegaard Mon, 17 Jan 2011 14:00:48 +0100 + +bitcoin (0.3.19~dfsg-3) unstable; urgency=low + + * Document in copyright file files excluded from repackaged source. + * Update copyright file: + + Bump DEP5 format hint to Subversion draft rev. 153. + + Consistently wrap at 72 chars. + + Refer to GPL-2 file (not GPL symlink). + * Link against Berkeley DB 4.8 (not 4.7): + + Build-depend on libdb4.8++-dev (and on on libdb4.7++-dev). + + Suggest libdb4.8-util and db4.7-util. + + Add README.Debian note on (untested) upgrade routine. + + Add NEWS entry on changed db version, referring to README.Debian. + + -- Jonas Smedegaard Fri, 07 Jan 2011 22:50:57 +0100 + +bitcoin (0.3.19~dfsg-2) unstable; urgency=low + + * Adjust build options to use optimized miner only for amd64. Fixes + FTBFS on i386 (and other archs, if compiling anywhere else at all). + * Avoid static linking. + * Adjust patch 2001 to avoid only arch-specific optimizations (keep + -O3). + * Extend long description to mention disk consumption and initial use + of IRC. + All of above changes thanks to Helmuth Grohne. + * Add lintian override regarding OpenSSL and GPL: Linked code is Expat + - only Debian packaging is GPL-2+. + + -- Jonas Smedegaard Wed, 29 Dec 2010 00:27:54 +0100 + +bitcoin (0.3.19~dfsg-1) unstable; urgency=low + + [ Jonas Smedegaard ] + * Initial release. + Closes: bug#578157. + + -- Jonas Smedegaard Tue, 28 Dec 2010 15:49:22 +0100 diff --git a/contrib/debian/compat b/contrib/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/contrib/debian/compat @@ -0,0 +1 @@ +7 diff --git a/contrib/debian/control b/contrib/debian/control new file mode 100644 index 0000000..c8266f6 --- /dev/null +++ b/contrib/debian/control @@ -0,0 +1,59 @@ +Source: bitcoin +Section: utils +Priority: optional +Maintainer: Jonas Smedegaard +Uploaders: Micah Anderson +Build-Depends: debhelper, + devscripts, + bash-completion, + libboost-system-dev (>> 1.35) | libboost-system1.35-dev, + libdb4.8++-dev, + libssl-dev, + pkg-config, + libminiupnpc8-dev, + libboost-filesystem-dev (>> 1.35) | libboost-filesystem1.35-dev, + libboost-program-options-dev (>> 1.35) | libboost-program-options1.35-dev, + libboost-thread-dev (>> 1.35) | libboost-thread1.35-dev, + libboost-test-dev (>> 1.35) | libboost-test1.35-dev, + qt4-qmake, + libqt4-dev, + libqrencode-dev +Standards-Version: 3.9.2 +Homepage: http://www.bitcoin.org/ +Vcs-Git: git://github.com/bitcoin/bitcoin.git +Vcs-Browser: http://github.com/bitcoin/bitcoin + +Package: bitcoind +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: peer-to-peer network based digital currency - daemon + Bitcoin is a free open source peer-to-peer electronic cash system that + is completely decentralized, without the need for a central server or + trusted parties. Users hold the crypto keys to their own money and + transact directly with each other, with the help of a P2P network to + check for double-spending. + . + By default connects to an IRC network to discover other peers. + . + Full transaction history is stored locally at each client. This + requires 2+ GB of space, slowly growing. + . + This package provides bitcoind, a combined daemon and CLI tool to + interact with the daemon. + +Package: bitcoin-qt +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: peer-to-peer network based digital currency - Qt GUI + Bitcoin is a free open source peer-to-peer electronic cash system that + is completely decentralized, without the need for a central server or + trusted parties. Users hold the crypto keys to their own money and + transact directly with each other, with the help of a P2P network to + check for double-spending. + . + By default connects to an IRC network to discover other peers. + . + Full transaction history is stored locally at each client. This + requires 2+ GB of space, slowly growing. + . + This package provides Bitcoin-Qt, a GUI for Bitcoin based on Qt. diff --git a/contrib/debian/copyright b/contrib/debian/copyright new file mode 100644 index 0000000..71913c5 --- /dev/null +++ b/contrib/debian/copyright @@ -0,0 +1,167 @@ +Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=174 +Upstream-Name: Bitcoin +Upstream-Contact: Satoshi Nakamoto + irc://#bitcoin@freenode.net +Source: http://sourceforge.net/projects/bitcoin/files/ + https://github.com/bitcoin/bitcoin + +Files: * +Copyright: 2009-2012, Bitcoin Developers +License: Expat +Comment: The Bitcoin Developers encompasses the current developers listed on bitcoin.org, + as well as the numerous contributors to the project. + +Files: src/json/* +Copyright: 2007-2009, John W. Wilkinson +License: Expat + +Files: src/strlcpy.h +Copyright: 1998, Todd C. Miller +License: ISC + +Files: debian/* +Copyright: 2010-2011, Jonas Smedegaard + 2011, Matt Corallo +License: GPL-2+ + +Files: debian/manpages/* +Copyright: Micah Anderson +License: GPL-3+ + +Files: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png, + src/qt/res/src/*.svg +Copyright: Wladimir van der Laan +License: Expat + +Files: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png, + src/qt/res/icons/history.png, src/qt/res/icons/key.png, + src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png, + src/qt/res/icons/receive.png, src/qt/res/icons/send.png, + src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png +Copyright: David Vignoni (david@icon-king.com) + ICON KING - www.icon-king.com +License: LGPL +Comment: NUVOLA ICON THEME for KDE 3.x + Original icons: kaddressbook, klipper_dock, view-list-text, + key-password, encrypted/decrypted, go-home, go-down, + go-next, dialog-ok + Site: http://www.icon-king.com/projects/nuvola/ + +Files: src/qt/res/icons/connect*.png +Copyright: schollidesign +License: GPL-3+ +Comment: Icon Pack: Human-O2 + Site: http://findicons.com/icon/93743/blocks_gnome_netstatus_0 + +Files: src/qt/res/icons/transaction*.png +Copyright: md2k7 +License: You are free to do with these icons as you wish, including selling, + copying, modifying etc. +Comment: Site: https://bitcointalk.org/index.php?topic=15276.0 + +Files: src/qt/res/icons/configure.png, src/qt/res/icons/quit.png, + src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png, + src/qt/res/icons/add.png, src/qt/res/icons/edit.png, + src/qt/res/icons/remove.png +Copyright: http://www.everaldo.com +License: LGPL +Comment: Icon Pack: Crystal SVG + +Files: src/qt/res/icons/bitcoin.png, src/qt/res/icons/toolbar.png +Copyright: Bitboy (optimized for 16x16 by Wladimir van der Laan) +License: PUB-DOM +Comment: Site: https://bitcointalk.org/?topic=1756.0 + +Files: scripts/img/reload.xcf, src/qt/res/movies/update_spinner.mng +Copyright: Everaldo (Everaldo Coelho) +License: GPL-3+ +Comment: Icon Pack: Kids + Site: http://findicons.com/icon/17102/reload?id=17102 + +Files: src/qt/res/images/splash2.jpg +License: PUB-DOM +Copyright: Crobbo (forum) +Comment: Site: https://bitcointalk.org/index.php?topic=32273.0 + + +License: Expat + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +License: ISC + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + . + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR + BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + +License: GPL-2+ + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + . + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. +Comment: + On Debian systems the GNU General Public License (GPL) version 2 is + located in '/usr/share/common-licenses/GPL-2'. + . + You should have received a copy of the GNU General Public License along + with this program. If not, see . + +License: GPL-3+ + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU General Public License, Version 3 or any + later version published by the Free Software Foundation. +Comment: + On Debian systems the GNU General Public License (GPL) version 3 is + located in '/usr/share/common-licenses/GPL-3'. + . + You should have received a copy of the GNU General Public License along + with this program. If not, see . + +License: LGPL + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +Comment: + On Debian systems the GNU Lesser General Public License (LGPL) is + located in '/usr/share/common-licenses/LGPL'. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +License: PUB-DOM + This work is in the public domain. diff --git a/contrib/debian/examples/bitcoin.conf b/contrib/debian/examples/bitcoin.conf new file mode 100644 index 0000000..e56c43c --- /dev/null +++ b/contrib/debian/examples/bitcoin.conf @@ -0,0 +1,88 @@ +# bitcoin.conf configuration file. Lines beginning with # are comments. + + +# Network-related settings: + +# Run on the test network instead of the real bitcoin network. +#testnet=1 + +# Connect via a socks4 proxy +#proxy=127.0.0.1:9050 + +# Use as many addnode= settings as you like to connect to specific peers +#addnode=69.164.218.197 +#addnode=10.0.0.2:8333 + +# ... or use as many connect= settings as you like to connect ONLY +# to specific peers: +#connect=69.164.218.197 +#connect=10.0.0.1:8333 + +# Do not use Internet Relay Chat (irc.lfnet.org #bitcoin channel) to +# find other peers. +#noirc=1 + +# Maximum number of inbound+outbound connections. +#maxconnections= + + +# JSON-RPC options (for controlling a running Bitcoin/bitcoind process) + +# server=1 tells Bitcoin to accept JSON-RPC commands. +#server=1 + +# You must set rpcuser and rpcpassword to secure the JSON-RPC api +#rpcuser=Ulysseys +#rpcpassword=YourSuperGreatPasswordNumber_385593 + +# By default, only RPC connections from localhost are allowed. Specify +# as many rpcallowip= settings as you like to allow connections from +# other hosts (and you may use * as a wildcard character): +#rpcallowip=10.1.1.34 +#rpcallowip=192.168.1.* + +# Listen for RPC connections on this TCP port: +rpcport=8332 + +# You can use Bitcoin or bitcoind to send commands to Bitcoin/bitcoind +# running on another host using this option: +rpcconnect=127.0.0.1 + +# Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate +# with Bitcoin -server or bitcoind +#rpcssl=1 + +# OpenSSL settings used when rpcssl=1 +rpcsslciphers=TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH +rpcsslcertificatechainfile=server.cert +rpcsslprivatekeyfile=server.pem + + +# Miscellaneous options + +# Set gen=1 to attempt to generate bitcoins +gen=0 + +# Use SSE instructions to try to generate bitcoins faster. +#4way=1 + +# Pre-generate this many public/private key pairs, so wallet backups will be valid for +# both prior transactions and several dozen future transactions. +keypool=100 + +# Pay an optional transaction fee every time you send bitcoins. Transactions with fees +# are more likely than free transactions to be included in generated blocks, so may +# be validated sooner. +paytxfee=0.00 + +# Allow direct connections for the 'pay via IP address' feature. +#allowreceivebyip=1 + + +# User interface options + +# Start Bitcoin minimized +#min=1 + +# Minimize to the system tray +#minimizetotray=1 diff --git a/contrib/debian/gbp.conf b/contrib/debian/gbp.conf new file mode 100644 index 0000000..a7281f9 --- /dev/null +++ b/contrib/debian/gbp.conf @@ -0,0 +1,5 @@ +# Configuration file for git-buildpackage and friends + +[DEFAULT] +pristine-tar = True +sign-tags = True diff --git a/contrib/debian/manpages/bitcoin.conf.5 b/contrib/debian/manpages/bitcoin.conf.5 new file mode 100644 index 0000000..1243253 --- /dev/null +++ b/contrib/debian/manpages/bitcoin.conf.5 @@ -0,0 +1,94 @@ +.TH BITCOIN.CONF "5" "January 2011" "bitcoin.conf 3.19" +.SH NAME +bitcoin.conf \- bitcoin configuration file +.SH SYNOPSIS +All command-line options (except for '-datadir' and '-conf') may be specified in a configuration file, and all configuration file options may also be specified on the command line. Command-line options override values set in the configuration file. +.TP +The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character. +.TP +The configuration file is not automatically created; you can create it using your favorite plain-text editor. By default, bitcoind(1) will look for a file named bitcoin.conf(5) in the bitcoin data directory, but both the data directory and the configuration file path may be changed using the '-datadir' and '-conf' command-line arguments. +.SH LOCATION +bitcoin.conf should be located in $HOME/.bitcoin +.SH NETWORK-RELATED SETTINGS +.TP +.TP +\fBtestnet=\fR[\fI'1'\fR|\fI'0'\fR] +Enable or disable run on the test network instead of the real *bitcoin* network. +.TP +\fBproxy=\fR\fI'127.0.0.1:9050'\fR +Connect via a socks4 proxy. +.TP +\fBaddnode=\fR\fI'10.0.0.2:8333'\fR +Use as many *addnode=* settings as you like to connect to specific peers. +.TP +\fBconnect=\fR\fI'10.0.0.1:8333'\fR +Use as many *connect=* settings as you like to connect ONLY to specific peers. +.TP +\fBnoirc=\fR[\fI'1'\fR|\fI'0'\fR] +Use or Do not use Internet Relay Chat (irc.lfnet.org #bitcoin channel) to find other peers. +.TP +\fRmaxconnections=\fR\fI'value'\fR +Maximum number of inbound+outbound connections. +.SH JSON-RPC OPTIONS +.TP +\fBserver=\fR[\fI'1'\fR|\fI'0'\fR] +Tells *bitcoin* to accept or not accept JSON-RPC commands. +.TP +\fBrpcuser=\fR\fI'username'\fR +You must set *rpcuser* to secure the JSON-RPC api. +.TP +\fBrpcpassword=\fR\fI'password'\fR +You must set *rpcpassword* to secure the JSON-RPC api. +.TP +\fBrpctimeout=\fR\fI'30'\fR +How many seconds *bitcoin* will wait for a complete RPC HTTP request, after the HTTP connection is established. +.TP +\fBrpcallowip=\fR\fI'192.168.1.*'\fR +By default, only RPC connections from localhost are allowed. Specify as many *rpcallowip=* settings as you like to allow connections from other hosts (and you may use * as a wildcard character). +.TP +\fBrpcport=\fR\fI'8332'\fR +Listen for RPC connections on this TCP port. +.TP +\fBrpcconnect=\fR\fI'127.0.0.1'\fR +You can use *bitcoin* or *bitcoind(1)* to send commands to *bitcoin*/*bitcoind(1)* running on another host using this option. +.TP +\fBrpcssl=\fR\fI'1'\fR +Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate with *bitcoin* '-server' or *bitcoind(1)*. Example of OpenSSL settings used when *rpcssl*='1': +.TP +\fBrpcsslciphers=\fR\fI'TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH'\fR +.TP +\fBrpcsslcertificatechainfile=\fR\fI'server.cert'\fR +.TP +\fBrpcsslprivatekeyfile=\fR\fI'server.pem'\fR +.TP +.SH MISCELLANEOUS OPTIONS +.TP +\fBgen=\fR[\fI'0'\fR|\fI'1'\fR] +Enable or disable attempt to generate bitcoins. +.TP +\fB4way=\fR[\fI'0'\fR|\fI'1'\fR] +Enable or disable use SSE instructions to try to generate bitcoins faster. +.TP +\fBkeypool=\fR\fI'100'\fR +Pre-generate this many public/private key pairs, so wallet backups will be valid for both prior transactions and several dozen future transactions. +.TP +\fBpaytxfee=\fR\fI'0.00'\fR +Pay an optional transaction fee every time you send bitcoins. Transactions with fees are more likely than free transactions to be included in generated blocks, so may be validated sooner. +.TP +\fBallowreceivebyip=\fR\fI'1'\fR +Allow direct connections for the 'pay via IP address' feature. +.TP +.SH USER INTERFACE OPTIONS +.TP +\fBmin=\fR[\fI'0'\fR|\fI'1'\fR] +Enable or disable start bitcoind minimized. +.TP +\fBminimizetotray=\fR[\fI'0'\fR|\fI'1'\fR] +Enable or disable minimize to the system tray. +.SH "SEE ALSO" +bitcoind(1) +.SH AUTHOR +This manual page was written by Micah Anderson for the Debian system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL. + diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1 new file mode 100644 index 0000000..bf46a66 --- /dev/null +++ b/contrib/debian/manpages/bitcoind.1 @@ -0,0 +1,209 @@ +.TH BITCOIND "1" "January 2011" "bitcoind 3.19" +.SH NAME +bitcoind \- peer-to-peer network based digital currency +.SH SYNOPSIS +bitcoin [options] [params] +.TP +bitcoin [options] help - Get help for a command +.SH DESCRIPTION +This manual page documents the bitcoind program. Bitcoin is a peer-to-peer digital currency. Peer-to-peer (P2P) means that there is no central authority to issue new money or keep track of transactions. Instead, these tasks are managed collectively by the nodes of the network. Advantages: + +Bitcoins can be sent easily through the Internet, without having to trust middlemen. Transactions are designed to be irreversible. Be safe from instability caused by fractional reserve banking and central banks. The limited inflation of the Bitcoin system’s money supply is distributed evenly (by CPU power) throughout the network, not monopolized by banks. + +.SH OPTIONS +.TP +\fB\-conf=\fR +Specify configuration file (default: bitcoin.conf) +.TP +\fB\-gen\fR +Generate coins +.TP +\fB\-gen\fR=\fI0\fR +Don't generate coins +.TP +\fB\-min\fR +Start minimized +.TP +\fB\-datadir=\fR +Specify data directory +.TP +\fB\-proxy=\fR +Connect through socks4 proxy +.TP +\fB\-addnode=\fR +Add a node to connect to +.TP +\fB\-connect=\fR +Connect only to the specified node +.TP +\fB\-paytxfee=\fR +Fee per KB to add to transactions you send +.TP +\fB\-server\fR +Accept command line and JSON\-RPC commands +.TP +\fB\-daemon\fR +Run in the background as a daemon and accept commands +.TP +\fB\-testnet\fR +Use the test network +.TP +\fB\-rpcuser=\fR +Username for JSON\-RPC connections +.TP +\fB\-rpcpassword=\fR +Password for JSON\-RPC connections +.TP +\fB\-rpcport=\fR +Listen for JSON\-RPC connections on +.TP +\fB\-rpcallowip=\fR +Allow JSON\-RPC connections from specified IP address +.TP +\fB\-rpcconnect=\fR +Send commands to node running on +.PP +SSL options: (see the Bitcoin Wiki for SSL setup instructions) +.TP +\fB\-rpcssl\fR=\fI1\fR +Use OpenSSL (https) for JSON\-RPC connections +.TP +\fB\-rpcsslcertificatchainfile=\fR +Server certificate file (default: server.cert) +.TP +\fB\-rpcsslprivatekeyfile=\fR +Server private key (default: server.pem) +.TP +\fB\-rpcsslciphers=\fR +Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) +.TP +\-? +This help message +.SH COMMANDS +.TP +\fBbackupwallet 'destination'\fR +Safely copies *wallet.dat* to 'destination', which can be a directory or a path with filename. +.TP +\fBgetaccount 'bitcoinaddress'\fR +Returns the account associated with the given address. +.TP +\fBsetaccount 'bitcoinaddress' ['account']\fR +Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account']. +.TP +\fBgetaccountaddress 'account'\fR +Returns a new bitcoin address for 'account'. +.TP +\fBgetaddressesbyaccount 'account'\fR +Returns the list of addresses associated with the given 'account'. +.TP +\fBgetbalance 'account'\fR +Returns the server's available balance, or the balance for 'account'. +.TP +\fBgetblockcount\fR +Returns the number of blocks in the longest block chain. +.TP +\fBgetblocknumber\fR +Returns the block number of the latest block in the longest block chain. +.TP +\fBgetconnectioncount\fR +Returns the number of connections to other nodes. +.TP +\fBgetdifficulty\fR +Returns the proof-of-work difficulty as a multiple of the minimum difficulty. +.TP +\fBgetgenerate\fR +Returns boolean true if server is trying to generate bitcoins, false otherwise. +.TP +\fBsetgenerate 'generate' ['genproclimit']\fR +Generation is limited to ['genproclimit'] processors, -1 is unlimited. +.TP +\fBgethashespersec\fR +Returns a recent hashes per second performance measurement while generating. +.TP +\fBgetinfo\fR +Returns an object containing server information. +.TP +\fBgetnewaddress 'account'\fR +Returns a new bitcoin address for receiving payments. If 'account' is specified (recommended), it is added to the address book so payments received with the address will be credited to 'account'. +.TP +\fBgetreceivedbyaccount 'account' ['minconf=1']\fR +Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations. +.TP +\fBgetreceivedbyaddress 'bitcoinaddress' ['minconf=1']\fR +Returns the total amount received by 'bitcoinaddress' in transactions with at least ['minconf'] confirmations. +.TP +\fBgettransaction 'txid'\fR +Returns information about a specific transaction, given hexadecimal transaction ID. +.TP +\fBgetwork 'data'\fR +If 'data' is specified, tries to solve the block and returns true if it was successful. If 'data' is not specified, returns formatted hash 'data' to work on: + + "midstate" : precomputed hash state after hashing the first half of the data. + "data" : block data. + "hash1" : formatted hash buffer for second hash. + "target" : little endian hash target. +.TP +\fBhelp 'command'\fR +List commands, or get help for a command. +.TP +\fBlistaccounts ['minconf=1']\fR +List accounts and their current balances. + *note: requires bitcoin 0.3.20 or later. +.TP +\fBlistreceivedbyaccount ['minconf=1'] ['includeempty=false']\fR +['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing: + + "account" : the account of the receiving address. + "amount" : total amount received by the address. + "confirmations" : number of confirmations of the most recent transaction included. +.TP +\fBlistreceivedbyaddress ['minconf=1'] ['includeempty=false']\fR +['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing: + + "address" : receiving address. + "account" : the account of the receiving address. + "amount" : total amount received by the address. + "confirmations" : number of confirmations of the most recent transaction included. +.TP +\fBlisttransactions 'account' ['count=10']\fR +Returns a list of the last ['count'] transactions for 'account' - for all accounts if 'account' is not specified or is "*". Each entry in the list may contain: + + "category" : will be generate, send, receive, or move. + "amount" : amount of transaction. + "fee" : Fee (if any) paid (only for send transactions). + "confirmations" : number of confirmations (only for generate/send/receive). + "txid" : transaction ID (only for generate/send/receive). + "otheraccount" : account funds were moved to or from (only for move). + "message" : message associated with transaction (only for send). + "to" : message-to associated with transaction (only for send). + + *note: requires bitcoin 0.3.20 or later. +.TP +\fBmove <'fromaccount'> <'toaccount'> <'amount'> ['minconf=1'] ['comment']\fR +Moves funds between accounts. +.TP +\fBsendfrom* <'account'> <'bitcoinaddress'> <'amount'> ['minconf=1'] ['comment'] ['comment-to']\fR +Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success. +.TP +\fBsendtoaddress 'bitcoinaddress' 'amount' ['comment'] ['comment-to']\fR +Sends amount from the server's available balance to 'bitcoinaddress'. amount is a real and is rounded to the nearest 0.01. Returns transaction id on success. +.TP +\fBstop\fR +Stops the bitcoin server. +.TP +\fBvalidateaddress 'bitcoinaddress'\fR +Checks that 'bitcoinaddress' looks like a proper bitcoin address. Returns an object containing: + + "isvalid" : true or false. + "ismine" : true if the address is in the server's wallet. + "address" : bitcoinaddress. + + *note: ismine and address are only returned if the address is valid. + +.SH "SEE ALSO" +bitcoin.conf(5) +.SH AUTHOR +This manual page was written by Micah Anderson for the Debian system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL. + diff --git a/contrib/debian/patches/README b/contrib/debian/patches/README new file mode 100644 index 0000000..80c1584 --- /dev/null +++ b/contrib/debian/patches/README @@ -0,0 +1,3 @@ +0xxx: Grabbed from upstream development. +1xxx: Possibly relevant for upstream adoption. +2xxx: Only relevant for official Debian release. diff --git a/contrib/debian/patches/series b/contrib/debian/patches/series new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/contrib/debian/patches/series @@ -0,0 +1 @@ + diff --git a/contrib/debian/rules b/contrib/debian/rules new file mode 100644 index 0000000..98bb2bb --- /dev/null +++ b/contrib/debian/rules @@ -0,0 +1,33 @@ +#!/usr/bin/make -f +# -*- mode: makefile; coding: utf-8 -*- + +#DEB_MAKE_CHECK_TARGET = test_bitcoin +#build/bitcoind:: +# $(if $(filter nocheck,$(DEB_BUILD_OPTIONS)),,src/test_bitcoin) + +DEB_INSTALL_EXAMPLES_bitcoind += debian/examples/* +DEB_INSTALL_MANPAGES_bitcoind += debian/manpages/* + +%: + dh --with bash-completion $@ + +override_dh_auto_build: + cd src; $(MAKE) -f makefile.unix bitcoind + $(MAKE) + +override_dh_auto_clean: + if [ -f Makefile ]; then $(MAKE) clean; else rm -rf build/; rm -f bitcoin-qt; fi + cd src; $(MAKE) -f makefile.unix clean + +override_dh_auto_configure: + qmake bitcoin-qt.pro USE_QRCODE=1 + +override_dh_auto_test: + cd src; $(MAKE) -f makefile.unix test_bitcoin + src/test_bitcoin + +# Ensure wrapper is set executable +binary-post-install/bitcoind: + chmod +x $(cdbs_curdestdir)usr/bin/bitcoind +binary-post-install/bitcoin-qt: + chmod +x $(cdbs_curdestdir)usr/bin/bitcoin-qt diff --git a/contrib/debian/source/format b/contrib/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/contrib/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/contrib/debian/watch b/contrib/debian/watch new file mode 100644 index 0000000..c96d2f8 --- /dev/null +++ b/contrib/debian/watch @@ -0,0 +1,7 @@ +# Run the "uscan" command to check for upstream updates and more. +version=3 +# use qa.debian.org redirector; see man uscan +opts=uversionmangle=s/(\d)(alpha|beta|rc)/$1~$2/;s/\-src//,dversionmangle=s/~dfsg\d*// \ + http://sf.net/bitcoin/bitcoin-(\d.*)-linux\.tar\.gz debian +opts=uversionmangle=s/(\d)(alpha|beta|rc)/$1~$2/,dversionmangle=s/~dfsg\d*// \ + http://githubredir.debian.net/github/bitcoin/bitcoin v(.*).tar.gz diff --git a/contrib/gitian-descriptors/README b/contrib/gitian-descriptors/README new file mode 100644 index 0000000..a2d902e --- /dev/null +++ b/contrib/gitian-descriptors/README @@ -0,0 +1,31 @@ +Gavin's notes on getting gitian builds up and running: + +You need the right hardware: you need a 64-bit-capable CPU with hardware virtualization support (Intel VT-x or AMD-V). Not all modern CPUs support hardware virtualization. + +You probably need to enable hardware virtualization in your machine's BIOS. + +You need to be running a recent version of 64-bit-Ubuntu, and you need to install several prerequisites: + sudo apt-get install apache2 git apt-cacher-ng python-vm-builder qemu-kvm + +Sanity checks: + sudo service apt-cacher-ng status # Should return apt-cacher-ng is running + ls -l /dev/kvm # Should show a /dev/kvm device + +Once you've got the right hardware and software: + + git clone git://github.com/bitcoin/bitcoin.git + git clone git://github.com/devrandom/gitian-builder.git + mkdir gitian-builder/inputs + wget 'http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.6.tar.gz' -O gitian-builder/inputs/miniupnpc-1.6.tar.gz + + cd gitian-builder + bin/make-base-vm --arch i386 + bin/make-base-vm --arch amd64 + cd .. + + # To build + cd bitcoin + git pull + cd ../gitian-builder + git pull + ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian.yml diff --git a/contrib/gitian-descriptors/boost-win32.yml b/contrib/gitian-descriptors/boost-win32.yml new file mode 100644 index 0000000..c4a9f33 --- /dev/null +++ b/contrib/gitian-descriptors/boost-win32.yml @@ -0,0 +1,38 @@ +--- +name: "boost" +suites: +- "lucid" +architectures: +- "i386" +packages: +- "mingw32" +- "faketime" +- "zip" +reference_datetime: "2011-01-30 00:00:00" +remotes: [] +files: +- "boost_1_49_0.tar.bz2" +script: | + TMPDIR="$HOME/tmpdir" + mkdir -p $TMPDIR/bin/$GBUILD_BITS $TMPDIR/include + tar xjf boost_1_49_0.tar.bz2 + cd boost_1_49_0 + echo "using gcc : 4.4 : i586-mingw32msvc-g++ + : + i586-mingw32msvc-windres + i586-mingw32msvc-ar + -frandom-seed=boost1 + ;" > user-config.jam + ./bootstrap.sh --without-icu + ./bjam toolset=gcc target-os=windows threadapi=win32 threading=multi variant=release link=static --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete $MAKEOPTS stage + for lib in chrono date_time exception filesystem graph iostreams math_c99f math_c99l math_c99 math_tr1f math_tr1l math_tr1 prg_exec_monitor program_options random regex serialization signals system test_exec_monitor thread_win32 unit_test_framework wave wserialization; do + mkdir $lib + (cd $lib ; ar xf ../stage/lib/libboost_${lib}-mt-s.a) + mv $lib $TMPDIR/bin/$GBUILD_BITS + done + cp -a boost $TMPDIR/include + cd $TMPDIR + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + zip -r boost-win32-1.49.0-gitian2.zip * + cp boost-win32-1.49.0-gitian2.zip $OUTDIR diff --git a/contrib/gitian-descriptors/deps-win32.yml b/contrib/gitian-descriptors/deps-win32.yml new file mode 100644 index 0000000..941c9f2 --- /dev/null +++ b/contrib/gitian-descriptors/deps-win32.yml @@ -0,0 +1,72 @@ +--- +name: "casinocoin-deps" +suites: +- "lucid" +architectures: +- "i386" +packages: +- "mingw32" +- "git-core" +- "zip" +- "faketime" +- "wine" +- "psmisc" +reference_datetime: "2011-01-30 00:00:00" +remotes: [] +files: +- "openssl-1.0.1b.tar.gz" +- "db-4.8.30.NC.tar.gz" +- "miniupnpc-1.6.tar.gz" +- "zlib-1.2.7.tar.gz" +- "libpng-1.5.12.tar.gz" +- "qrencode-3.2.0.tar.bz2" +script: | + # + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + export TZ=UTC + # + tar xzf openssl-1.0.1b.tar.gz + cd openssl-1.0.1b + ./Configure --cross-compile-prefix=i586-mingw32msvc- mingw + make + cd .. + # + tar xzf db-4.8.30.NC.tar.gz + cd db-4.8.30.NC/build_unix + ../dist/configure --enable-mingw --enable-cxx --host=i586-mingw32msvc CFLAGS="-I/usr/i586-mingw32msvc/include" + make $MAKEOPTS + cd ../.. + # + tar xzf miniupnpc-1.6.tar.gz + cd miniupnpc-1.6 + sed 's/dllwrap -k --driver-name gcc/$(DLLWRAP) -k --driver-name $(CC)/' -i Makefile.mingw + sed 's|wingenminiupnpcstrings $< $@|./wingenminiupnpcstrings $< $@|' -i Makefile.mingw + make -f Makefile.mingw DLLWRAP=i586-mingw32msvc-dllwrap CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar + cd .. + mv miniupnpc-1.6 miniupnpc + # + tar xzf zlib-1.2.7.tar.gz + cd zlib-1.2.7 + make -f win32/Makefile.gcc PREFIX=i586-mingw32msvc- $MAKEOPTS + cd .. + # + tar xzf libpng-1.5.12.tar.gz + cd libpng-1.5.12 + ./configure -disable-shared CC=i586-mingw32msvc-cc AR=i586-mingw32msvc-ar STRIP=i586-mingw32msvc-strip RANLIB=i586-mingw32msvc-ranlib OBJDUMP=i586-mingw32msvc-objdump LD=i586-mingw32msvc-ld LDFLAGS="-L../zlib-1.2.7/" CFLAGS="-I../zlib-1.2.7/" + make $MAKEOPTS + cd .. + # + tar xjf qrencode-3.2.0.tar.bz2 + cd qrencode-3.2.0 + ./configure CC=i586-mingw32msvc-cc AR=i586-mingw32msvc-ar STRIP=i586-mingw32msvc-strip RANLIB=i586-mingw32msvc-ranlib OBJDUMP=i586-mingw32msvc-objdump LD=i586-mingw32msvc-ld png_LIBS="../libpng-1.5.12/.libs/libpng15.a ../zlib-1.2.7/libz.a" png_CFLAGS="-I../libpng-1.5.12" + make $MAKEOPTS + cd .. + # + zip -r $OUTDIR/casinocoin-deps-0.0.4.zip \ + $(ls qrencode-*/{qrencode.h,.libs/libqrencode.{,l}a} | sort) \ + $(ls db-*/build_unix/{libdb_cxx.a,db.h,db_cxx.h,libdb.a,.libs/libdb_cxx-?.?.a} | sort) \ + $(find openssl-* -name '*.a' -o -name '*.h' | sort) \ + $(find miniupnpc -name '*.h' -o -name 'libminiupnpc.a' | sort) + # Kill wine processes as gitian won't figure out we are done otherwise + killall wineserver services.exe explorer.exe winedevice.exe diff --git a/contrib/gitian-descriptors/gitian-win32.yml b/contrib/gitian-descriptors/gitian-win32.yml new file mode 100644 index 0000000..62e44f2 --- /dev/null +++ b/contrib/gitian-descriptors/gitian-win32.yml @@ -0,0 +1,75 @@ +--- +name: "casinocoin" +suites: +- "lucid" +architectures: +- "i386" +packages: +- "mingw32" +- "git-core" +- "unzip" +- "nsis" +- "faketime" +reference_datetime: "2011-01-30 00:00:00" +remotes: +- "url": "https://github.com/casinocoin-project/casinocoin.git" + "dir": "casinocoin" +files: +- "qt-win32-4.7.4-gitian.zip" +- "boost-win32-1.49.0-gitian2.zip" +- "casinocoin-deps-0.0.4.zip" +script: | + # + mkdir $HOME/qt + cd $HOME/qt + unzip ../build/qt-win32-4.7.4-gitian.zip + cd $HOME/build/ + export PATH=$PATH:$HOME/qt/bin/ + # + mkdir boost_1_49_0 + cd boost_1_49_0 + mkdir -p stage/lib + unzip ../boost-win32-1.49.0-gitian2.zip + cd bin/$GBUILD_BITS + for lib in *; do + i586-mingw32msvc-ar rc ../../stage/lib/libboost_${lib}-mt-s.a $lib/*.o + i586-mingw32msvc-ranlib ../../stage/lib/libboost_${lib}-mt-s.a + done + cd ../.. + mv include/boost . + cd .. + # + unzip casinocoin-deps-0.0.4.zip + # + find -type f | xargs touch --date="$REFERENCE_DATETIME" + # + cd casinocoin + mkdir -p $OUTDIR/src + git archive HEAD | tar -x -C $OUTDIR/src + cp $OUTDIR/src/doc/README_windows.txt $OUTDIR/readme.txt + cp $OUTDIR/src/COPYING $OUTDIR/license.txt + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + export TZ=UTC + $HOME/qt/src/bin/qmake -spec unsupported/win32-g++-cross MINIUPNPC_LIB_PATH=$HOME/build/miniupnpc MINIUPNPC_INCLUDE_PATH=$HOME/build/ BDB_LIB_PATH=$HOME/build/db-4.8.30.NC/build_unix BDB_INCLUDE_PATH=$HOME/build/db-4.8.30.NC/build_unix BOOST_LIB_PATH=$HOME/build/boost_1_49_0/stage/lib BOOST_INCLUDE_PATH=$HOME/build/boost_1_49_0 BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$HOME/build/openssl-1.0.1b OPENSSL_INCLUDE_PATH=$HOME/build/openssl-1.0.1b/include QRENCODE_LIB_PATH=$HOME/build/qrencode-3.2.0/.libs QRENCODE_INCLUDE_PATH=$HOME/build/qrencode-3.2.0 USE_QRCODE=1 INCLUDEPATH=$HOME/build DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=bitcoin QMAKE_LFLAGS=-frandom-seed=bitcoin USE_BUILD_INFO=1 + make $MAKEOPTS + i586-mingw32msvc-strip release/casinocoin-qt.exe + cp release/casinocoin-qt.exe $OUTDIR/ + # + cd src + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + export TZ=UTC + make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build casinocoind.exe USE_UPNP=0 DEBUGFLAGS="-frandom-seed=casinocoin" + i586-mingw32msvc-strip casinocoind.exe + mkdir $OUTDIR/daemon + cp casinocoind.exe $OUTDIR/daemon + cd .. + mkdir nsis + git archive HEAD | tar -x -C nsis + cd nsis/src + mkdir ../release + cp ../../release/* ../release/ + cp ../../src/*.exe . + makensis ../share/setup.nsi + cp ../share/casinocoin-*-win32-setup.exe $OUTDIR/ diff --git a/contrib/gitian-descriptors/gitian.yml b/contrib/gitian-descriptors/gitian.yml new file mode 100644 index 0000000..dd8e700 --- /dev/null +++ b/contrib/gitian-descriptors/gitian.yml @@ -0,0 +1,55 @@ +--- +name: "casinocoin" +suites: +- "lucid" +architectures: +- "i386" +- "amd64" +packages: +- "libdb4.8++-dev" +- "qt4-qmake" +- "libqt4-dev" +- "libboost-system-dev" +- "libboost-filesystem-dev" +- "libboost-program-options-dev" +- "libboost-thread-dev" +- "libssl-dev" +- "git-core" +- "unzip" +- "pkg-config" +- "libpng12-dev" +reference_datetime: "2011-01-30 00:00:00" +remotes: +- "url": "https://github.com/casinocoin-project/casinocoin.git" + "dir": "casinocoin" +files: +- "miniupnpc-1.6.tar.gz" +- "qrencode-3.2.0.tar.bz2" +script: | + INSTDIR="$HOME/install" + export LIBRARY_PATH="$INSTDIR/lib" + # + tar xzf miniupnpc-1.6.tar.gz + cd miniupnpc-1.6 + INSTALLPREFIX=$INSTDIR make $MAKEOPTS install + cd .. + # + tar xjf qrencode-3.2.0.tar.bz2 + cd qrencode-3.2.0 + ./configure --prefix=$INSTDIR --enable-static --disable-shared + make $MAKEOPTS install + cd .. + # + cd casinocoin + mkdir -p $OUTDIR/src + git archive HEAD | tar -x -C $OUTDIR/src + cp $OUTDIR/src/doc/README $OUTDIR + cp $OUTDIR/src/COPYING $OUTDIR + cd src + make -f makefile.unix STATIC=1 OPENSSL_INCLUDE_PATH="$INSTDIR/include" OPENSSL_LIB_PATH="$INSTDIR/lib" $MAKEOPTS casinocoind USE_UPNP=0 DEBUGFLAGS= + mkdir -p $OUTDIR/bin/$GBUILD_BITS + install -s casinocoind $OUTDIR/bin/$GBUILD_BITS + cd .. + qmake INCLUDEPATH="$INSTDIR/include" LIBS="-L$INSTDIR/lib" RELEASE=1 USE_QRCODE=1 + make $MAKEOPTS + install -s casinocoin-qt $OUTDIR/bin/$GBUILD_BITS diff --git a/contrib/gitian-descriptors/qt-win32.yml b/contrib/gitian-descriptors/qt-win32.yml new file mode 100644 index 0000000..6eb76b2 --- /dev/null +++ b/contrib/gitian-descriptors/qt-win32.yml @@ -0,0 +1,54 @@ +--- +name: "qt" +suites: +- "lucid" +architectures: +- "i386" +packages: +- "mingw32" +- "zip" +- "faketime" +reference_datetime: "2011-01-30 00:00:00" +remotes: [] +files: +- "qt-everywhere-opensource-src-4.7.4.tar.gz" +script: | + INSTDIR="$HOME/qt/" + mkdir $INSTDIR + SRCDIR="$INSTDIR/src/" + mkdir $SRCDIR + # + tar xzf qt-everywhere-opensource-src-4.7.4.tar.gz + cd qt-everywhere-opensource-src-4.7.4 + sed 's/$TODAY/2011-01-30/' -i configure + sed 's/i686-pc-mingw32-/i586-mingw32msvc-/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf + sed --posix 's|QMAKE_CFLAGS\t\t= -pipe|QMAKE_CFLAGS\t\t= -pipe -isystem /usr/i586-mingw32msvc/include/ -frandom-seed=qtbuild|' -i mkspecs/unsupported/win32-g++-cross/qmake.conf + sed 's/QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads/QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf + sed 's/QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads/QMAKE_LFLAGS_EXCEPTIONS_ON = -lmingwthrd/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf + sed --posix 's/QMAKE_MOC\t\t= i586-mingw32msvc-moc/QMAKE_MOC\t\t= moc/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf + sed --posix 's/QMAKE_RCC\t\t= i586-mingw32msvc-rcc/QMAKE_RCC\t\t= rcc/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf + sed --posix 's/QMAKE_UIC\t\t= i586-mingw32msvc-uic/QMAKE_UIC\t\t= uic/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf + # ar adds timestamps to every object file included in the static library + # providing -D as ar argument is supposed to solve it, but doesn't work as qmake strips off the arguments and adds -M to pass a script... + # which somehow cannot be combined with other flags. + # use faketime only for ar, as it confuses make/qmake into hanging sometimes + sed --posix "s|QMAKE_LIB\t\t= i586-mingw32msvc-ar -ru|QMAKE_LIB\t\t= $HOME/ar -Dr|" -i mkspecs/unsupported/win32-g++-cross/qmake.conf + echo '#!/bin/bash' > $HOME/ar + echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/ar + echo 'i586-mingw32msvc-ar "$@"' >> $HOME/ar + chmod +x $HOME/ar + #export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + export TZ=UTC + ./configure -prefix $INSTDIR -confirm-license -release -opensource -static -no-qt3support -xplatform unsupported/win32-g++-cross -no-multimedia -no-audio-backend -no-phonon -no-phonon-backend -no-declarative -no-script -no-scripttools -no-javascript-jit -no-webkit -no-svg -no-xmlpatterns -no-sql-sqlite -no-nis -no-cups -no-iconv -no-dbus -no-gif -no-libtiff -opengl no -nomake examples -nomake demos -nomake docs + find . -name *.prl | xargs -l sed 's|/\.||' -i + find . -name *.prl | xargs -l sed 's|/$||' -i + make $MAKEOPTS install + cp -a bin $SRCDIR/ + cd $INSTDIR + find . -name *.prl | xargs -l sed 's|/$||' -i + #sed 's|QMAKE_PRL_LIBS.*|QMAKE_PRL_LIBS = -lQtDeclarative -lQtScript -lQtSvg -lQtSql -lQtXmlPatterns -lQtGui -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lmsimg32 -lQtNetwork -lQtCore -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32|' -i imports/Qt/labs/particles/qmlparticlesplugin.prl + + # as zip stores file timestamps, use faketime to intercept stat calls to set dates for all files to reference date + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + zip -r $OUTDIR/qt-win32-4.7.4-gitian.zip * diff --git a/contrib/gitian-downloader/bluematt-key.pgp b/contrib/gitian-downloader/bluematt-key.pgp new file mode 100644 index 0000000..fb6d9eb Binary files /dev/null and b/contrib/gitian-downloader/bluematt-key.pgp differ diff --git a/contrib/gitian-downloader/devrandom-key.pgp b/contrib/gitian-downloader/devrandom-key.pgp new file mode 100644 index 0000000..7189812 Binary files /dev/null and b/contrib/gitian-downloader/devrandom-key.pgp differ diff --git a/contrib/gitian-downloader/gavinandresen-key.pgp b/contrib/gitian-downloader/gavinandresen-key.pgp new file mode 100644 index 0000000..f81f44e Binary files /dev/null and b/contrib/gitian-downloader/gavinandresen-key.pgp differ diff --git a/contrib/gitian-downloader/laanwj-key.pgp b/contrib/gitian-downloader/laanwj-key.pgp new file mode 100644 index 0000000..5592951 --- /dev/null +++ b/contrib/gitian-downloader/laanwj-key.pgp @@ -0,0 +1,28 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: SKS 1.1.0 + +mQENBE5UtMEBCADOUz2i9l/D8xYINCmfUDnxi+DXvX5LmZ39ZdvsoE+ugO0SRRGdIHEFO2is +0xezX50wXu9aneb+tEqM0BuiLo6VxaXpxrkxHpr6c4jf37SkE/H0qsi/txEUp7337y3+4HMG +lUjiuh802I72p1qusjsKBnmnnR0rwNouTcoDmGUDh7jpKCtzFv+2TR2dRthJn7vmmjq3+bG6 +PYfqoFY1yHrAGT1lrDBULZsQ/NBLI2+J4oo2LYv3GCq8GNnzrovqvTvui50VSROhLrOe58o2 +shE+sjQShAy5wYkPt1R1fQnpfx+5vf+TPnkxVwRb3h5GhCp0YL8XC/BXsd5vM4KlVH2rABEB +AAG0K1dsYWRpbWlyIEouIHZhbiBkZXIgTGFhbiA8bGFhbndqQGdtYWlsLmNvbT6JATgEEwEC +ACIFAk5UtMECGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEHSBCwEjRsmmy6YIAK09 +buNXyYQrJBsX16sXxEhx5QPKyF3uHJDFJv66SdnpvIkNoznsaPiRJkbTANop93FZmaGa6wVn +zGDiz7jPA8Dpxx5aAYPhIT+zPJAdXWM3wJ/Gio9besRNzniai8Lwi5MZ9R/5yFGBobm6/AcN +4sUoqA3NSV2U3I29R0Vwlzo8GVtmyi9ENSi6Oo7AcXNTRt69cxW4nAHkB+amwwDJlcAb31ex +bogYXPhScwqQZixRr+JBkKxBjkTXXnQypT4KI5SegYwQVYfyiZmDP7UHKe/u6pSKKbVphLg8 +xLB5spcXse8/a2+onrbNlw6y8TXiJ++Z54PE7zztWTXf2huakeG5AQ0ETlS0wQEIAMNO3OkP +xoPRKWzBLcI7JRITAW+HNaLTq3uN2+4WxA57DEjbL9EDoAv+7wTkDAL40f0T+xiu6GJcLFjw +GJZu/tYu7+mErHjrdo+K4suCQt7w5EXCBvOLjhW4tyYMzNx8hP+oqzOW9iEC+6VV91+DYeqt +EkJuyVXOI4vzBlTw8uGow8aMMsCq8XVvKUZFTPsjGl197Q5B3A+ZOFCR8xqiqdPjuz6MglVV +oFdDNu3EZn8zkGsQlovXoE9ndVeVzx/XMNmsxFaMYsReUs253RIf1FEfgExID0fg2OnyLCjS +2iFW1RgajS+/saIkKl+N1iuMzJA7wMAM0plhRueOG0MtZSsAEQEAAYkBHwQYAQIACQUCTlS0 +wQIbDAAKCRB0gQsBI0bJpmsDB/4waenn2CvSHXyomykfpwf5lMte1V5LvH3z5R2LY+1NopRv +LSz3iC39x69XWiTbhywDfgafnGPW4pWBOff2/bu5/A6z1Hnan1vyrRRD/hx1uMJ7S6q+bIvZ +iVIg1p0jH6tdIIhwX3cydhdRZHo7e9oSMgOUWsr6Ar59NRo9CENwGPE4U61HXfOnxWdrFWoA +XdwZczBeLxmUy6Vo6sKqv+gE4bqrtAM0sY/MsQ9cU95x+52ox/sq44lQMwd3ZBYUP7B1qbHI +hZSZuch6MLi5scLPeau0ZvCaljiaMeivP5+x0gWPRs0kI+9sZxInbqvrsJ6oOBJM3xYGhtn1 +zZ7qmZR7 +=si/k +-----END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-downloader/linux-download-config b/contrib/gitian-downloader/linux-download-config new file mode 100644 index 0000000..aef614d --- /dev/null +++ b/contrib/gitian-downloader/linux-download-config @@ -0,0 +1,38 @@ +--- +name: bitcoin +urls: +- http://bitcoin.org/bitcoin-latest-linux-gitian.zip +rss: +- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss + xpath: //item/link/text() + pattern: bitcoin-\d+.\d+.\d+-linux-gitian.zip +signers: + 0A82509767C7D4A5D14DA2301AE1D35043E08E54: + weight: 40 + name: BlueMatt + key: bluematt + BF6273FAEF7CC0BA1F562E50989F6B3048A116B5: + weight: 40 + name: Devrandom + key: devrandom + E463A93F5F3117EEDE6C7316BD02942421F4889F: + weight: 40 + name: Luke-Jr + key: luke-jr + D762373D24904A3E42F33B08B9A408E71DAAC974: + weight: 40 + name: "Pieter Wuille" + key: sipa + 77E72E69DA7EE0A148C06B21B34821D4944DE5F7: + weight: 40 + name: tcatm + key: tcatm + 01CDF4627A3B88AAE4A571C87588242FBE38D3A8: + weight: 40 + name: "Gavin Andresen" + key: gavinandresen + 71A3B16735405025D447E8F274810B012346C9A6: + weight: 40 + name: "Wladimir J. van der Laan" + key: laanwj +minimum_weight: 120 diff --git a/contrib/gitian-downloader/luke-jr-key.pgp b/contrib/gitian-downloader/luke-jr-key.pgp new file mode 100644 index 0000000..275b041 Binary files /dev/null and b/contrib/gitian-downloader/luke-jr-key.pgp differ diff --git a/contrib/gitian-downloader/sipa-key.pgp b/contrib/gitian-downloader/sipa-key.pgp new file mode 100644 index 0000000..ffa09bb Binary files /dev/null and b/contrib/gitian-downloader/sipa-key.pgp differ diff --git a/contrib/gitian-downloader/tcatm-key.pgp b/contrib/gitian-downloader/tcatm-key.pgp new file mode 100644 index 0000000..baaec76 Binary files /dev/null and b/contrib/gitian-downloader/tcatm-key.pgp differ diff --git a/contrib/gitian-downloader/win32-download-config b/contrib/gitian-downloader/win32-download-config new file mode 100644 index 0000000..0f7032e --- /dev/null +++ b/contrib/gitian-downloader/win32-download-config @@ -0,0 +1,38 @@ +--- +name: bitcoin +urls: +- http://bitcoin.org/bitcoin-latest-win32-gitian.zip +rss: +- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss + xpath: //item/link/text() + pattern: bitcoin-\d+.\d+.\d+-win32-gitian.zip +signers: + 0A82509767C7D4A5D14DA2301AE1D35043E08E54: + weight: 40 + name: BlueMatt + key: bluematt + BF6273FAEF7CC0BA1F562E50989F6B3048A116B5: + weight: 40 + name: Devrandom + key: devrandom + E463A93F5F3117EEDE6C7316BD02942421F4889F: + weight: 40 + name: Luke-Jr + key: luke-jr + D762373D24904A3E42F33B08B9A408E71DAAC974: + weight: 40 + name: "Pieter Wuille" + key: sipa + 77E72E69DA7EE0A148C06B21B34821D4944DE5F7: + weight: 40 + name: tcatm + key: tcatm + 01CDF4627A3B88AAE4A571C87588242FBE38D3A8: + weight: 40 + name: "Gavin Andresen" + key: gavinandresen + 71A3B16735405025D447E8F274810B012346C9A6: + weight: 40 + name: "Wladimir J. van der Laan" + key: laanwj +minimum_weight: 120 diff --git a/contrib/macdeploy/LICENSE b/contrib/macdeploy/LICENSE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/contrib/macdeploy/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/contrib/macdeploy/background.png b/contrib/macdeploy/background.png new file mode 100644 index 0000000..a50a0ba Binary files /dev/null and b/contrib/macdeploy/background.png differ diff --git a/contrib/macdeploy/background.psd b/contrib/macdeploy/background.psd new file mode 100644 index 0000000..5889676 Binary files /dev/null and b/contrib/macdeploy/background.psd differ diff --git a/contrib/macdeploy/fancy.plist b/contrib/macdeploy/fancy.plist new file mode 100644 index 0000000..a660788 --- /dev/null +++ b/contrib/macdeploy/fancy.plist @@ -0,0 +1,32 @@ + + + + + window_bounds + + 300 + 300 + 800 + 620 + + background_picture + background.png + icon_size + 96 + applications_symlink + + items_position + + Applications + + 370 + 156 + + CasinoCoin-Qt.app + + 128 + 156 + + + + diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus new file mode 100644 index 0000000..e159f9b --- /dev/null +++ b/contrib/macdeploy/macdeployqtplus @@ -0,0 +1,747 @@ +#!/usr/bin/env python + +# +# Copyright (C) 2011 Patrick "p2k" Schneider +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import subprocess, sys, re, os, shutil, stat, os.path +from time import sleep +from argparse import ArgumentParser + +# This is ported from the original macdeployqt with modifications + +class FrameworkInfo(object): + def __init__(self): + self.frameworkDirectory = "" + self.frameworkName = "" + self.frameworkPath = "" + self.binaryDirectory = "" + self.binaryName = "" + self.binaryPath = "" + self.version = "" + self.installName = "" + self.deployedInstallName = "" + self.sourceFilePath = "" + self.destinationDirectory = "" + self.sourceResourcesDirectory = "" + self.destinationResourcesDirectory = "" + + def __eq__(self, other): + if self.__class__ == other.__class__: + return self.__dict__ == other.__dict__ + else: + return False + + def __str__(self): + return """ Framework name: %s + Framework directory: %s + Framework path: %s + Binary name: %s + Binary directory: %s + Binary path: %s + Version: %s + Install name: %s + Deployed install name: %s + Source file Path: %s + Deployed Directory (relative to bundle): %s +""" % (self.frameworkName, + self.frameworkDirectory, + self.frameworkPath, + self.binaryName, + self.binaryDirectory, + self.binaryPath, + self.version, + self.installName, + self.deployedInstallName, + self.sourceFilePath, + self.destinationDirectory) + + def isDylib(self): + return self.frameworkName.endswith(".dylib") + + def isQtFramework(self): + if self.isDylib(): + return self.frameworkName.startswith("libQt") + else: + return self.frameworkName.startswith("Qt") + + reOLine = re.compile(r'^(.+) \(compatibility version [0-9.]+, current version [0-9.]+\)$') + bundleFrameworkDirectory = "Contents/Frameworks" + bundleBinaryDirectory = "Contents/MacOS" + + @classmethod + def fromOtoolLibraryLine(cls, line): + # Note: line must be trimmed + if line == "": + return None + + # Don't deploy system libraries (exception for libQtuitools and libQtlucene). + if line.startswith("/System/Library/") or line.startswith("@executable_path") or (line.startswith("/usr/lib/") and "libQt" not in line): + return None + + m = cls.reOLine.match(line) + if m is None: + raise RuntimeError("otool line could not be parsed: " + line) + + path = m.group(1) + + info = cls() + info.sourceFilePath = path + info.installName = path + + if path.endswith(".dylib"): + dirname, filename = os.path.split(path) + info.frameworkName = filename + info.frameworkDirectory = dirname + info.frameworkPath = path + + info.binaryDirectory = dirname + info.binaryName = filename + info.binaryPath = path + info.version = "-" + + info.installName = path + info.deployedInstallName = "@executable_path/../Frameworks/" + info.binaryName + info.sourceFilePath = path + info.destinationDirectory = cls.bundleFrameworkDirectory + else: + parts = path.split("/") + i = 0 + # Search for the .framework directory + for part in parts: + if part.endswith(".framework"): + break + i += 1 + if i == len(parts): + raise RuntimeError("Could not find .framework or .dylib in otool line: " + line) + + info.frameworkName = parts[i] + info.frameworkDirectory = "/".join(parts[:i]) + info.frameworkPath = os.path.join(info.frameworkDirectory, info.frameworkName) + + info.binaryName = parts[i+3] + info.binaryDirectory = "/".join(parts[i+1:i+3]) + info.binaryPath = os.path.join(info.binaryDirectory, info.binaryName) + info.version = parts[i+2] + + info.deployedInstallName = "@executable_path/../Frameworks/" + os.path.join(info.frameworkName, info.binaryPath) + info.destinationDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, info.binaryDirectory) + + info.sourceResourcesDirectory = os.path.join(info.frameworkPath, "Resources") + info.destinationResourcesDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Resources") + + return info + +class ApplicationBundleInfo(object): + def __init__(self, path): + self.path = path + appName = os.path.splitext(os.path.basename(path))[0] + self.binaryPath = os.path.join(path, "Contents", "MacOS", appName) + if not os.path.exists(self.binaryPath): + raise RuntimeError("Could not find bundle binary for " + path) + self.resourcesPath = os.path.join(path, "Contents", "Resources") + self.pluginPath = os.path.join(path, "Contents", "PlugIns") + +class DeploymentInfo(object): + def __init__(self): + self.qtPath = None + self.pluginPath = None + self.deployedFrameworks = [] + + def detectQtPath(self, frameworkDirectory): + parentDir = os.path.dirname(frameworkDirectory) + if os.path.exists(os.path.join(parentDir, "translations")): + # Classic layout, e.g. "/usr/local/Trolltech/Qt-4.x.x" + self.qtPath = parentDir + elif os.path.exists(os.path.join(parentDir, "share", "qt4", "translations")): + # MacPorts layout, e.g. "/opt/local/share/qt4" + self.qtPath = os.path.join(parentDir, "share", "qt4") + + if self.qtPath is not None: + pluginPath = os.path.join(self.qtPath, "plugins") + if os.path.exists(pluginPath): + self.pluginPath = pluginPath + + def usesFramework(self, name): + nameDot = "%s." % name + libNameDot = "lib%s." % name + for framework in self.deployedFrameworks: + if framework.endswith(".framework"): + if framework.startswith(nameDot): + return True + elif framework.endswith(".dylib"): + if framework.startswith(libNameDot): + return True + return False + +def getFrameworks(binaryPath, verbose): + if verbose >= 3: + print "Inspecting with otool: " + binaryPath + otool = subprocess.Popen(["otool", "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + o_stdout, o_stderr = otool.communicate() + if otool.returncode != 0: + if verbose >= 1: + sys.stderr.write(o_stderr) + sys.stderr.flush() + raise RuntimeError("otool failed with return code %d" % otool.returncode) + + otoolLines = o_stdout.split("\n") + otoolLines.pop(0) # First line is the inspected binary + if ".framework" in binaryPath or binaryPath.endswith(".dylib"): + otoolLines.pop(0) # Frameworks and dylibs list themselves as a dependency. + + libraries = [] + for line in otoolLines: + info = FrameworkInfo.fromOtoolLibraryLine(line.strip()) + if info is not None: + if verbose >= 3: + print "Found framework:" + print info + libraries.append(info) + + return libraries + +def runInstallNameTool(action, *args): + subprocess.check_call(["install_name_tool", "-"+action] + list(args)) + +def changeInstallName(oldName, newName, binaryPath, verbose): + if verbose >= 3: + print "Using install_name_tool:" + print " in", binaryPath + print " change reference", oldName + print " to", newName + runInstallNameTool("change", oldName, newName, binaryPath) + +def changeIdentification(id, binaryPath, verbose): + if verbose >= 3: + print "Using install_name_tool:" + print " change identification in", binaryPath + print " to", id + runInstallNameTool("id", id, binaryPath) + +def runStrip(binaryPath, verbose): + if verbose >= 3: + print "Using strip:" + print " stripped", binaryPath + subprocess.check_call(["strip", "-x", binaryPath]) + +def copyFramework(framework, path, verbose): + fromPath = framework.sourceFilePath + toDir = os.path.join(path, framework.destinationDirectory) + toPath = os.path.join(toDir, framework.binaryName) + + if not os.path.exists(fromPath): + raise RuntimeError("No file at " + fromPath) + + if os.path.exists(toPath): + return None # Already there + + if not os.path.exists(toDir): + os.makedirs(toDir) + + shutil.copy2(fromPath, toPath) + if verbose >= 3: + print "Copied:", fromPath + print " to:", toPath + + permissions = os.stat(toPath) + if not permissions.st_mode & stat.S_IWRITE: + os.chmod(toPath, permissions.st_mode | stat.S_IWRITE) + + if not framework.isDylib(): # Copy resources for real frameworks + fromResourcesDir = framework.sourceResourcesDirectory + if os.path.exists(fromResourcesDir): + toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory) + shutil.copytree(fromResourcesDir, toResourcesDir) + if verbose >= 3: + print "Copied resources:", fromResourcesDir + print " to:", toResourcesDir + elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout) + qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib") + qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib") + if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath): + shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath) + if verbose >= 3: + print "Copied for libQtGui:", qtMenuNibSourcePath + print " to:", qtMenuNibDestinationPath + + return toPath + +def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploymentInfo=None): + if deploymentInfo is None: + deploymentInfo = DeploymentInfo() + + while len(frameworks) > 0: + framework = frameworks.pop(0) + deploymentInfo.deployedFrameworks.append(framework.frameworkName) + + if verbose >= 2: + print "Processing", framework.frameworkName, "..." + + # Get the Qt path from one of the Qt frameworks + if deploymentInfo.qtPath is None and framework.isQtFramework(): + deploymentInfo.detectQtPath(framework.frameworkDirectory) + + if framework.installName.startswith("@executable_path"): + if verbose >= 2: + print framework.frameworkName, "already deployed, skipping." + continue + + # install_name_tool the new id into the binary + changeInstallName(framework.installName, framework.deployedInstallName, binaryPath, verbose) + + # Copy farmework to app bundle. + deployedBinaryPath = copyFramework(framework, bundlePath, verbose) + # Skip the rest if already was deployed. + if deployedBinaryPath is None: + continue + + if strip: + runStrip(deployedBinaryPath, verbose) + + # install_name_tool it a new id. + changeIdentification(framework.deployedInstallName, deployedBinaryPath, verbose) + # Check for framework dependencies + dependencies = getFrameworks(deployedBinaryPath, verbose) + + for dependency in dependencies: + changeInstallName(dependency.installName, dependency.deployedInstallName, deployedBinaryPath, verbose) + + # Deploy framework if necessary. + if dependency.frameworkName not in deploymentInfo.deployedFrameworks and dependency not in frameworks: + frameworks.append(dependency) + + return deploymentInfo + +def deployFrameworksForAppBundle(applicationBundle, strip, verbose): + frameworks = getFrameworks(applicationBundle.binaryPath, verbose) + if len(frameworks) == 0 and verbose >= 1: + print "Warning: Could not find any external frameworks to deploy in %s." % (applicationBundle.path) + return DeploymentInfo() + else: + return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose) + +def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): + # Lookup available plugins, exclude unneeded + plugins = [] + for dirpath, dirnames, filenames in os.walk(deploymentInfo.pluginPath): + pluginDirectory = os.path.relpath(dirpath, deploymentInfo.pluginPath) + if pluginDirectory == "designer": + # Skip designer plugins + continue + elif pluginDirectory == "phonon": + # Deploy the phonon plugins only if phonon is in use + if not deploymentInfo.usesFramework("phonon"): + continue + elif pluginDirectory == "sqldrivers": + # Deploy the sql plugins only if QtSql is in use + if not deploymentInfo.usesFramework("QtSql"): + continue + elif pluginDirectory == "script": + # Deploy the script plugins only if QtScript is in use + if not deploymentInfo.usesFramework("QtScript"): + continue + elif pluginDirectory == "qmltooling": + # Deploy the qml plugins only if QtDeclarative is in use + if not deploymentInfo.usesFramework("QtDeclarative"): + continue + elif pluginDirectory == "bearer": + # Deploy the bearer plugins only if QtNetwork is in use + if not deploymentInfo.usesFramework("QtNetwork"): + continue + + for pluginName in filenames: + pluginPath = os.path.join(pluginDirectory, pluginName) + if pluginName.endswith("_debug.dylib"): + # Skip debug plugins + continue + elif pluginPath == "imageformats/libqsvg.dylib" or pluginPath == "iconengines/libqsvgicon.dylib": + # Deploy the svg plugins only if QtSvg is in use + if not deploymentInfo.usesFramework("QtSvg"): + continue + elif pluginPath == "accessible/libqtaccessiblecompatwidgets.dylib": + # Deploy accessibility for Qt3Support only if the Qt3Support is in use + if not deploymentInfo.usesFramework("Qt3Support"): + continue + elif pluginPath == "graphicssystems/libqglgraphicssystem.dylib": + # Deploy the opengl graphicssystem plugin only if QtOpenGL is in use + if not deploymentInfo.usesFramework("QtOpenGL"): + continue + + plugins.append((pluginDirectory, pluginName)) + + for pluginDirectory, pluginName in plugins: + if verbose >= 2: + print "Processing plugin", os.path.join(pluginDirectory, pluginName), "..." + + sourcePath = os.path.join(deploymentInfo.pluginPath, pluginDirectory, pluginName) + destinationDirectory = os.path.join(appBundleInfo.pluginPath, pluginDirectory) + if not os.path.exists(destinationDirectory): + os.makedirs(destinationDirectory) + + destinationPath = os.path.join(destinationDirectory, pluginName) + shutil.copy2(sourcePath, destinationPath) + if verbose >= 3: + print "Copied:", sourcePath + print " to:", destinationPath + + if strip: + runStrip(destinationPath, verbose) + + dependencies = getFrameworks(destinationPath, verbose) + + for dependency in dependencies: + changeInstallName(dependency.installName, dependency.deployedInstallName, destinationPath, verbose) + + # Deploy framework if necessary. + if dependency.frameworkName not in deploymentInfo.deployedFrameworks: + deployFrameworks([dependency], appBundleInfo.path, destinationPath, strip, verbose, deploymentInfo) + +qt_conf="""[Paths] +translations=Resources +plugins=PlugIns +""" + +ap = ArgumentParser(description="""Improved version of macdeployqt. + +Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .dmg file. +Note, that the "dist" folder will be deleted before deploying on each run. + +Optionally, Qt translation files (.qm) and additional resources can be added to the bundle.""") + +ap.add_argument("app_bundle", nargs=1, metavar="app-bundle", help="application bundle to be deployed") +ap.add_argument("-verbose", type=int, nargs=1, default=[1], metavar="<0-3>", help="0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug") +ap.add_argument("-no-plugins", dest="plugins", action="store_false", default=True, help="skip plugin deployment") +ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, help="don't run 'strip' on the binaries") +ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image; if basename is not specified, a camel-cased version of the app name is used") +ap.add_argument("-fancy", nargs=1, metavar="plist", default=[], help="make a fancy looking disk image using the given plist file with instructions; requires -dmg to work") +ap.add_argument("-add-qt-tr", nargs=1, metavar="languages", default=[], help="add Qt translation files to the bundle's ressources; the language list must be separated with commas, not with whitespace") +ap.add_argument("-add-resources", nargs="+", metavar="path", default=[], help="list of additional files or folders to be copied into the bundle's resources; must be the last argument") + +config = ap.parse_args() + +verbose = config.verbose[0] + +# ------------------------------------------------ + +app_bundle = config.app_bundle[0] + +if not os.path.exists(app_bundle): + if verbose >= 1: + sys.stderr.write("Error: Could not find app bundle \"%s\"\n" % (app_bundle)) + sys.exit(1) + +app_bundle_name = os.path.splitext(os.path.basename(app_bundle))[0] + +# ------------------------------------------------ + +for p in config.add_resources: + if verbose >= 3: + print "Checking for \"%s\"..." % p + if not os.path.exists(p): + if verbose >= 1: + sys.stderr.write("Error: Could not find additional resource file \"%s\"\n" % (p)) + sys.exit(1) + +# ------------------------------------------------ + +if len(config.fancy) == 1: + if verbose >= 3: + print "Fancy: Importing plistlib..." + try: + import plistlib + except ImportError: + if verbose >= 1: + sys.stderr.write("Error: Could not import plistlib which is required for fancy disk images.\n") + sys.exit(1) + + if verbose >= 3: + print "Fancy: Importing appscript..." + try: + import appscript + except ImportError: + if verbose >= 1: + sys.stderr.write("Error: Could not import appscript which is required for fancy disk images.\n") + sys.stderr.write("Please install it e.g. with \"sudo easy_install appscript\".\n") + sys.exit(1) + + p = config.fancy[0] + if verbose >= 3: + print "Fancy: Loading \"%s\"..." % p + if not os.path.exists(p): + if verbose >= 1: + sys.stderr.write("Error: Could not find fancy disk image plist at \"%s\"\n" % (p)) + sys.exit(1) + + try: + fancy = plistlib.readPlist(p) + except: + if verbose >= 1: + sys.stderr.write("Error: Could not parse fancy disk image plist at \"%s\"\n" % (p)) + sys.exit(1) + + try: + assert not fancy.has_key("window_bounds") or (isinstance(fancy["window_bounds"], list) and len(fancy["window_bounds"]) == 4) + assert not fancy.has_key("background_picture") or isinstance(fancy["background_picture"], str) + assert not fancy.has_key("icon_size") or isinstance(fancy["icon_size"], int) + assert not fancy.has_key("applications_symlink") or isinstance(fancy["applications_symlink"], bool) + if fancy.has_key("items_position"): + assert isinstance(fancy["items_position"], dict) + for key, value in fancy["items_position"].iteritems(): + assert isinstance(value, list) and len(value) == 2 and isinstance(value[0], int) and isinstance(value[1], int) + except: + if verbose >= 1: + sys.stderr.write("Error: Bad format of fancy disk image plist at \"%s\"\n" % (p)) + sys.exit(1) + + if fancy.has_key("background_picture"): + bp = fancy["background_picture"] + if verbose >= 3: + print "Fancy: Resolving background picture \"%s\"..." % bp + if not os.path.exists(bp): + bp = os.path.join(os.path.dirname(p), bp) + if not os.path.exists(bp): + if verbose >= 1: + sys.stderr.write("Error: Could not find background picture at \"%s\" or \"%s\"\n" % (fancy["background_picture"], bp)) + sys.exit(1) + else: + fancy["background_picture"] = bp +else: + fancy = None + +# ------------------------------------------------ + +if os.path.exists("dist"): + if verbose >= 2: + print "+ Removing old dist folder +" + + shutil.rmtree("dist") + +# ------------------------------------------------ + +target = os.path.join("dist", app_bundle) + +if verbose >= 2: + print "+ Copying source bundle +" +if verbose >= 3: + print app_bundle, "->", target + +os.mkdir("dist") +shutil.copytree(app_bundle, target) + +applicationBundle = ApplicationBundleInfo(target) + +# ------------------------------------------------ + +if verbose >= 2: + print "+ Deploying frameworks +" + +try: + deploymentInfo = deployFrameworksForAppBundle(applicationBundle, config.strip, verbose) + if deploymentInfo.qtPath is None: + deploymentInfo.qtPath = os.getenv("QTDIR", None) + if deploymentInfo.qtPath is None: + if verbose >= 1: + sys.stderr.write("Warning: Could not detect Qt's path, skipping plugin deployment!\n") + config.plugins = False +except RuntimeError as e: + if verbose >= 1: + sys.stderr.write("Error: %s\n" % str(e)) + sys.exit(ret) + +# ------------------------------------------------ + +if config.plugins: + if verbose >= 2: + print "+ Deploying plugins +" + + try: + deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose) + except RuntimeError as e: + if verbose >= 1: + sys.stderr.write("Error: %s\n" % str(e)) + sys.exit(ret) + +# ------------------------------------------------ + +if len(config.add_qt_tr) == 0: + add_qt_tr = [] +else: + qt_tr_dir = os.path.join(deploymentInfo.qtPath, "translations") + add_qt_tr = ["qt_%s.qm" % lng for lng in config.add_qt_tr[0].split(",")] + for lng_file in add_qt_tr: + p = os.path.join(qt_tr_dir, lng_file) + if verbose >= 3: + print "Checking for \"%s\"..." % p + if not os.path.exists(p): + if verbose >= 1: + sys.stderr.write("Error: Could not find Qt translation file \"%s\"\n" % (lng_file)) + sys.exit(1) + +# ------------------------------------------------ + +if verbose >= 2: + print "+ Installing qt.conf +" + +f = open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") +f.write(qt_conf) +f.close() + +# ------------------------------------------------ + +if len(add_qt_tr) > 0 and verbose >= 2: + print "+ Adding Qt translations +" + +for lng_file in add_qt_tr: + if verbose >= 3: + print os.path.join(qt_tr_dir, lng_file), "->", os.path.join(applicationBundle.resourcesPath, lng_file) + shutil.copy2(os.path.join(qt_tr_dir, lng_file), os.path.join(applicationBundle.resourcesPath, lng_file)) + +# ------------------------------------------------ + +if len(config.add_resources) > 0 and verbose >= 2: + print "+ Adding additional resources +" + +for p in config.add_resources: + t = os.path.join(applicationBundle.resourcesPath, os.path.basename(p)) + if verbose >= 3: + print p, "->", t + if os.path.isdir(p): + shutil.copytree(p, t) + else: + shutil.copy2(p, t) + +# ------------------------------------------------ + +if config.dmg is not None: + def runHDIUtil(verb, image_basename, **kwargs): + hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"] + if kwargs.has_key("capture_stdout"): + del kwargs["capture_stdout"] + run = subprocess.check_output + else: + if verbose < 2: + hdiutil_args.append("-quiet") + elif verbose >= 3: + hdiutil_args.append("-verbose") + run = subprocess.check_call + + for key, value in kwargs.iteritems(): + hdiutil_args.append("-" + key) + if not value is True: + hdiutil_args.append(str(value)) + + return run(hdiutil_args) + + if verbose >= 2: + if fancy is None: + print "+ Creating .dmg disk image +" + else: + print "+ Preparing .dmg disk image +" + + if config.dmg != "": + dmg_name = config.dmg + else: + spl = app_bundle_name.split(" ") + dmg_name = spl[0] + "".join(p.capitalize() for p in spl[1:]) + + if fancy is None: + try: + runHDIUtil("create", dmg_name, srcfolder="dist", format="UDBZ", volname=app_bundle_name, ov=True) + except subprocess.CalledProcessError as e: + sys.exit(e.returncode) + else: + if verbose >= 3: + print "Determining size of \"dist\"..." + size = 0 + for path, dirs, files in os.walk("dist"): + for file in files: + size += os.path.getsize(os.path.join(path, file)) + size += int(size * 0.1) + + if verbose >= 3: + print "Creating temp image for modification..." + try: + runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=app_bundle_name, ov=True) + except subprocess.CalledProcessError as e: + sys.exit(e.returncode) + + if verbose >= 3: + print "Attaching temp image..." + try: + output = runHDIUtil("attach", dmg_name + ".temp", readwrite=True, noverify=True, noautoopen=True, capture_stdout=True) + except subprocess.CalledProcessError as e: + sys.exit(e.returncode) + + m = re.search("/Volumes/(.+$)", output) + disk_root = m.group(0) + disk_name = m.group(1) + + if verbose >= 2: + print "+ Applying fancy settings +" + + if fancy.has_key("background_picture"): + bg_path = os.path.join(disk_root, os.path.basename(fancy["background_picture"])) + if verbose >= 3: + print fancy["background_picture"], "->", bg_path + shutil.copy2(fancy["background_picture"], bg_path) + else: + bg_path = None + + if fancy.get("applications_symlink", False): + os.symlink("/Applications", os.path.join(disk_root, "Applications")) + + finder = appscript.app("Finder") + disk = finder.disks[disk_name] + disk.open() + window = disk.container_window + window.current_view.set(appscript.k.icon_view) + window.toolbar_visible.set(False) + window.statusbar_visible.set(False) + if fancy.has_key("window_bounds"): + window.bounds.set(fancy["window_bounds"]) + view_options = window.icon_view_options + view_options.arrangement.set(appscript.k.not_arranged) + if fancy.has_key("icon_size"): + view_options.icon_size.set(fancy["icon_size"]) + if bg_path is not None: + view_options.background_picture.set(disk.files[os.path.basename(bg_path)]) + if fancy.has_key("items_position"): + for name, position in fancy["items_position"].iteritems(): + window.items[name].position.set(position) + disk.close() + if bg_path is not None: + subprocess.call(["SetFile", "-a", "V", bg_path]) + disk.update(registering_applications=False) + sleep(2) + disk.eject() + + if verbose >= 2: + print "+ Finalizing .dmg disk image +" + + try: + runHDIUtil("convert", dmg_name + ".temp", format="UDBZ", o=dmg_name + ".dmg", ov=True) + except subprocess.CalledProcessError as e: + sys.exit(e.returncode) + + os.unlink(dmg_name + ".temp.dmg") + +# ------------------------------------------------ + +if verbose >= 2: + print "+ Done +" + +sys.exit(0) diff --git a/contrib/macdeploy/notes.txt b/contrib/macdeploy/notes.txt new file mode 100644 index 0000000..a3f0b54 --- /dev/null +++ b/contrib/macdeploy/notes.txt @@ -0,0 +1,26 @@ + +macdeployqtplus works best on OS X Lion, for Snow Leopard you'd need to install +Python 2.7 and make it your default Python installation. + +You will need the appscript package for the fancy disk image creation to work. +Install it by invoking "sudo easy_install appscript". + +Ths script should be invoked in the target directory like this: +$source_dir/contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy $source_dir/contrib/macdeploy/fancy.plist -verbose 2 + +During the process, the disk image window will pop up briefly where the fancy +settings are applied. This is normal, please do not interfere. + +You can also set up Qt Creator for invoking the script. For this, go to the +"Projects" tab on the left side, switch to "Run Settings" above and add a +deploy configuration. Next add a deploy step choosing "Custom Process Step". +Fill in the following. + +Enable custom process step: [x] +Command: %{sourceDir}/contrib/macdeploy/macdeployqtplus +Working directory: %{buildDir} +Command arguments: Bitcoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy %{sourceDir}/contrib/macdeploy/fancy.plist -verbose 2 + +After that you can start the deployment process through the menu with +Build -> Deploy Project "bitcoin-qt" + diff --git a/contrib/pyminer/README b/contrib/pyminer/README new file mode 100644 index 0000000..d159657 --- /dev/null +++ b/contrib/pyminer/README @@ -0,0 +1,6 @@ + +This is a 'getwork' CPU mining client for bitcoin. + +It is pure-python, and therefore very, very slow. The purpose is to +provide a reference implementation of a miner, for study. + diff --git a/contrib/pyminer/example-config.cfg b/contrib/pyminer/example-config.cfg new file mode 100644 index 0000000..103e7c1 --- /dev/null +++ b/contrib/pyminer/example-config.cfg @@ -0,0 +1,32 @@ + +# +# RPC login details +# +host=127.0.0.1 +port=8332 + +rpcuser=myusername +rpcpass=mypass + + +# +# mining details +# + +threads=4 + +# periodic rate for requesting new work, if solution not found +scantime=60 + + +# +# misc. +# + +# not really used right now +logdir=/tmp/pyminer + +# set to 1, to enable hashmeter output +hashmeter=0 + + diff --git a/contrib/pyminer/pyminer.py b/contrib/pyminer/pyminer.py new file mode 100644 index 0000000..2887aba --- /dev/null +++ b/contrib/pyminer/pyminer.py @@ -0,0 +1,252 @@ +#!/usr/bin/python +# +# Copyright (c) 2011 The Bitcoin developers +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. +# + +import time +import json +import pprint +import hashlib +import struct +import re +import base64 +import httplib +import sys +from multiprocessing import Process + +ERR_SLEEP = 15 +MAX_NONCE = 1000000L + +settings = {} +pp = pprint.PrettyPrinter(indent=4) + +class BitcoinRPC: + OBJID = 1 + + def __init__(self, host, port, username, password): + authpair = "%s:%s" % (username, password) + self.authhdr = "Basic %s" % (base64.b64encode(authpair)) + self.conn = httplib.HTTPConnection(host, port, False, 30) + def rpc(self, method, params=None): + self.OBJID += 1 + obj = { 'version' : '1.1', + 'method' : method, + 'id' : self.OBJID } + if params is None: + obj['params'] = [] + else: + obj['params'] = params + self.conn.request('POST', '/', json.dumps(obj), + { 'Authorization' : self.authhdr, + 'Content-type' : 'application/json' }) + + resp = self.conn.getresponse() + if resp is None: + print "JSON-RPC: no response" + return None + + body = resp.read() + resp_obj = json.loads(body) + if resp_obj is None: + print "JSON-RPC: cannot JSON-decode body" + return None + if 'error' in resp_obj and resp_obj['error'] != None: + return resp_obj['error'] + if 'result' not in resp_obj: + print "JSON-RPC: no result in object" + return None + + return resp_obj['result'] + def getblockcount(self): + return self.rpc('getblockcount') + def getwork(self, data=None): + return self.rpc('getwork', data) + +def uint32(x): + return x & 0xffffffffL + +def bytereverse(x): + return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) | + (((x) >> 8) & 0x0000ff00) | ((x) >> 24) )) + +def bufreverse(in_buf): + out_words = [] + for i in range(0, len(in_buf), 4): + word = struct.unpack('@I', in_buf[i:i+4])[0] + out_words.append(struct.pack('@I', bytereverse(word))) + return ''.join(out_words) + +def wordreverse(in_buf): + out_words = [] + for i in range(0, len(in_buf), 4): + out_words.append(in_buf[i:i+4]) + out_words.reverse() + return ''.join(out_words) + +class Miner: + def __init__(self, id): + self.id = id + self.max_nonce = MAX_NONCE + + def work(self, datastr, targetstr): + # decode work data hex string to binary + static_data = datastr.decode('hex') + static_data = bufreverse(static_data) + + # the first 76b of 80b do not change + blk_hdr = static_data[:76] + + # decode 256-bit target value + targetbin = targetstr.decode('hex') + targetbin = targetbin[::-1] # byte-swap and dword-swap + targetbin_str = targetbin.encode('hex') + target = long(targetbin_str, 16) + + # pre-hash first 76b of block header + static_hash = hashlib.sha256() + static_hash.update(blk_hdr) + + for nonce in xrange(self.max_nonce): + + # encode 32-bit nonce value + nonce_bin = struct.pack(" Upstream RPC result:", result + + def iterate(self, rpc): + work = rpc.getwork() + if work is None: + time.sleep(ERR_SLEEP) + return + if 'data' not in work or 'target' not in work: + time.sleep(ERR_SLEEP) + return + + time_start = time.time() + + (hashes_done, nonce_bin) = self.work(work['data'], + work['target']) + + time_end = time.time() + time_diff = time_end - time_start + + self.max_nonce = long( + (hashes_done * settings['scantime']) / time_diff) + if self.max_nonce > 0xfffffffaL: + self.max_nonce = 0xfffffffaL + + if settings['hashmeter']: + print "HashMeter(%d): %d hashes, %.2f Khash/sec" % ( + self.id, hashes_done, + (hashes_done / 1000.0) / time_diff) + + if nonce_bin is not None: + self.submit_work(rpc, work['data'], nonce_bin) + + def loop(self): + rpc = BitcoinRPC(settings['host'], settings['port'], + settings['rpcuser'], settings['rpcpass']) + if rpc is None: + return + + while True: + self.iterate(rpc) + +def miner_thread(id): + miner = Miner(id) + miner.loop() + +if __name__ == '__main__': + if len(sys.argv) != 2: + print "Usage: pyminer.py CONFIG-FILE" + sys.exit(1) + + f = open(sys.argv[1]) + for line in f: + # skip comment lines + m = re.search('^\s*#', line) + if m: + continue + + # parse key=value lines + m = re.search('^(\w+)\s*=\s*(\S.*)$', line) + if m is None: + continue + settings[m.group(1)] = m.group(2) + f.close() + + if 'host' not in settings: + settings['host'] = '127.0.0.1' + if 'port' not in settings: + settings['port'] = 8332 + if 'threads' not in settings: + settings['threads'] = 1 + if 'hashmeter' not in settings: + settings['hashmeter'] = 0 + if 'scantime' not in settings: + settings['scantime'] = 30L + if 'rpcuser' not in settings or 'rpcpass' not in settings: + print "Missing username and/or password in cfg file" + sys.exit(1) + + settings['port'] = int(settings['port']) + settings['threads'] = int(settings['threads']) + settings['hashmeter'] = int(settings['hashmeter']) + settings['scantime'] = long(settings['scantime']) + + thr_list = [] + for thr_id in range(settings['threads']): + p = Process(target=miner_thread, args=(thr_id,)) + p.start() + thr_list.append(p) + time.sleep(1) # stagger threads + + print settings['threads'], "mining threads started" + + print time.asctime(), "Miner Starts - %s:%s" % (settings['host'], settings['port']) + try: + for thr_proc in thr_list: + thr_proc.join() + except KeyboardInterrupt: + pass + print time.asctime(), "Miner Stops - %s:%s" % (settings['host'], settings['port']) + diff --git a/contrib/qt_translations.py b/contrib/qt_translations.py new file mode 100644 index 0000000..fd8a8b7 --- /dev/null +++ b/contrib/qt_translations.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +# Helpful little script that spits out a comma-separated list of +# language codes for Qt icons that should be included +# in binary bitcoin distributions + +import glob +import os +import re +import sys + +if len(sys.argv) != 3: + sys.exit("Usage: %s $QTDIR/translations $BITCOINDIR/src/qt/locale"%sys.argv[0]) + +d1 = sys.argv[1] +d2 = sys.argv[2] + +l1 = set([ re.search(r'qt_(.*).qm', f).group(1) for f in glob.glob(os.path.join(d1, 'qt_*.qm')) ]) +l2 = set([ re.search(r'bitcoin_(.*).qm', f).group(1) for f in glob.glob(os.path.join(d2, 'bitcoin_*.qm')) ]) + +print ",".join(sorted(l1.intersection(l2))) + diff --git a/contrib/wallettools/walletchangepass.py b/contrib/wallettools/walletchangepass.py new file mode 100644 index 0000000..30f3f5b --- /dev/null +++ b/contrib/wallettools/walletchangepass.py @@ -0,0 +1,5 @@ +from jsonrpc import ServiceProxy +access = ServiceProxy("http://127.0.0.1:8332") +pwd = raw_input("Enter old wallet passphrase: ") +pwd2 = raw_input("Enter new wallet passphrase: ") +access.walletpassphrasechange(pwd, pwd2) \ No newline at end of file diff --git a/contrib/wallettools/walletunlock.py b/contrib/wallettools/walletunlock.py new file mode 100644 index 0000000..f847c6f --- /dev/null +++ b/contrib/wallettools/walletunlock.py @@ -0,0 +1,4 @@ +from jsonrpc import ServiceProxy +access = ServiceProxy("http://127.0.0.1:8332") +pwd = raw_input("Enter wallet passphrase: ") +access.walletpassphrase(pwd, 60) \ No newline at end of file diff --git a/doc/Doxyfile b/doc/Doxyfile new file mode 100644 index 0000000..08d4f8c --- /dev/null +++ b/doc/Doxyfile @@ -0,0 +1,1752 @@ +# Doxyfile 1.7.4 + +# !!! Invoke doxygen from project root using: +# doxygen doc/Doxyfile + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Bitcoin + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.5.0 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "P2P Digital Currency" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = doc/bitcoin_logo_doxygen.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/doc/README b/doc/README new file mode 100644 index 0000000..5ef6b5d --- /dev/null +++ b/doc/README @@ -0,0 +1,35 @@ +CasinoCoin 0.6 BETA + +Copyright (c) 2009-2012 Bitcoin Developers +Copyright (c) 2011-2012 Litecoin Developers +Copyright (c) 2013 CasinoCoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file COPYING or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +Intro +----- +CasinoCoin is a free open source peer-to-peer electronic cash system that is +completely decentralized, without the need for a central server or trusted +parties. Users hold the crypto keys to their own money and transact directly +with each other, with the help of a P2P network to check for double-spending. + + +Setup +----- +You need the Qt4 run-time libraries to run CasinoCoin-Qt. On Debian or Ubuntu: + sudo apt-get install libqtgui4 + +Unpack the files into a directory and run: + bin/32/casinocoin-qt (GUI, 32-bit) + bin/32/casinocoind (headless, 32-bit) + bin/64/casinocoin-qt (GUI, 64-bit) + bin/64/casinocoind (headless, 64-bit) + + +See the documentation at the bitcoin wiki: + https://en.bitcoin.it/wiki/Main_Page +for help and more information. diff --git a/doc/README_ScryptMiner.txt b/doc/README_ScryptMiner.txt new file mode 100644 index 0000000..dde1799 --- /dev/null +++ b/doc/README_ScryptMiner.txt @@ -0,0 +1,33 @@ +ScryptMiner-GUI +=== + +A simple GUI for the scrypt-based cpuminer written in C++ using Qt. + +To use, copy the minerd executable to the same directory as the GUI itself, alongside with any needed libraries. +After that, just run the GUI executable. + +=== + +LICENSING INFORMATION + +=== + +Copyright (C) 2011 by Matoking + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/doc/README_windows.txt b/doc/README_windows.txt new file mode 100644 index 0000000..4aa9135 --- /dev/null +++ b/doc/README_windows.txt @@ -0,0 +1,37 @@ +CasinoCoin 0.6 BETA + +Copyright (c) 2009-2012 Bitcoin Developers +Copyright (c) 2011-2012 Litecoin Developers +Copyright (c) 2013 CasinoCoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file COPYING or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +Intro +----- +CasinoCoin is a free open source peer-to-peer electronic cash system that is +completely decentralized, without the need for a central server or trusted +parties. Users hold the crypto keys to their own money and transact directly +with each other, with the help of a P2P network to check for double-spending. + + +Setup +----- +Unpack the files into a directory and run casinocoin-qt.exe. + +If you have Microsoft Security Essentials, you need to add casinocoin-qt.exe to its +"Excluded processes" list. Microsoft Security Essentials->Settings tab, +select Excluded processes, press Add, select casinocoin-qt.exe, OK, Save changes. + +The software automatically finds other nodes to connect to. You can +enable Universal Plug and Play using a menu entry or set your firewall +to forward port 9333 (TCP) to your computer so you can receive +incoming connections. CasinoCoin works without incoming connections, +but allowing incoming connections helps the CasinoCoin network. + +See the bitcoin wiki at: + https://en.bitcoin.it/wiki/Main_Page +for more help and information. diff --git a/doc/Tor.txt b/doc/Tor.txt new file mode 100644 index 0000000..174d354 --- /dev/null +++ b/doc/Tor.txt @@ -0,0 +1,96 @@ +TOR SUPPORT IN BITCOIN +====================== + +It is possible to run Bitcoin as a Tor hidden service, and connect to such services. + +The following assumes you have a Tor proxy running on port 9050. Many distributions +default to having a SOCKS proxy listening on port 9050, but others may not. +In particular, the Tor Browser Bundle defaults to listening on a random port. See +https://www.torproject.org/docs/faq.html.en#TBBSocksPort for how to properly +configure Tor. + + +1. Run bitcoin behind a Tor proxy +--------------------------------- + +The first step is running Bitcoin behind a Tor proxy. This will already make all +outgoing connections be anonimized, but more is possible. + +-socks=5 SOCKS5 supports connecting-to-hostname, which can be used instead + of doing a (leaking) local DNS lookup. SOCKS5 is the default, + but SOCKS4 does not support this. (SOCKS4a does, but isn't + implemented). + +-proxy=ip:port Set the proxy server. If SOCKS5 is selected (default), this proxy + server will be used to try to reach .onion addresses as well. + +-tor=ip:port Set the proxy server to use for tor hidden services. You do not + need to set this if it's the same as -proxy. You can use -notor + to explicitly disable access to hidden service. + +-dnsseed DNS seeds are not resolved directly when a SOCKS5 proxy server is + set. Rather, a short-lived proxy connection to the dns seed + hostname is attempted, and peer addresses are requested. + +-listen When using -proxy, listening is disabled by default. If you want + to run a hidden service (see next section), you'll need to enable + it explicitly. + +-connect=X When behind a Tor proxy, you can specify .onion addresses instead +-addnode=X of IP addresses or hostnames in these parameters. It requires +-seednode=X SOCKS5. In Tor mode, such addresses can also be exchanged with + other P2P nodes. + +In a typical situation, this suffices to run behind a Tor proxy: + + ./bitcoin -proxy=127.0.0.1:9050 + + +2. Run a bitcoin hidden server +------------------------------ + +If you configure your Tor system accordingly, it is possible to make your node also +reachable from the Tor network. Add these lines to your /etc/tor/torrc (or equivalent +config file): + + HiddenServiceDir /var/lib/tor/bitcoin-service/ + HiddenServicePort 9333 127.0.0.1:9333 + +The directory can be different of course, but (both) 9333's should be equal to your +bitcoind's P2P listen port (9333 by default). + +-externalip=X You can tell bitcoin about its publicly reachable address using + this option, and this can be a .onion address. Given the above + configuration, you can find your onion address in + /var/lib/tor/bitcoin-service/hostname. Onion addresses are given + preference for your node to advertize itself with, for connections + coming from unroutable addresses (such as 127.0.0.1, where the + Tor proxy typically runs). + +-listen You'll need to enable listening for incoming connections, as this + is off by default behind a proxy. + +-discover When -externalip is specified, no attempt is made to discover local + IPv4 or IPv6 addresses. If you want to run a dual stack, reachable + from both Tor and IPv4 (or IPv6), you'll need to either pass your + other addresses using -externalip, or explicitly enable -discover. + Note that both addresses of a dual-stack system may be easily + linkable using traffic analysis. + +In a typical situation, where you're only reachable via Tor, this should suffice: + + ./bitcoind -proxy=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -listen + +(obviously replace the Onion address with your own). If you don't care too much +about hiding your node, and want to be reachable on IPv4 as well, additionally +specify: + + ./bitcoind ... -discover + +and open port 9333 on your firewall (or use -upnp). + +If you only want to use Tor to reach onion addresses, but not use it as a proxy +for normal IPv4/IPv6 communication, use: + + ./bitcoin -tor=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -discover + diff --git a/doc/assets-attribution.txt b/doc/assets-attribution.txt new file mode 100644 index 0000000..e5936ee --- /dev/null +++ b/doc/assets-attribution.txt @@ -0,0 +1,60 @@ +Code: src/strlcpy.h +Author: Todd C. Miller +License: ISC + +Icon: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png, + src/qt/res/src/*.svg +Designer: Wladimir van der Laan +License: MIT + +Icon: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png, + src/qt/res/icons/history.png, src/qt/res/icons/key.png, + src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png, + src/qt/res/icons/receive.png, src/qt/res/icons/send.png, + src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png +Icon Pack: NUVOLA ICON THEME for KDE 3.x +Designer: David Vignoni (david@icon-king.com) + ICON KING - www.icon-king.com +License: LGPL +Site: http://www.icon-king.com/projects/nuvola/ + +Icon: src/qt/res/icons/connect*.png +Icon Pack: Human-O2 +Designer: schollidesign +License: GNU/GPL +Site: http://findicons.com/icon/93743/blocks_gnome_netstatus_0 + +Icon: src/qt/res/icons/transaction*.png +Designer: md2k7 +Site: https://bitcointalk.org/index.php?topic=15276.0 +License: You are free to do with these icons as you wish, including selling, + copying, modifying etc. + +Icon: src/qt/res/icons/configure.png, src/qt/res/icons/quit.png, + src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png, + src/qt/res/icons/add.png, src/qt/res/icons/edit.png, + src/qt/res/icons/remove.png (edited) +Designer: http://www.everaldo.com +Icon Pack: Crystal SVG +License: LGPL + +Icon: src/qt/res/icons/bitcoin.png, src/qt/res/icons/toolbar.png +Designer: BitcoinPorn (forum) +License: Public Domain +Site: https://bitcointalk.org/index.php?topic=47417.msg591988#msg591988 + +Icon: scripts/img/reload.xcf (modified),src/qt/res/movies/update_spinner.mng +Icon Pack: Kids +Designer: Everaldo (Everaldo Coelho) +License: GNU/GPL +Site: http://findicons.com/icon/17102/reload?id=17102 + +Image: src/qt/res/images/splash2.jpg (Wallet image) +Designer: Crobbo (forum), adapted to CasinoCoin by BitcoinPorn (forum) +Site: https://bitcointalk.org/index.php?topic=32273.0, https://bitcointalk.org/index.php?topic=47417.msg591988#msg591988 +License: Public domain + +Icon: src/qt/res/icons/debugwindow.png +Designer: Vignoni David +Site: http://www.oxygen-icons.org/ +License: Oxygen icon theme is dual licensed. You may copy it under the Creative Common Attribution-ShareAlike 3.0 License or the GNU Library General Public License. diff --git a/doc/bitcoin_logo_doxygen.png b/doc/bitcoin_logo_doxygen.png new file mode 100644 index 0000000..5b41b02 Binary files /dev/null and b/doc/bitcoin_logo_doxygen.png differ diff --git a/doc/build-msw.txt b/doc/build-msw.txt new file mode 100644 index 0000000..a312cdf --- /dev/null +++ b/doc/build-msw.txt @@ -0,0 +1,86 @@ +Copyright (c) 2009-2012 Bitcoin Developers +Copyright (c) 2011-2012 Litecoin Developers +Copyright (c) 2013 CasinoCoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file COPYING or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP +software written by Thomas Bernard. + + +See readme-qt.rst for instructions on building CasinoCoin-QT, the +graphical user interface. + +WINDOWS BUILD NOTES +=================== + +Compilers Supported +------------------- +TODO: What works? +Note: releases are cross-compiled using mingw running on Linux. + + +Dependencies +------------ +Libraries you need to download separately and build: + + default path download +OpenSSL \openssl-1.0.1b-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/ + +Their licenses: +OpenSSL Old BSD license with the problematic advertising requirement +Berkeley DB New BSD license with additional requirement that linked software must be free open source +Boost MIT-like license +miniupnpc New (3-clause) BSD license + +Versions used in this release: +OpenSSL 1.0.1b +Berkeley DB 4.8.30.NC +Boost 1.47.0 +miniupnpc 1.6 + + +OpenSSL +------- +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 +./config +make + +Berkeley DB +----------- +MSYS shell: +cd /c/db-4.8.30.NC-mgw/build_unix +sh ../dist/configure --enable-mingw --enable-cxx +make + +Boost +----- +DOS prompt: +downloaded boost jam 3.1.18 +cd \boost-1.47.0-mgw +bjam toolset=gcc --build-type=complete stage + +MiniUPnPc +--------- +UPnP support is optional, make with USE_UPNP= to disable it. + +MSYS shell: +cd /c/miniupnpc-1.6-mgw +make -f Makefile.mingw +mkdir miniupnpc +cp *.h miniupnpc/ + +CasinoCoin +------- +DOS prompt: +cd \casinocoin\src +mingw32-make -f makefile.mingw +strip casinocoind.exe diff --git a/doc/build-osx.txt b/doc/build-osx.txt new file mode 100644 index 0000000..cc7fa1c --- /dev/null +++ b/doc/build-osx.txt @@ -0,0 +1,56 @@ +Copyright (c) 2009-2012 Bitcoin Developers +Copyright (c) 2011-2012 Litecoin Developers +Copyright (c) 2013 CasinoCoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file COPYING or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP +software written by Thomas Bernard. + + +Mac OS X casinocoind build instructions +Laszlo Hanyecz +Douglas Huff + + +See readme-qt.rst for instructions on building CasinoCoin-QT, the +graphical user interface. + +Tested on 10.5, 10.6 and 10.7 intel. PPC is not supported because it's big-endian. + +All of the commands should be executed in Terminal.app.. it's in +/Applications/Utilities + +You need to install XCode with all the options checked so that the compiler and +everything is available in /usr not just /Developer. XCode should be available on your OS X +install DVD, but if not, you can get the current version from https://developer.apple.com/xcode/ + + +1. Clone the github tree to get the source code: + +git clone git@github.com:casinocoin-project/casinocoin.git casinocoin + +2. Download and install MacPorts from http://www.macports.org/ + +2a. (for 10.7 Lion) + Edit /opt/local/etc/macports/macports.conf and uncomment "build_arch i386" + +3. Install dependencies from MacPorts + +sudo port install boost db48 openssl miniupnpc + +Optionally install qrencode (and set USE_QRCODE=1): +sudo port install qrencode + +4. Now you should be able to build casinocoind: + +cd casinocoin/src +make -f makefile.osx USE_IPV6=1 + +Run: + ./casinocoind --help # for a list of command-line options. +Run + ./casinocoind -daemon # to start the casinocoin daemon. +Run + ./casinocoind help # When the daemon is running, to get a list of RPC commands diff --git a/doc/build-unix.txt b/doc/build-unix.txt new file mode 100644 index 0000000..a3c8d7c --- /dev/null +++ b/doc/build-unix.txt @@ -0,0 +1,157 @@ +Copyright (c) 2009-2012 Bitcoin Developers +Copyright (c) 2011-2012 Litecoin Developers +Copyright (c) 2013 CasinoCoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file COPYING or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP +software written by Thomas Bernard. + + +UNIX BUILD NOTES +================ + +To Build +-------- + +cd src/ +make -f makefile.unix # Headless casinocoin + +See readme-qt.rst for instructions on building CasinoCoin-Qt, +the graphical user interface. + +Dependencies +------------ + + Library Purpose Description + ------- ------- ----------- + libssl SSL Support Secure communications + libdb4.8 Berkeley DB Blockchain & wallet storage + libboost Boost C++ Library + miniupnpc UPnP Support Optional firewall-jumping support + libqrencode QRCode generation Optional QRCode generation + +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=0 (the default) UPnP support turned off by default at runtime + USE_UPNP=1 UPnP support turned on by default at runtime + +libqrencode may be used for QRCode image generation. It can be downloaded +from http://fukuchi.org/works/qrencode/index.html.en, or installed via +your package manager. Set USE_QRCODE to control this: + USE_QRCODE=0 (the default) No QRCode support - libqrcode not required + USE_QRCODE=1 QRCode support enabled + +IPv6 support may be enabled by setting + USE_IPV6=1 Enable IPv6 support + +Licenses of statically linked libraries: + Berkeley DB New BSD license with additional requirement that linked + software must be free open source + Boost MIT-like license + miniupnpc New (3-clause) BSD license + +Versions used in this release: + GCC 4.3.3 + OpenSSL 0.9.8g + Berkeley DB 4.8.30.NC + Boost 1.37 + miniupnpc 1.6 + +Dependency Build Instructions: Ubuntu & Debian +---------------------------------------------- +sudo apt-get install build-essential +sudo apt-get install libssl-dev +sudo apt-get install libdb4.8-dev +sudo apt-get install libdb4.8++-dev + Boost 1.40+: sudo apt-get install libboost-all-dev + or Boost 1.37: sudo apt-get install libboost1.37-dev +sudo apt-get install libqrencode-dev + +If using Boost 1.37, append -mt to the boost libraries in the makefile. + + +Dependency Build Instructions: Gentoo +------------------------------------- + +emerge -av1 --noreplace boost glib openssl sys-libs/db:4.8 + +Take the following steps to build (no UPnP support): + cd ${CASINOCOIN_DIR}/src + make -f makefile.unix USE_UPNP= USE_IPV6=1 BDB_INCLUDE_PATH='/usr/include/db4.8' + strip casinocoind + + +Notes +----- +The release is built with GCC and then "strip casinocoind" to strip the debug +symbols, which reduces the executable size by about 90%. + + +miniupnpc +--------- +tar -xzvf miniupnpc-1.6.tar.gz +cd miniupnpc-1.6 +make +sudo su +make install + + +Berkeley DB +----------- +You need Berkeley DB 4.8. If you have to build Berkeley DB yourself: +../dist/configure --enable-cxx +make + + +Boost +----- +If you need to build Boost yourself: +sudo su +./bootstrap.sh +./bjam install + + +Security +-------- +To help make your casinocoin installation more secure by making certain attacks impossible to +exploit even if a vulnerability is found, you can take the following measures: + +* Position Independent Executable + Build position independent code to take advantage of Address Space Layout Randomization + offered by some kernels. An attacker who is able to cause execution of code at an arbitrary + memory location is thwarted if he doesn't know where anything useful is located. + The stack and heap are randomly located by default but this allows the code section to be + randomly located as well. + + On an Amd64 processor where a library was not compiled with -fPIC, this will cause an error + such as: "relocation R_X86_64_32 against `......' can not be used when making a shared object;" + + To build with PIE, use: + make -f makefile.unix ... -e PIE=1 + + To test that you have built PIE executable, install scanelf, part of paxutils, and use: + scanelf -e ./casinocoin + + The output should contain: + TYPE + ET_DYN + +* Non-executable Stack + If the stack is executable then trivial stack based buffer overflow exploits are possible if + vulnerable buffers are found. By default, casinocoin should be built with a non-executable stack + but if one of the libraries it uses asks for an executable stack or someone makes a mistake + and uses a compiler extension which requires an executable stack, it will silently build an + executable without the non-executable stack protection. + + To verify that the stack is non-executable after compiling use: + scanelf -e ./casinocoin + + the output should contain: + STK/REL/PTL + RW- R-- RW- + + The STK RW- means that the stack is readable and writeable but not executable. diff --git a/doc/coding.txt b/doc/coding.txt new file mode 100644 index 0000000..c81dbf6 --- /dev/null +++ b/doc/coding.txt @@ -0,0 +1,99 @@ +Please be consistent with the existing coding style. + +Block style: + +bool Function(char* psz, int n) +{ + // Comment summarising what this section of code does + for (int i = 0; i < n; i++) + { + // When something fails, return early + if (!Something()) + return false; + ... + } + + // Success return is usually at the end + return true; +} + +- ANSI/Allman block style +- 4 space indenting, no tabs +- No extra spaces inside parenthesis; please don't do ( this ) +- No space after function names, one space after if, for and while + +Variable names begin with the type in lowercase, like nSomeVariable. +Please don't put the first word of the variable name in lowercase like +someVariable. + +Common types: +n integer number: short, unsigned short, int, unsigned int, + int64, uint64, sometimes char if used as a number +d double, float +f flag +hash uint256 +p pointer or array, one p for each level of indirection +psz pointer to null terminated string +str string object +v vector or similar list objects +map map or multimap +set set or multiset +bn CBigNum + +------------------------- +Locking/mutex usage notes + +The code is multi-threaded, and uses mutexes and the +CRITICAL_BLOCK/TRY_CRITICAL_BLOCK macros to protect data structures. + +Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main +and then cs_wallet, while thread 2 locks them in the opposite order: +result, deadlock as each waits for the other to release its lock) are +a problem. Compile with -DDEBUG_LOCKORDER to get lock order +inconsistencies reported in the debug.log file. + +Re-architecting the core code so there are better-defined interfaces +between the various components is a goal, with any necessary locking +done by the components (e.g. see the self-contained CKeyStore class +and its cs_KeyStore lock for example). + +------- +Threads + +StartNode : Starts other threads. + +ThreadGetMyExternalIP : Determines outside-the-firewall IP address, +sends addr message to connected peers when it determines it. + +ThreadIRCSeed : Joins IRC bootstrapping channel, watching for new +peers and advertising this node's IP address. + +ThreadSocketHandler : Sends/Receives data from peers on port 9333. + +ThreadMessageHandler : Higher-level message handling (sending and +receiving). + +ThreadOpenConnections : Initiates new connections to peers. + +ThreadTopUpKeyPool : replenishes the keystore's keypool. + +ThreadCleanWalletPassphrase : re-locks an encrypted wallet after user +has unlocked it for a period of time. + +SendingDialogStartTransfer : used by pay-via-ip-address code (obsolete) + +ThreadDelayedRepaint : repaint the gui + +ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used +in 500ms. + +ThreadRPCServer : Remote procedure call handler, listens on port 9332 +for connections and services them. + +ThreadBitcoinMiner : Generates casinocoins + +ThreadMapPort : Universal plug-and-play startup/shutdown + +Shutdown : Does an orderly shutdown of everything + +ExitTimeout : Windows-only, sleeps 5 seconds then exits application diff --git a/doc/readme-qt.rst b/doc/readme-qt.rst new file mode 100644 index 0000000..4370335 --- /dev/null +++ b/doc/readme-qt.rst @@ -0,0 +1,152 @@ +CasinoCoin-Qt: Qt4 GUI for CasinoCoin +================================ + +Build instructions +=================== + +Debian +------- + +First, make sure that the required packages for Qt4 development of your +distribution are installed, for Debian and Ubuntu these are: + +:: + + apt-get install qt4-qmake libqt4-dev build-essential libboost-dev libboost-system-dev \ + libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \ + libssl-dev libdb4.8++-dev + +then execute the following: + +:: + + qmake + make + +Alternatively, install `Qt Creator`_ and open the `casinocoin-qt.pro` file. + +An executable named `casinocoin-qt` will be built. + +.. _`Qt Creator`: http://qt.nokia.com/downloads/ + +Windows +-------- + +Windows build instructions: + +- Download the `Qt Windows SDK`_ and install it. You don't need the Symbian stuff, just the desktop Qt. + +- Download and extract the `dependencies archive`_ [#]_, or compile openssl, boost and dbcxx yourself. + +- Copy the contents of the folder "deps" to "X:\\QtSDK\\mingw", replace X:\\ with the location where you installed the Qt SDK. Make sure that the contents of "deps\\include" end up in the current "include" directory. + +- Open the bitcoin-qt.pro file in Qt Creator and build as normal (ctrl-B) + +.. _`Qt Windows SDK`: http://qt.nokia.com/downloads/sdk-windows-cpp +.. _`dependencies archive`: https://download.visucore.com/bitcoin/qtgui_deps_1.zip +.. [#] PGP signature: https://download.visucore.com/bitcoin/qtgui_deps_1.zip.sig (signed with RSA key ID `610945D0`_) +.. _`610945D0`: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x610945D0 + + +Mac OS X +-------- + +- Download and install the `Qt Mac OS X SDK`_. It is recommended to also install Apple's Xcode with UNIX tools. + +- Download and install `MacPorts`_. + +- Execute the following commands in a terminal to get the dependencies: + +:: + + sudo port selfupdate + sudo port install boost db48 miniupnpc + +- Open the bitcoin-qt.pro file in Qt Creator and build as normal (cmd-B) + +.. _`Qt Mac OS X SDK`: http://qt.nokia.com/downloads/sdk-mac-os-cpp +.. _`MacPorts`: http://www.macports.org/install.php + + +Build configuration options +============================ + +UPnP port forwarding +--------------------- + +To use UPnP for port forwarding behind a NAT router (recommended, as more connections overall allow for a faster and more stable casinocoin experience), pass the following argument to qmake: + +:: + + qmake "USE_UPNP=1" + +(in **Qt Creator**, you can find the setting for additional qmake arguments under "Projects" -> "Build Settings" -> "Build Steps", then click "Details" next to **qmake**) + +This requires miniupnpc for UPnP port mapping. It can be downloaded from +http://miniupnp.tuxfamily.org/files/. UPnP support is not compiled in by default. + +Set USE_UPNP to a different value to control this: + ++------------+--------------------------------------------------------------------------+ +| USE_UPNP=- | no UPnP support, miniupnpc not required; | ++------------+--------------------------------------------------------------------------+ +| USE_UPNP=0 | (the default) built with UPnP, support turned off by default at runtime; | ++------------+--------------------------------------------------------------------------+ +| USE_UPNP=1 | build with UPnP support turned on by default at runtime. | ++------------+--------------------------------------------------------------------------+ + +Notification support for recent (k)ubuntu versions +--------------------------------------------------- + +To see desktop notifications on (k)ubuntu versions starting from 10.04, enable usage of the +FreeDesktop notification interface through DBUS using the following qmake option: + +:: + + qmake "USE_DBUS=1" + +Generation of QR codes +----------------------- + +libqrencode may be used to generate QRCode images for payment requests. +It can be downloaded from http://fukuchi.org/works/qrencode/index.html.en, or installed via your package manager. Pass the USE_QRCODE +flag to qmake to control this: + ++--------------+--------------------------------------------------------------------------+ +| USE_QRCODE=0 | (the default) No QRCode support - libarcode not required | ++--------------+--------------------------------------------------------------------------+ +| USE_QRCODE=1 | QRCode support enabled | ++--------------+--------------------------------------------------------------------------+ + + +Berkely DB version warning +========================== + +A warning for people using the *static binary* version of CasinoCoin on a Linux/UNIX-ish system (tl;dr: **Berkely DB databases are not forward compatible**). + +The static binary version of CasinoCoin is linked against libdb4.8 (see also `this Debian issue`_). + +Now the nasty thing is that databases from 5.X are not compatible with 4.X. + +If the globally installed development package of Berkely DB installed on your system is 5.X, any source you +build yourself will be linked against that. The first time you run with a 5.X version the database will be upgraded, +and 4.X cannot open the new format. This means that you cannot go back to the old statically linked version without +significant hassle! + +.. _`this Debian issue`: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=621425 + +Ubuntu 11.10 warning +==================== + +Ubuntu 11.10 has a package called 'qt-at-spi' installed by default. At the time of writing, having that package +installed causes casinocoin-qt to crash intermittently. The issue has been reported as `launchpad bug 857790`_, but +isn't yet fixed. + +Until the bug is fixed, you can remove the qt-at-spi package to work around the problem, though this will presumably +disable screen reader functionality for Qt apps: + +:: + + sudo apt-get remove qt-at-spi + +.. _`launchpad bug 857790`: https://bugs.launchpad.net/ubuntu/+source/qt-at-spi/+bug/857790 diff --git a/doc/release-process.txt b/doc/release-process.txt new file mode 100644 index 0000000..ffb1ea4 --- /dev/null +++ b/doc/release-process.txt @@ -0,0 +1,143 @@ +* update translations (ping tcatm on IRC for now) + +* update (commit) version in sources + bitcoin-qt.pro + src/version.h + share/setup.nsi + doc/README* + +* tag version in git + + git tag -a v0.5.1 + +* write release notes. git shortlog helps a lot: + + git shortlog --no-merges v0.5.0.. + +* perform gitian builds + + * From a directory containing the casinocoin source, gitian-builder and gitian.sigs + export SIGNER=(your gitian key, ie bluematt, sipa, etc) + export VERSION=0.5.1 + cd ./gitian-builder + + * Fetch and build inputs: + mkdir -p inputs; cd inputs/ + wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.6.tar.gz' -O miniupnpc-1.6.tar.gz + wget 'http://www.openssl.org/source/openssl-1.0.1b.tar.gz' + wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' + wget 'http://zlib.net/zlib-1.2.7.tar.gz' + wget 'ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng-1.5.12.tar.gz' + wget 'http://fukuchi.org/works/qrencode/qrencode-3.2.0.tar.bz2' + wget 'http://downloads.sourceforge.net/project/boost/boost/1.47.0/boost_1_47_0.tar.bz2' + wget 'http://download.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.7.4.tar.gz' + cd .. + ./bin/gbuild ../casinocoin/contrib/gitian-descriptors/boost-win32.yml + cp build/out/boost-win32-1.47.0-gitian.zip inputs/ + ./bin/gbuild ../casinocoin/contrib/gitian-descriptors/qt-win32.yml + cp build/out/qt-win32-4.7.4-gitian.zip inputs/ + ./bin/gbuild ../casinocoin/contrib/gitian-descriptors/deps-win32.yml + cp build/out/casinocoin-deps-0.0.3.zip inputs/ + + * Build casinocoind and casinocoin-qt on Linux32, Linux64, and Win32: + ./bin/gbuild --commit casinocoin=v${VERSION} ../casinocoin/contrib/gitian-descriptors/gitian.yml + ./bin/gsign --signer $SIGNER --release ${VERSION} --destination ../gitian.sigs/ ../casinocoin/contrib/gitian-descriptors/gitian.yml + pushd build/out + zip -r casinocoin-${VERSION}-linux-gitian.zip * + mv casinocoin-${VERSION}-linux-gitian.zip ../../ + popd + ./bin/gbuild --commit casinocoin=v${VERSION} ../casinocoin/contrib/gitian-descriptors/gitian-win32.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-win32 --destination ../gitian.sigs/ ../casinocoin/contrib/gitian-descriptors/gitian-win32.yml + pushd build/out + zip -r casinocoin-${VERSION}-win32-gitian.zip * + mv casinocoin-${VERSION}-win32-gitian.zip ../../ + popd + + Build output expected: + 1. linux 32-bit and 64-bit binaries + source (casinocoin-${VERSION}-linux-gitian.zip) + 2. windows 32-bit binary, installer + source (casinocoin-${VERSION}-win32-gitian.zip) + 3. Gitian signatures (in gitian.sigs/${VERSION}[-win32]/(your gitian key)/ + +* repackage gitian builds for release as stand-alone zip/tar/installer exe + + * Linux .tar.gz: + unzip casinocoin-${VERSION}-linux-gitian.zip -d casinocoin-${VERSION}-linux + tar czvf casinocoin-${VERSION}-linux.tar.gz casinocoin-${VERSION}-linux + rm -rf casinocoin-${VERSION}-linux + + * Windows .zip and setup.exe: + unzip casinocoin-${VERSION}-win32-gitian.zip -d casinocoin-${VERSION}-win32 + mv casinocoin-${VERSION}-win32/casinocoin-*-setup.exe . + zip -r casinocoin-${VERSION}-win32.zip casinocoin-${VERSION}-win32 + rm -rf casinocoin-${VERSION}-win32 + +* perform Mac build + See this blog post for how Gavin set up his build environment to build the OSX + release; note that a patched version of macdeployqt is not needed anymore, as + the required functionality and fixes are implemented directly in macdeployqtplus: + http://gavintech.blogspot.com/2011/11/deploying-bitcoin-qt-on-osx.html + Gavin also had trouble with the macports py27-appscript package; he + ended up installing a version that worked with: /usr/bin/easy_install-2.7 appscript + + qmake RELEASE=1 USE_UPNP=1 USE_QRCODE=1 bitcoin-qt.pro + make + export QTDIR=/opt/local/share/qt4 # needed to find translations/qt_*.qm files + T=$(contrib/qt_translations.py $QTDIR/translations src/qt/locale) + python2.7 contrib/macdeploy/macdeployqtplus CasinoCoin-Qt.app -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist + + Build output expected: + CasinoCoin-Qt.dmg + +* upload builds to SourceForge + +* create SHA256SUMS for builds, and PGP-sign it + +* update bitcoin.org version + make sure all OS download links go to the right versions + +* update forum version + +* 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} + git add ${VERSION}-win32/${SIGNER} + git commit -a + git push # Assuming you can push to the gitian.sigs tree + popd + +------------------------------------------------------------------------- + +* After 3 or more people have gitian-built, repackage gitian-signed zips: + + * From a directory containing bitcoin source, gitian.sigs and gitian zips + export VERSION=0.5.1 + mkdir bitcoin-${VERSION}-linux-gitian + pushd bitcoin-${VERSION}-linux-gitian + unzip ../bitcoin-${VERSION}-linux-gitian.zip + mkdir gitian + cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/ + for signer in $(ls ../gitian.sigs/${VERSION}/); do + cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert + cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig + done + zip -r bitcoin-${VERSION}-linux-gitian.zip * + cp bitcoin-${VERSION}-linux-gitian.zip ../ + popd + mkdir bitcoin-${VERSION}-win32-gitian + pushd bitcoin-${VERSION}-win32-gitian + unzip ../bitcoin-${VERSION}-win32-gitian.zip + mkdir gitian + cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/ + for signer in $(ls ../gitian.sigs/${VERSION}-win32/); do + cp ../gitian.sigs/${VERSION}-win32/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert + cp ../gitian.sigs/${VERSION}-win32/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig + done + zip -r bitcoin-${VERSION}-win32-gitian.zip * + cp bitcoin-${VERSION}-win32-gitian.zip ../ + popd + + * Upload gitian zips to SourceForge diff --git a/doc/translation_process.md b/doc/translation_process.md new file mode 100644 index 0000000..c483020 --- /dev/null +++ b/doc/translation_process.md @@ -0,0 +1,103 @@ +Translations +============ + +The Qt GUI can be easily translated into other languages. Here's how we +handle those translations. + +Files and Folders +----------------- + +### bitcoin-qt.pro + +This file takes care of generating `.qm` files from `.ts` files. It is mostly +automated. + +### src/qt/bitcoin.qrc + +This file must be updated whenever a new translation is added. Please note that +files must end with `.qm`, not `.ts`. + + + locale/bitcoin_en.qm + ... + + +### src/qt/locale/ + +This directory contains all translations. Filenames must adhere to this format: + + bitcoin_xx_YY.ts or bitcoin_xx.ts + +#### bitcoin_en.ts (Source file) + +`src/qt/locale/bitcoin_en.ts` is treated in a special way. It is used as the +source for all other translations. Whenever a string in the code is changed +this file must be updated to reflect those changes. This can be accomplished +by running `lupdate` (included in the Qt SDK). Also, a custom script is used +to extract strings from the non-Qt parts: + + python share/qt/extract_strings_qt.py + lupdate bitcoin-qt.pro -no-obsolete -locations none -ts src/qt/locale/bitcoin_en.ts + +##### Handling of plurals in the source file + +When new plurals are added to the source file, it's important to do the following steps: + +1. Open bitcoin_en.ts in Qt Linguist (also included in the Qt SDK) +2. Search for `%n`, which will take you to the parts in the translation that use plurals +3. Look for empty `English Translation (Singular)` and `English Translation (Plural)` fields +4. Add the appropriate strings for the singular and plural form of the base string +5. Mark the item as done (via the green arrow symbol in the toolbar) +6. Repeat from step 2. until all singular and plural forms are in the source file +7. Save the source file + +##### Creating the pull-request + +An updated source file should be merged to github and Transifex will pick it +up from there (can take some hours). Afterwards the new strings show up as "Remaining" +in Transifex and can be translated. + +To create the pull-request you have to do: + + git add src/qt/bitcoinstrings.cpp src/qt/locale/bitcoin_en.ts + git commit + +Syncing with Transifex +---------------------- + +We are using https://transifex.com as a frontend for translating the client. + +https://www.transifex.com/projects/p/bitcoin/resource/tx/ + +The "Transifex client" (see: http://help.transifex.com/features/client/) +will help with fetching new translations from Transifex. Use the following +config to be able to connect with the client: + +### .tx/config + + [main] + host = https://www.transifex.com + + [bitcoin.tx] + file_filter = src/qt/locale/bitcoin_.ts + source_file = src/qt/locale/bitcoin_en.ts + source_lang = en + +### .tx/config (for Windows) + + [main] + host = https://www.transifex.com + + [bitcoin.tx] + file_filter = src\qt\locale\bitcoin_.ts + source_file = src\qt\locale\bitcoin_en.ts + source_lang = en + +It is also possible to directly download new translations one by one from the Transifex website. + +### Fetching new translations + +1. `tx pull -a` +2. update `src/qt/bitcoin.qrc` manually or via + `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/locale/\1.qm<\/file>/'` +3. `git add` new translations from `src/qt/locale/` diff --git a/doc/unit-tests.txt b/doc/unit-tests.txt new file mode 100644 index 0000000..f76970d --- /dev/null +++ b/doc/unit-tests.txt @@ -0,0 +1,33 @@ +Compiling/running 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. diff --git a/share/genbuild.sh b/share/genbuild.sh new file mode 100644 index 0000000..d959877 --- /dev/null +++ b/share/genbuild.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +if [ $# -gt 0 ]; then + FILE="$1" + shift + if [ -f "$FILE" ]; then + INFO="$(head -n 1 "$FILE")" + fi +else + echo "Usage: $0 " + exit 1 +fi + +if [ -e "$(which git)" ]; then + # clean 'dirty' status of touched files that haven't been modified + git diff >/dev/null 2>/dev/null + + # get a string like "v0.6.0-66-g59887e8-dirty" + DESC="$(git describe --dirty 2>/dev/null)" + + # get a string like "2012-04-10 16:27:19 +0200" + TIME="$(git log -n 1 --format="%ci")" +fi + +if [ -n "$DESC" ]; then + NEWINFO="#define BUILD_DESC \"$DESC\"" +else + NEWINFO="// No build information available" +fi + +# only update build.h if necessary +if [ "$INFO" != "$NEWINFO" ]; then + echo "$NEWINFO" >"$FILE" + echo "#define BUILD_DATE \"$TIME\"" >>"$FILE" +fi diff --git a/share/pixmaps/addressbook16.bmp b/share/pixmaps/addressbook16.bmp new file mode 100644 index 0000000..c557691 Binary files /dev/null and b/share/pixmaps/addressbook16.bmp differ diff --git a/share/pixmaps/addressbook16mask.bmp b/share/pixmaps/addressbook16mask.bmp new file mode 100644 index 0000000..d3a478d Binary files /dev/null and b/share/pixmaps/addressbook16mask.bmp differ diff --git a/share/pixmaps/addressbook20.bmp b/share/pixmaps/addressbook20.bmp new file mode 100644 index 0000000..2b33b22 Binary files /dev/null and b/share/pixmaps/addressbook20.bmp differ diff --git a/share/pixmaps/addressbook20mask.bmp b/share/pixmaps/addressbook20mask.bmp new file mode 100644 index 0000000..56ce612 Binary files /dev/null and b/share/pixmaps/addressbook20mask.bmp differ diff --git a/share/pixmaps/bitcoin-bc.ico b/share/pixmaps/bitcoin-bc.ico new file mode 100644 index 0000000..476045c Binary files /dev/null and b/share/pixmaps/bitcoin-bc.ico differ diff --git a/share/pixmaps/bitcoin.ico b/share/pixmaps/bitcoin.ico new file mode 100644 index 0000000..8b12f82 Binary files /dev/null and b/share/pixmaps/bitcoin.ico differ diff --git a/share/pixmaps/bitcoin32.xpm b/share/pixmaps/bitcoin32.xpm new file mode 100644 index 0000000..6d2f9fa --- /dev/null +++ b/share/pixmaps/bitcoin32.xpm @@ -0,0 +1,112 @@ +/* XPM */ +static char * bitcoin32_xpm[] = { +"32 32 77 1", +" c None", +". c #A2A1A1", +"+ c #A1A1A1", +"@ c #A1A0A0", +"# c #9F9F9F", +"$ c #A7A7A7", +"% c #A9A9A9", +"& c #AEAEAE", +"* c #B0B0B0", +"= c #B1B1B1", +"- c #A8A8A8", +"; c #A4A4A4", +"> c #ACACAC", +", c #B2B2B2", +"' c #AAAAAA", +") c #ABABAB", +"! c #A6A6A6", +"~ c #A3A3A3", +"{ c #A8A7A7", +"] c #A5A5A5", +"^ c #ADADAD", +"/ c #9E9E9E", +"( c #ADACAC", +"_ c #A2A2A2", +": c #A0A0A0", +"< c #9D9D9D", +"[ c #A5A4A4", +"} c #9C9C9C", +"| c #9B9B9B", +"1 c #979797", +"2 c #8C8C8C", +"3 c #848484", +"4 c #838383", +"5 c #878787", +"6 c #929292", +"7 c #9A9A9A", +"8 c #AFAFAF", +"9 c #8B8B8B", +"0 c #7F7F7F", +"a c #808080", +"b c #7E7E7E", +"c c #828282", +"d c #969696", +"e c #939292", +"f c #999999", +"g c #898989", +"h c #8A8A8A", +"i c #888888", +"j c #959595", +"k c #939393", +"l c #909090", +"m c #8D8D8D", +"n c #9D9C9C", +"o c #B4B4B4", +"p c #B6B6B6", +"q c #919090", +"r c #A9A8A8", +"s c #B8B8B8", +"t c #BCBCBC", +"u c #B5B5B5", +"v c #C5C5C5", +"w c #C1C1C1", +"x c #B3B3B3", +"y c #C8C8C8", +"z c #BFBFBF", +"A c #B9B9B9", +"B c #AAA9A9", +"C c #9E9D9D", +"D c #949494", +"E c #919191", +"F c #8E8E8E", +"G c #858585", +"H c #B7B7B7", +"I c #818181", +"J c #989898", +"K c #949393", +"L c #989797", +" ", +" .+@ ", +" #$%&*==*&-; ", +" +>,')'!;~!%%)={ ", +" -*)&'!;+##+~]%^%*/ ", +" ()&'$;_:/<'[ ", +" ^%'!~+#/<}|||}/#+~!%-] ", +" '));_:/<}1234567<<#+~'%# ", +" _&8$_/<}}790aabcd<}&e ", +" *,);:/}% ", +" ]88$_/}<#+fkllmi47_:<}<+!^8j ", +" ^,);:<}<+;}7djkmh;!_/}<#~%>~ ", +" no8$_/<<#_]#:}|fk18';#<}/+!^= ", +" %^);:<}<:]]_]~_:}$p^!+/}<#~%=q ", +" r%$_#<<#_-!!%''%]st,';:/}/+]$# ", +" ;-;:<}<:;)!'^8,u&vwp&$+/}<#~~+ ", +" ]']+/}<:;-~-*=xuxyzu^]+/}<:~]+ ", +" ;>-~#<]+<}<:}f'=*)<^s8-~#<}<:;%)C ", +" !=*%~#<}/dD8=8+jEF2i9d}}/_$&u ", +" ou>]+<}|kD,**#|1DlmG57<:;'x* ", +" BH*%~#<7k<=*8&>%;+/gI7/+$^8+ ", +" :xu>]+<}1-=*8&^%]_:a4|#;',x9 ", +" (p*-~#/<~~_+_+#]~+:/}fJJfJ1dk6}_;'== ", +" +&=>-]_+#/<<<<<#:_;$)8&K ", +" [&u*^-]~+#<%]~+:_;$)8oo=L ", +" L*,Au*>-]]$)&oH,>2 ", +" #*p,o=^)8,8p)f ", +" D:]^=*>_#m ", +" "}; diff --git a/share/pixmaps/bitcoin80.xpm b/share/pixmaps/bitcoin80.xpm new file mode 100644 index 0000000..b8113a7 --- /dev/null +++ b/share/pixmaps/bitcoin80.xpm @@ -0,0 +1,229 @@ +/* XPM */ +static char * bitcoin80_xpm[] = { +"80 80 146 2", +" c None", +". c #C3C3C3", +"+ c #C0C0C0", +"@ c #C0BFBF", +"# c #939292", +"$ c #989898", +"% c #979797", +"& c #949494", +"* c #939393", +"= c #949393", +"- c #959595", +"; c #969595", +"> c #8D8D8D", +", c #A3A2A2", +"' c #8E8D8D", +") c #9D9D9D", +"! c #A9A9A9", +"~ c #ACACAC", +"{ c #AFAFAF", +"] c #B3B3B3", +"^ c #B7B7B7", +"/ c #BBBBBB", +"( c #C1C1C1", +"_ c #C2C2C2", +": c #BEBEBE", +"< c #B2B2B2", +"[ c #ADADAD", +"} c #A4A4A4", +"| c #878686", +"1 c #929191", +"2 c #A7A7A7", +"3 c #9F9F9F", +"4 c #C4C4C4", +"5 c #CACACA", +"6 c #B9B9B9", +"7 c #A0A0A0", +"8 c #A1A1A1", +"9 c #B0B0B0", +"0 c #CDCDCD", +"a c #A3A4A4", +"b c #7F7E7E", +"c c #9D9C9C", +"d c #969696", +"e c #B6B6B6", +"f c #BABABA", +"g c #A5A5A5", +"h c #A2A2A2", +"i c #ABABAB", +"j c #AAAAAA", +"k c #A8A8A8", +"l c #A6A6A6", +"m c #979696", +"n c #CCCCCC", +"o c #AEAEAE", +"p c #A3A3A3", +"q c #828181", +"r c #9B9B9B", +"s c #BCBCBC", +"t c #C5C5C5", +"u c #888888", +"v c #989797", +"w c #9C9C9C", +"x c #BDBDBD", +"y c #8B8B8B", +"z c #848383", +"A c #9B9A9A", +"B c #9E9E9E", +"C c #898888", +"D c #919191", +"E c #838282", +"F c #B4B4B4", +"G c #B1B1B1", +"H c #909090", +"I c #9A9999", +"J c #B5B5B5", +"K c #858383", +"L c #A09F9F", +"M c #9A9A9A", +"N c #999999", +"O c #8C8B8B", +"P c #8E8E8E", +"Q c #868686", +"R c #878787", +"S c #929292", +"T c #898989", +"U c #8A8A8A", +"V c #828282", +"W c #7E7E7E", +"X c #7D7D7D", +"Y c #7C7C7C", +"Z c #818181", +"` c #8F8F8F", +" . c #808080", +".. c #7F7F7F", +"+. c #8D8C8C", +"@. c #848484", +"#. c #8C8C8C", +"$. c #BFBFBF", +"%. c #807E7E", +"&. c #838383", +"*. c #959494", +"=. c #999898", +"-. c #858585", +";. c #A6A7A7", +">. c #7E7D7D", +",. c #C6C6C6", +"'. c #ACABAB", +"). c #B8B8B8", +"!. c #ABAAAA", +"~. c #868585", +"{. c #BCBBBB", +"]. c #7C7B7B", +"^. c #C7C7C7", +"/. c #848282", +"(. c #C8C8C8", +"_. c #9E9D9D", +":. c #C9C9C9", +"<. c #BCBDBD", +"[. c #8B8A8A", +"}. c #817F7F", +"|. c #8A8989", +"1. c #B7B8B8", +"2. c #908F8F", +"3. c #7B7B7B", +"4. c #818080", +"5. c #919090", +"6. c #7A7A7A", +"7. c #8E8C8C", +"8. c #828080", +"9. c #8F8E8E", +"0. c #B1B0B0", +"a. c #C5C4C4", +"b. c #979898", +"c. c #7D7C7C", +"d. c #A9A8A8", +"e. c #B9BABA", +"f. c #807F7F", +"g. c #AAABAB", +"h. c #CACBCB", +"i. c #B0AFAF", +"j. c #AEADAD", +"k. c #959393", +"l. c #888787", +"m. c #858484", +"n. c #CBCBCB", +"o. c #9B9C9C", +" ", +" ", +" ", +" . + @ ", +" # $ $ % & & * = & - ; % # > ", +" , > ' ) ! ~ { ] ^ / + ( _ : / ^ < { [ } * | 1 ", +" * > 2 3 2 4 5 6 ! 7 3 7 8 8 8 8 8 3 3 3 } 9 4 0 6 7 a $ b ", +" c d 7 e f 6 ] g h g ! i i j k 2 l g l 2 ! ! ! g 8 7 i ^ f / [ - 1 ", +" m = 9 j n { ) 2 o { [ ~ i ! k g g } p h p } g 2 ! j i [ [ j 8 3 + ( } k q ", +" r 7 6 s j } i 9 { [ ~ i ! k 2 l } p h h 8 h h } g l 2 k j i [ o ~ 2 } { t j ) u ", +" v h o _ o 3 o 9 { [ ~ j ! k 2 g } p h 8 7 7 3 7 8 8 h p g l 2 k ! i [ [ o k w x ] [ y ", +" * 2 ( < h ~ 9 { o ~ i j k l l } } p h 8 7 7 3 3 3 7 8 8 h p } g l 2 ! j ~ ~ { [ 2 7 4 [ 2 z ", +" A o x 2 g { { o [ i j k l g } p h h 8 7 3 3 B B ) B B 3 7 7 8 h p } g l 2 k j i [ o i 3 ] f , C ", +" D } } _ w i { o ~ i j k l g } p p 8 8 7 7 B B ) ) ) ) ) ) B B 3 7 7 8 h p p g l 2 ! j ~ ~ ~ g 7 ( 2 E ", +" D h F G h [ o ~ i j k l l } p p h 8 8 7 3 3 B B ) w w w w w ) B B B 3 7 8 8 h p } g l 2 ! ! i ~ k 8 : 2 H ", +" I l J ^ h ~ ~ i ! k 2 g } p h h 8 7 3 3 B B B w w ) ) ) ) ) ) ) w ) ) B B 3 3 7 8 h p p g l 2 ! ! i ! w + ! K ", +" * L < i g ~ i ! k l l } } h h 8 7 3 3 B B B ) w w w w r r r r r r w w ) ) B B B 3 7 8 8 h h } g l 2 ! ! k ) 6 p C ", +" 3 F e } o ~ ! l g } p h 8 8 7 3 B B B ) w w r M $ % - & * * * * - d % N r w ) ) ) B B 3 7 8 h h p g g 2 j j 7 ( l E ", +" O p f } { o i k g p h 8 8 3 7 B B ) ) w ) ) r N % * P y u Q Q Q R y > S - $ M r ) ) ) B B 3 3 7 8 8 p p l ! i j r s } T ", +" = j + h 9 { i ! l } h 8 7 3 3 B B ) ) w ) ) w N d H U V W X X X Y X X Z T ` - N r ) w w ) ) B B 3 7 7 8 h g 2 j ~ j g + d ", +" w 8 f 3 9 9 [ j 2 g h 8 7 3 B ) ) ) w ) ) ) ) M d H T .X X W ....W W X Y ..T H d r ) ) ) ) w ) ) B B 3 7 8 p l ! i o 2 j { +. ", +" A 6 [ o < o ~ ! l } 8 8 3 B B ) w w ) ) ) ) w N * y @.Z W X W ......W X X X V #.- M ) ) ) ) ) w w ) B B 3 8 p g 2 ! ~ [ } $.3 %. ", +" % 2 6 p F 9 [ j k g p 8 7 B B ) w ) ) ) w w ) ) $ D #.R &.@.T u R R Q @.&.V W X u * M ) ) w ) ) ) ) ) ) B 3 7 8 p l ! i o o 7 + *. ", +" =.f l < ] { ~ ! l } h 7 3 B ) w ) ) w w ) B B ) $ S > T Q T U U T u R Q -.V ..W Q * r B ) B ) w ) ) ) ) B B 3 8 p g 2 j ~ { ! ~ g u ", +" C o x j F 9 [ i k g p 8 7 3 ) ) ) ) w ) ) B B 3 B $ S ` #.y #.#.#.y U T u Q &.Z ..-.& w 7 B B ) ) w ) ) w ) B 3 7 h p g ! i o 9 } t 1 ", +" ;./ w F ] o ~ ! 2 } h 8 3 B ) w ) ) w B B 3 7 8 ) $ & S ` ` P P P > > y U u @.V Z R d B 7 7 7 3 B ) ) ) ) w ) B 3 8 p g 2 j ~ 9 i [ < >. ", +" ; B 6 ~ F 9 [ i 2 g p 8 7 B B w ) ) w ) B 3 7 8 h ) N - & * * H H H ` ` > #.U Q @.&.y N 8 h 8 8 7 3 ) ) ) ) ) ) ) 3 7 h } g ! ~ o G 3 6 ; ", +" H + k F < { ~ ! l } h 7 3 ) ) w ) ) ) ) 3 7 h p p B M $ $ % - * * S S D ` > y u R -.` B p g } p 8 7 B B w ) ) w ) B 3 8 h g 2 j ~ 9 ~ F h -. ", +" 2 ,.g F 9 [ i 2 g p 8 7 B ) w ) ) w ) ) 7 7 h } p 3 r M N M d d - - & * S H #.U u u - h 2 2 l } 8 7 3 B w ) ) ) w B 3 7 h p l ! i o 9 } . q ", +" % o 2 { < o ~ ! 2 } h 8 3 B ) w ) ) w B B 7 8 p } p 7 ) w w w $ $ % d d - * S P > y #.) 2 j j l g h 8 3 B ) w ) ) w ) B 7 8 p g 2 j ~ 9 } + M ", +" M ^ 7 ] 9 [ i k g p h 7 3 ) w ) ) ) ) B 3 8 h } l p 7 B ) B ) M M N N $ $ d & D ` > * p i [ j k g p h 7 3 ) ) w ) ) ) B 3 8 h } l ! ~ o i g [ ", +" '.v . ! < o ~ ! l } 8 8 3 B ) w ) ) w ) 3 3 8 p g l p 7 3 8 8 3 ) w w r r M $ % & * S r j 9 { [ j 2 g p 7 7 B ) w ) ) w B B 7 8 h g 2 ! ~ { 7 ^ | ", +" & p : o G [ j k g p 8 7 B B w ) ) w ) B 3 7 h } l l } 8 8 h g 8 7 3 B 3 B ) r N $ d d p 9 ] G o j k g p 8 7 3 ) ) ) ) ) ) B 3 7 h } l k i o g ( > ", +" C f i G { i ! l } h 7 3 B ) ) ) ) ) ) 3 7 8 p g k 2 p 8 h } 2 p p h h 8 8 7 B ) w r r ~ J e ] { [ ! 2 g h 8 3 B B w ) ) ) ) B 3 8 p } 2 ! [ j _ N ", +" > ,.3 9 [ i 2 g p h 7 3 ) ) ) ) w ) ) 3 7 h p l ! l p h p g k g g } } } } p 8 8 3 ) h < ).).J G o j k g } h 7 B ) ) w ) w ) B 3 8 h p l ! i i J !.~. ", +" - ,.B o ~ k l } h 8 3 B ) w ) w ) B B 7 8 p g k ! l p } g k ! 2 k k k k 2 2 } l } 7 ! ).s / ^ ] { [ ! 2 } p 8 3 B ) w ) ) w ) B 3 8 p } 2 j ~ 2 {.>. ", +" w + 8 [ i 2 g p h 7 B B w w ) w ) B 3 7 h } l ! j l } } l j ! ! j j i j j ! j i ! } 9 s + x 6 J < o i ! l } 8 7 3 B ) w ) ) ) B 3 7 8 p g 2 i B t ]. ", +" 7 6 } ~ ! l } h 8 3 B ) w ) ) ) ) 3 3 8 p g k j j l } g k i j i ~ ~ [ o o [ G { i ! )._ _ $./ e ] { [ ! 2 g h 8 7 B B ) ) ) ) B B 7 8 h g l j w ^.b ", +" h ] l j 2 g p 8 7 B ) ) ) ) w B B 7 7 h } l ! ~ ! l g 2 j ~ [ [ o { { G G G ^ < ~ { : ,.t ( s 6 J < o i k l } 8 7 3 B ) ) ) ) w B 3 7 h p g ! w t /. ", +" h { 2 ! l } h 8 7 B ) w ) ) w B B 7 8 p g 2 j [ j 2 l k ~ o o { 9 9 < < ] e f J o ^ t 5 (.. $./ e < { ~ ! 2 } h 8 3 B ) w ) ) w ) 3 7 8 p } k ) ( z ", +" _.} ~ j j 2 g p 8 7 3 ) ) ) ) w B B 3 7 h } 2 ! i l g g 2 j o 9 { G < < ] ] e ^ < [ f ,.:.,._ x 6 J G o i k l p 8 7 3 ) ) ) ) w ) B 3 7 h p g ! 3 <.y ", +" 8 g ~ i ~ k g } h 8 3 ) ) ) ) w ) ) 3 7 8 p g k k } h h g 2 o 9 9 9 G < ] ] J ] 9 [ x ^.(.4 $./ ^ F { [ j 2 g h 8 7 B ) ) ) ) w ) B 7 8 h } l j 3 + [. ", +" h { i ~ j 2 } p 8 7 B B w ) ) ) ) B 3 8 h } l g 8 3 7 p l 9 9 9 G G < < < 9 o ~ o $.,.,._ x f J < o i k l } 8 7 3 B ) w ) ) ) ) 3 7 h p g k i 3 ( E ", +" h G i o i k l p h 8 B B ) w ) w ) B B 7 h p g h 3 ) 3 8 ! 9 9 9 < < G G G ~ ! l 9 + t 4 $./ ).] 9 [ ! k g p 8 3 B ) ) ) ) w ) B 3 8 h } l ! ~ B 4 E ", +" 7 e k 9 ~ ! 2 g p 8 3 3 ) ) ) ) w B B 3 8 h } 7 w w ) 3 [ 9 G 9 < G G G i 2 } p 9 $.4 ( x 6 J G o ~ ! l } h 7 7 B ) w ) w ) B B 7 h p l k j [ ) ^.W ", +" M x } < o ~ k l } h 7 3 B ) ) ) ) ) ) B 7 8 8 w M N r B { 9 G G G G 9 9 l h 7 8 9 x ( $./ e ] { [ j k } h 8 3 B B w ) ) ) ) B 3 8 p } l j ~ { B ,.]. ", +" * _ 8 ] 9 ~ j 2 g p 8 7 B B w ) ) w ) B 3 7 3 M $ N M B 9 G G G G 9 { 9 3 3 ) ) i J e J < o i ! l } p 8 3 B B B ) w ) ) ) ) 3 7 h } g k i [ 9 g x }. ", +" |.t 3 J < o ~ ! l } h 8 3 ) ) ) ) ) w B B 3 w $ d d $ 7 9 G G 9 9 { { { M M N % w p } h 7 3 r M N N M r r r ) w w ) ) w ) B 3 8 h } 2 j ~ 9 9 < ~ ", +" | / ! e F 9 [ j k g h h 3 3 B w ) ) ) ) B B N d & d d l < 9 G G { 9 9 ! - % - & S D ` P y y U u T U > D d $ M r ) ) ) ) B 3 7 h p l k i [ G [ ( N ", +" *.g / ] e < o ~ ! l } p 8 3 B w ) ) ) ) B ) $ & * & * o G G 9 9 9 { 9 w S * S D P > y U T T R -.&.Z Z R P * $ r w ) ) ) B 7 8 h } l j ~ 9 ] k 4 U ", +" m . [ ).F 9 [ j k g p 8 7 B B ) ) ) w ) M d * S * & ] G G 9 { { { 9 P P H P > y T T u R -.@.&.&. ...W -.P d M w ) w B 3 7 h p g k i [ G F 8 f Z ", +" m 1.h 6 J G o ~ ! l } h 8 3 ) ) ) ) ) w $ - S S S B < 9 G { 9 { o [ B 3 7 B w r M $ d d & * S ` ` P ..W U * N w w ) B 3 8 p } 2 j ~ { ] 9 } i ", +" 2.{ g F ).] 9 [ j 2 } p 8 7 B B w ) ) w $ * S D D k G 9 9 G { { o { { { o ~ i ! k g } p 8 3 B w r $ X Y @.D N w ) ) B 7 h p g k i [ G J l ( *. ", +" } . 2 f J < o ~ k l p h 7 B B w w ) w % & S S S [ 9 9 G { 9 { o o o o ~ ~ j k 2 g } h 7 7 ) ) r H 3.3.&.H N w ) B 3 8 h } l j ~ 9 < J } :.4. ", +" T ( 2 6 ).F 9 [ j k g h 8 3 B ) ) ) w $ & & * & { G 9 9 9 { { { { o [ ~ i j k 2 g } h 8 7 B ) B &.3.3.V H N ) B B 7 8 p l k i [ G J G J p ", +" 5.8 ).{ 6 e < { ~ ! l } h 7 3 B ) w w N d - - N G G G G 9 9 { { o [ o ~ ~ j j k l g p h 8 3 B ) 6.3.Y &.S N ) B 3 8 h } l j ~ { ] J h x 7. ", +" h s B ).).F 9 [ j 2 g p 8 7 B B w ) w $ $ % } G G 9 9 G 9 9 { { [ o [ ~ i k k l g } h h 7 3 $ 6.3.Y Q * r ) 3 7 8 } g k i [ G J { k J Y ", +" 8.o f o f e < o ~ ! l p 8 7 3 B ) ) ) w w M [ 9 9 9 G G G 9 9 { { o o ~ i j ! 2 l g p p 8 8 * ..X W y - w B 3 8 h } 2 j ~ { ] J g :.#. ", +" D : g ^ ).F 9 [ j 2 g h 8 3 3 B ) B B ) w k k 2 l l l g g g g g g } } p p h 7 7 B r r $ $ y V Z -.H $ ) 3 7 8 p l k j [ G J o [ l q ", +" 9.k ^ l 6 e < o ~ ! l p h 8 7 3 B B B B ) ) w w M $ % - - d d % $ $ % % d d - - & S D P y u Q Q > - w B 7 7 h } l j ~ 9 ] ] B t [. ", +" 9.s i G ^ F 9 [ j 2 g p h h 7 7 3 3 B 3 B w w r N % % % d % % % $ % $ % d d d - & * D P > #.> & N B 7 8 h p g k i [ G ] 2 + B ", +" - w s 8 J J < o ~ ! g l p p h 8 7 7 3 3 B B ) r M N $ $ $ $ $ $ N $ $ $ $ % % % d d - - * & d N ) 7 h p } g l j [ { ] ~ g 0.@. ", +" | j + p e F 9 [ j k 2 l } } p h 8 7 7 7 3 B B ) r w r M M M r M M M M M M r M r r r r r ) B 7 8 h } g l 2 ! i o G { g a.+. ", +" ~.2 e k F < o [ ~ j ! k l l } h h 8 7 7 3 3 B B B ) ) ) ) ) ) ) ) ) ) ) ) B B 3 3 7 8 h h p } l l 2 ! i ~ o { { B ( b. ", +" - ^ { k ] G 9 o [ i j ! k g g p p 8 8 8 3 3 3 B ) ) ) ) ) ) ) w ) ) B B 3 3 3 7 8 h h } g l k ! i i o { G { 8 (.p c. ", +" - x 2 ! F F < 9 o [ ~ i ! k l g } p p h 8 7 3 B B B ) ) ) ) ) ) B 3 7 7 8 h h } g g 2 k j i ~ [ o 9 ] G 8 ).l Z ", +" L + i i e J J < 9 { [ ~ j k 2 l g } p h 8 8 7 3 B B ) ) ) 3 B 3 7 8 8 p p } g l k ! i ~ o o G < F < h 4 d.Z ", +" v e.9 l e ).e J < 9 { [ i j ! 2 l g } p h 8 7 3 3 B B B 3 7 8 h h p } g l k ! i ~ o { G ] F e < h : ! -. ", +" N < e g e 6 ).e J < 9 o [ ~ j ! k l g } p h 8 8 7 7 8 8 h h } g g 2 2 ! i ~ o o G ] J ^ ^ { 3 t ) 4. ", +" O [ _ h G f 6 ).J ] G 9 o [ ~ j ! 2 l g p p 8 8 7 8 h p } g l 2 k i i [ { 9 < F e ).e l ~ / r f. ", +" U ) ( j k e f 6 ).J F < 9 { [ i j ! 2 l } } p p p } g l k ! j ~ [ { G ] F ^ 6 ).9 g ^ f S ", +" E A g.5 8 ~ 6 f 6 ).J F < 9 { [ ~ i k 2 g g } g l k ! i ~ [ o 9 ] F e 6 6 F p o ^.8 E ", +" U _./ 6 ! ! ^ / f ).e F < 9 o [ i j k 2 l k ! i ~ [ { 9 ] F e ).6 G p 9 s G y ", +" O 8 : + 7 k ] ).6 ).e F < 9 o ~ ~ j j i ~ [ o 9 ] F e e J o h k h.[ *.b ", +" @.7 0.: $.k 8 j ] e e J ] G o o ~ [ { < ] F ] o } 7 < . 6 !.' q ", +" -.5.c / ,.e i k ! k k k k l l l 2 l 2 k ! i.$.4 j.k.l. ", +" b m.$ p i 6 t n.n.0 n.n n 0 5 + ] k o.O ..b ", +" m.-.R l.y #.O C R @.z ", +" ", +" "}; diff --git a/share/pixmaps/check.ico b/share/pixmaps/check.ico new file mode 100644 index 0000000..0c4e6e8 Binary files /dev/null and b/share/pixmaps/check.ico differ diff --git a/share/pixmaps/favicon.ico b/share/pixmaps/favicon.ico new file mode 100644 index 0000000..be52174 Binary files /dev/null and b/share/pixmaps/favicon.ico differ diff --git a/share/pixmaps/nsis-header.bmp b/share/pixmaps/nsis-header.bmp new file mode 100644 index 0000000..b5a3040 Binary files /dev/null and b/share/pixmaps/nsis-header.bmp differ diff --git a/share/pixmaps/nsis-wizard.bmp b/share/pixmaps/nsis-wizard.bmp new file mode 100644 index 0000000..e85bc19 Binary files /dev/null and b/share/pixmaps/nsis-wizard.bmp differ diff --git a/share/pixmaps/send16.bmp b/share/pixmaps/send16.bmp new file mode 100644 index 0000000..676b5c4 Binary files /dev/null and b/share/pixmaps/send16.bmp differ diff --git a/share/pixmaps/send16mask.bmp b/share/pixmaps/send16mask.bmp new file mode 100644 index 0000000..06c747f Binary files /dev/null and b/share/pixmaps/send16mask.bmp differ diff --git a/share/pixmaps/send16masknoshadow.bmp b/share/pixmaps/send16masknoshadow.bmp new file mode 100644 index 0000000..faf24e0 Binary files /dev/null and b/share/pixmaps/send16masknoshadow.bmp differ diff --git a/share/pixmaps/send20.bmp b/share/pixmaps/send20.bmp new file mode 100644 index 0000000..2b90422 Binary files /dev/null and b/share/pixmaps/send20.bmp differ diff --git a/share/pixmaps/send20mask.bmp b/share/pixmaps/send20mask.bmp new file mode 100644 index 0000000..f124d0d Binary files /dev/null and b/share/pixmaps/send20mask.bmp differ diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py new file mode 100644 index 0000000..1267b18 --- /dev/null +++ b/share/qt/extract_strings_qt.py @@ -0,0 +1,72 @@ +#!/usr/bin/python +''' +Extract _("...") strings for translation and convert to Qt4 stringdefs so that +they can be picked up by Qt linguist. +''' +from subprocess import Popen, PIPE +import glob +import operator + +OUT_CPP="src/qt/bitcoinstrings.cpp" +EMPTY=['""'] + +def parse_po(text): + """ + Parse 'po' format produced by xgettext. + Return a list of (msgid,msgstr) tuples. + """ + messages = [] + msgid = [] + msgstr = [] + in_msgid = False + in_msgstr = False + + for line in text.split('\n'): + line = line.rstrip('\r') + if line.startswith('msgid '): + if in_msgstr: + messages.append((msgid, msgstr)) + in_msgstr = False + # message start + in_msgid = True + + msgid = [line[6:]] + elif line.startswith('msgstr '): + in_msgid = False + in_msgstr = True + msgstr = [line[7:]] + elif line.startswith('"'): + if in_msgid: + msgid.append(line) + if in_msgstr: + msgstr.append(line) + + if in_msgstr: + messages.append((msgid, msgstr)) + + return messages + +files = glob.glob('src/*.cpp') + glob.glob('src/*.h') + +# xgettext -n --keyword=_ $FILES +child = Popen(['xgettext','--output=-','-n','--keyword=_'] + files, stdout=PIPE) +(out, err) = child.communicate() + +messages = parse_po(out) + +f = open(OUT_CPP, 'w') +f.write("""#include +// Automatically generated by extract_strings.py +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif +""") +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))) +f.write('};') +f.close() diff --git a/share/qt/img/reload.xcf b/share/qt/img/reload.xcf new file mode 100644 index 0000000..dc8be62 Binary files /dev/null and b/share/qt/img/reload.xcf differ diff --git a/share/qt/make_spinner.py b/share/qt/make_spinner.py new file mode 100644 index 0000000..136aff3 --- /dev/null +++ b/share/qt/make_spinner.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# W.J. van der Laan, 2011 +# Make spinning .mng animation from a .png +# Requires imagemagick 6.7+ +from __future__ import division +from os import path +from PIL import Image +from subprocess import Popen + +SRC='img/reload_scaled.png' +DST='../../src/qt/res/movies/update_spinner.mng' +TMPDIR='/tmp' +TMPNAME='tmp-%03i.png' +NUMFRAMES=35 +FRAMERATE=10.0 +CONVERT='convert' +CLOCKWISE=True +DSIZE=(16,16) + +im_src = Image.open(SRC) + +if CLOCKWISE: + im_src = im_src.transpose(Image.FLIP_LEFT_RIGHT) + +def frame_to_filename(frame): + return path.join(TMPDIR, TMPNAME % frame) + +frame_files = [] +for frame in xrange(NUMFRAMES): + rotation = (frame + 0.5) / NUMFRAMES * 360.0 + if CLOCKWISE: + rotation = -rotation + im_new = im_src.rotate(rotation, Image.BICUBIC) + im_new.thumbnail(DSIZE, Image.ANTIALIAS) + outfile = frame_to_filename(frame) + im_new.save(outfile, 'png') + frame_files.append(outfile) + +p = Popen([CONVERT, "-delay", str(FRAMERATE), "-dispose", "2"] + frame_files + [DST]) +p.communicate() + + + diff --git a/share/qt/make_windows_icon.sh b/share/qt/make_windows_icon.sh new file mode 100644 index 0000000..bf607b1 --- /dev/null +++ b/share/qt/make_windows_icon.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# create multiresolution windows icon +ICON_SRC=../../src/qt/res/icons/bitcoin.png +ICON_DST=../../src/qt/res/icons/bitcoin.ico +convert ${ICON_SRC} -resize 16x16 bitcoin-16.png +convert ${ICON_SRC} -resize 32x32 bitcoin-32.png +convert ${ICON_SRC} -resize 48x48 bitcoin-48.png +convert bitcoin-16.png bitcoin-32.png bitcoin-48.png ${ICON_DST} + diff --git a/share/setup.nsi b/share/setup.nsi new file mode 100644 index 0000000..2dddd71 --- /dev/null +++ b/share/setup.nsi @@ -0,0 +1,162 @@ +Name CasinoCoin + +RequestExecutionLevel highest +SetCompressor /SOLID lzma + +# General Symbol Definitions +!define REGKEY "SOFTWARE\$(^Name)" +!define VERSION 1.0.0.3 +!define COMPANY "CasinoCoin project" +!define URL http://www.casinocoin.org/ + +# MUI Symbol Definitions +!define MUI_ICON "../share/pixmaps/bitcoin.ico" +!define MUI_WELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp" +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_RIGHT +!define MUI_HEADERIMAGE_BITMAP "../share/pixmaps/nsis-header.bmp" +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM +!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup +!define MUI_STARTMENUPAGE_DEFAULTFOLDER CasinoCoin +!define MUI_FINISHPAGE_RUN $INSTDIR\casinocoin-qt.exe +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp" +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +# Included files +!include Sections.nsh +!include MUI2.nsh + +# Variables +Var StartMenuGroup + +# Installer pages +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +# Installer languages +!insertmacro MUI_LANGUAGE English + +# Installer attributes +OutFile casinocoin-1.0.0.3-win32-setup.exe +InstallDir $PROGRAMFILES\CasinoCoin +CRCCheck on +XPStyle on +BrandingText " " +ShowInstDetails show +VIProductVersion 1.0.0.3 +VIAddVersionKey ProductName CasinoCoin +VIAddVersionKey ProductVersion "${VERSION}" +VIAddVersionKey CompanyName "${COMPANY}" +VIAddVersionKey CompanyWebsite "${URL}" +VIAddVersionKey FileVersion "${VERSION}" +VIAddVersionKey FileDescription "" +VIAddVersionKey LegalCopyright "" +InstallDirRegKey HKCU "${REGKEY}" Path +ShowUninstDetails show + +# Installer sections +Section -Main SEC0000 + SetOutPath $INSTDIR + SetOverwrite on + File ../release/casinocoin-qt.exe + File /oname=license.txt ../COPYING + File /oname=readme.txt ../doc/README_windows.txt + SetOutPath $INSTDIR\daemon + File ../src/casinocoind.exe + SetOutPath $INSTDIR\src + File /r /x *.exe /x *.o ../src\*.* + SetOutPath $INSTDIR + WriteRegStr HKCU "${REGKEY}\Components" Main 1 + + # Remove old wxwidgets-based-bitcoin executable and locales: + Delete /REBOOTOK $INSTDIR\casinocoin.exe + RMDir /r /REBOOTOK $INSTDIR\locale +SectionEnd + +Section -post SEC0001 + WriteRegStr HKCU "${REGKEY}" Path $INSTDIR + SetOutPath $INSTDIR + WriteUninstaller $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + CreateDirectory $SMPROGRAMS\$StartMenuGroup + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\CasinoCoin.lnk" $INSTDIR\casinocoin-qt.exe + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall CasinoCoin.lnk" $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_END + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 + WriteRegStr HKCR "casinocoin" "URL Protocol" "" + WriteRegStr HKCR "casinocoin" "" "URL:Bitcoin" + WriteRegStr HKCR "casinocoin\DefaultIcon" "" $INSTDIR\casinocoin-qt.exe + WriteRegStr HKCR "casinocoin\shell\open\command" "" '"$INSTDIR\casinocoin-qt.exe" "$$1"' +SectionEnd + +# Macro for selecting uninstaller sections +!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID + Push $R0 + ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}" + StrCmp $R0 1 0 next${UNSECTION_ID} + !insertmacro SelectSection "${UNSECTION_ID}" + GoTo done${UNSECTION_ID} +next${UNSECTION_ID}: + !insertmacro UnselectSection "${UNSECTION_ID}" +done${UNSECTION_ID}: + Pop $R0 +!macroend + +# Uninstaller sections +Section /o -un.Main UNSEC0000 + Delete /REBOOTOK $INSTDIR\casinocoin-qt.exe + Delete /REBOOTOK $INSTDIR\license.txt + Delete /REBOOTOK $INSTDIR\readme.txt + RMDir /r /REBOOTOK $INSTDIR\daemon + RMDir /r /REBOOTOK $INSTDIR\src + DeleteRegValue HKCU "${REGKEY}\Components" Main +SectionEnd + +Section -un.post UNSEC0001 + DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall CasinoCoin.lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\CasinoCoin.lnk" + Delete /REBOOTOK "$SMSTARTUP\CasinoCoin.lnk" + Delete /REBOOTOK $INSTDIR\uninstall.exe + Delete /REBOOTOK $INSTDIR\debug.log + Delete /REBOOTOK $INSTDIR\db.log + DeleteRegValue HKCU "${REGKEY}" StartMenuGroup + DeleteRegValue HKCU "${REGKEY}" Path + DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components" + DeleteRegKey /IfEmpty HKCU "${REGKEY}" + DeleteRegKey HKCR "casinocoin" + RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup + RmDir /REBOOTOK $INSTDIR + Push $R0 + StrCpy $R0 $StartMenuGroup 1 + StrCmp $R0 ">" no_smgroup +no_smgroup: + Pop $R0 +SectionEnd + +# Installer functions +Function .onInit + InitPluginsDir +FunctionEnd + +# Uninstaller functions +Function un.onInit + ReadRegStr $INSTDIR HKCU "${REGKEY}" Path + !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup + !insertmacro SELECT_UNSECTION Main ${UNSEC0000} +FunctionEnd diff --git a/share/ui.rc b/share/ui.rc new file mode 100644 index 0000000..c3cece1 --- /dev/null +++ b/share/ui.rc @@ -0,0 +1,15 @@ +bitcoin ICON "pixmaps/bitcoin.ico" + +#include "wx/msw/wx.rc" + +check ICON "pixmaps/check.ico" +send16 BITMAP "pixmaps/send16.bmp" +send16mask BITMAP "pixmaps/send16mask.bmp" +send16masknoshadow BITMAP "pixmaps/send16masknoshadow.bmp" +send20 BITMAP "pixmaps/send20.bmp" +send20mask BITMAP "pixmaps/send20mask.bmp" +addressbook16 BITMAP "pixmaps/addressbook16.bmp" +addressbook16mask BITMAP "pixmaps/addressbook16mask.bmp" +addressbook20 BITMAP "pixmaps/addressbook20.bmp" +addressbook20mask BITMAP "pixmaps/addressbook20mask.bmp" +favicon ICON "pixmaps/favicon.ico" diff --git a/src/addrman.cpp b/src/addrman.cpp new file mode 100644 index 0000000..acd0d46 --- /dev/null +++ b/src/addrman.cpp @@ -0,0 +1,527 @@ +// Copyright (c) 2012 Pieter Wuille +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "addrman.h" + +using namespace std; + +int CAddrInfo::GetTriedBucket(const std::vector &nKey) const +{ + CDataStream ss1(SER_GETHASH, 0); + std::vector vchKey = GetKey(); + ss1 << nKey << vchKey; + uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64(); + + CDataStream ss2(SER_GETHASH, 0); + std::vector vchGroupKey = GetGroup(); + ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP); + uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64(); + return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; +} + +int CAddrInfo::GetNewBucket(const std::vector &nKey, const CNetAddr& src) const +{ + CDataStream ss1(SER_GETHASH, 0); + std::vector vchGroupKey = GetGroup(); + std::vector vchSourceGroupKey = src.GetGroup(); + ss1 << nKey << vchGroupKey << vchSourceGroupKey; + uint64 hash1 = Hash(ss1.begin(), ss1.end()).Get64(); + + CDataStream ss2(SER_GETHASH, 0); + ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP); + uint64 hash2 = Hash(ss2.begin(), ss2.end()).Get64(); + return hash2 % ADDRMAN_NEW_BUCKET_COUNT; +} + +bool CAddrInfo::IsTerrible(int64 nNow) const +{ + if (nLastTry && nLastTry >= nNow-60) // never remove things tried the last minute + return false; + + if (nTime > nNow + 10*60) // came in a flying DeLorean + return true; + + if (nTime==0 || nNow-nTime > ADDRMAN_HORIZON_DAYS*86400) // not seen in over a month + return true; + + if (nLastSuccess==0 && nAttempts>=ADDRMAN_RETRIES) // tried three times and never a success + return true; + + if (nNow-nLastSuccess > ADDRMAN_MIN_FAIL_DAYS*86400 && nAttempts>=ADDRMAN_MAX_FAILURES) // 10 successive failures in the last week + return true; + + return false; +} + +double CAddrInfo::GetChance(int64 nNow) const +{ + double fChance = 1.0; + + int64 nSinceLastSeen = nNow - nTime; + int64 nSinceLastTry = nNow - nLastTry; + + if (nSinceLastSeen < 0) nSinceLastSeen = 0; + if (nSinceLastTry < 0) nSinceLastTry = 0; + + fChance *= 600.0 / (600.0 + nSinceLastSeen); + + // deprioritize very recent attempts away + if (nSinceLastTry < 60*10) + fChance *= 0.01; + + // deprioritize 50% after each failed attempt + for (int n=0; n::iterator it = mapAddr.find(addr); + if (it == mapAddr.end()) + return NULL; + if (pnId) + *pnId = (*it).second; + std::map::iterator it2 = mapInfo.find((*it).second); + if (it2 != mapInfo.end()) + return &(*it2).second; + return NULL; +} + +CAddrInfo* CAddrMan::Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId) +{ + int nId = nIdCount++; + mapInfo[nId] = CAddrInfo(addr, addrSource); + mapAddr[addr] = nId; + mapInfo[nId].nRandomPos = vRandom.size(); + vRandom.push_back(nId); + if (pnId) + *pnId = nId; + return &mapInfo[nId]; +} + +void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) +{ + if (nRndPos1 == nRndPos2) + return; + + assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size()); + + int nId1 = vRandom[nRndPos1]; + int nId2 = vRandom[nRndPos2]; + + assert(mapInfo.count(nId1) == 1); + assert(mapInfo.count(nId2) == 1); + + mapInfo[nId1].nRandomPos = nRndPos2; + mapInfo[nId2].nRandomPos = nRndPos1; + + vRandom[nRndPos1] = nId2; + vRandom[nRndPos2] = nId1; +} + +int CAddrMan::SelectTried(int nKBucket) +{ + std::vector &vTried = vvTried[nKBucket]; + + // random shuffle the first few elements (using the entire list) + // find the least recently tried among them + int64 nOldest = -1; + int nOldestPos = -1; + for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++) + { + int nPos = GetRandInt(vTried.size() - i) + i; + int nTemp = vTried[nPos]; + vTried[nPos] = vTried[i]; + vTried[i] = nTemp; + assert(nOldest == -1 || mapInfo.count(nTemp) == 1); + if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) { + nOldest = nTemp; + nOldestPos = nPos; + } + } + + return nOldestPos; +} + +int CAddrMan::ShrinkNew(int nUBucket) +{ + assert(nUBucket >= 0 && (unsigned int)nUBucket < vvNew.size()); + std::set &vNew = vvNew[nUBucket]; + + // first look for deletable items + for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) + { + assert(mapInfo.count(*it)); + CAddrInfo &info = mapInfo[*it]; + if (info.IsTerrible()) + { + if (--info.nRefCount == 0) + { + SwapRandom(info.nRandomPos, vRandom.size()-1); + vRandom.pop_back(); + mapAddr.erase(info); + mapInfo.erase(*it); + nNew--; + } + vNew.erase(it); + return 0; + } + } + + // otherwise, select four randomly, and pick the oldest of those to replace + int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())}; + int nI = 0; + int nOldest = -1; + for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) + { + if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3]) + { + assert(nOldest == -1 || mapInfo.count(*it) == 1); + if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime) + nOldest = *it; + } + nI++; + } + assert(mapInfo.count(nOldest) == 1); + CAddrInfo &info = mapInfo[nOldest]; + if (--info.nRefCount == 0) + { + SwapRandom(info.nRandomPos, vRandom.size()-1); + vRandom.pop_back(); + mapAddr.erase(info); + mapInfo.erase(nOldest); + nNew--; + } + vNew.erase(nOldest); + + return 1; +} + +void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) +{ + assert(vvNew[nOrigin].count(nId) == 1); + + // remove the entry from all new buckets + for (std::vector >::iterator it = vvNew.begin(); it != vvNew.end(); it++) + { + if ((*it).erase(nId)) + info.nRefCount--; + } + nNew--; + + assert(info.nRefCount == 0); + + // what tried bucket to move the entry to + int nKBucket = info.GetTriedBucket(nKey); + std::vector &vTried = vvTried[nKBucket]; + + // first check whether there is place to just add it + if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) + { + vTried.push_back(nId); + nTried++; + info.fInTried = true; + return; + } + + // otherwise, find an item to evict + int nPos = SelectTried(nKBucket); + + // find which new bucket it belongs to + assert(mapInfo.count(vTried[nPos]) == 1); + int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey); + std::set &vNew = vvNew[nUBucket]; + + // remove the to-be-replaced tried entry from the tried set + CAddrInfo& infoOld = mapInfo[vTried[nPos]]; + infoOld.fInTried = false; + infoOld.nRefCount = 1; + // do not update nTried, as we are going to move something else there immediately + + // check whether there is place in that one, + if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) + { + // if so, move it back there + vNew.insert(vTried[nPos]); + } else { + // otherwise, move it to the new bucket nId came from (there is certainly place there) + vvNew[nOrigin].insert(vTried[nPos]); + } + nNew++; + + vTried[nPos] = nId; + // we just overwrote an entry in vTried; no need to update nTried + info.fInTried = true; + return; +} + +void CAddrMan::Good_(const CService &addr, int64 nTime) +{ +// printf("Good: addr=%s\n", addr.ToString().c_str()); + + int nId; + CAddrInfo *pinfo = Find(addr, &nId); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo &info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + info.nLastSuccess = nTime; + info.nLastTry = nTime; + info.nTime = nTime; + info.nAttempts = 0; + + // if it is already in the tried set, don't do anything else + if (info.fInTried) + return; + + // find a bucket it is in now + int nRnd = GetRandInt(vvNew.size()); + int nUBucket = -1; + for (unsigned int n = 0; n < vvNew.size(); n++) + { + int nB = (n+nRnd) % vvNew.size(); + std::set &vNew = vvNew[nB]; + if (vNew.count(nId)) + { + nUBucket = nB; + break; + } + } + + // if no bucket is found, something bad happened; + // TODO: maybe re-add the node, but for now, just bail out + if (nUBucket == -1) return; + + printf("Moving %s to tried\n", addr.ToString().c_str()); + + // move nId to the tried tables + MakeTried(info, nId, nUBucket); +} + +bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty) +{ + if (!addr.IsRoutable()) + return false; + + bool fNew = false; + int nId; + CAddrInfo *pinfo = Find(addr, &nId); + + if (pinfo) + { + // periodically update nTime + bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60); + int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); + if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty)) + pinfo->nTime = max((int64)0, addr.nTime - nTimePenalty); + + // add services + pinfo->nServices |= addr.nServices; + + // do not update if no new information is present + if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime)) + return false; + + // do not update if the entry was already in the "tried" table + if (pinfo->fInTried) + return false; + + // do not update if the max reference count is reached + if (pinfo->nRefCount == ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + return false; + + // stochastic test: previous nRefCount == N: 2^N times harder to increase it + int nFactor = 1; + for (int n=0; nnRefCount; n++) + nFactor *= 2; + if (nFactor > 1 && (GetRandInt(nFactor) != 0)) + return false; + } else { + pinfo = Create(addr, source, &nId); + pinfo->nTime = max((int64)0, (int64)pinfo->nTime - nTimePenalty); +// printf("Added %s [nTime=%fhr]\n", pinfo->ToString().c_str(), (GetAdjustedTime() - pinfo->nTime) / 3600.0); + nNew++; + fNew = true; + } + + int nUBucket = pinfo->GetNewBucket(nKey, source); + std::set &vNew = vvNew[nUBucket]; + if (!vNew.count(nId)) + { + pinfo->nRefCount++; + if (vNew.size() == ADDRMAN_NEW_BUCKET_SIZE) + ShrinkNew(nUBucket); + vvNew[nUBucket].insert(nId); + } + return fNew; +} + +void CAddrMan::Attempt_(const CService &addr, int64 nTime) +{ + CAddrInfo *pinfo = Find(addr); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo &info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + info.nLastTry = nTime; + info.nAttempts++; +} + +CAddress CAddrMan::Select_(int nUnkBias) +{ + if (size() == 0) + return CAddress(); + + double nCorTried = sqrt(nTried) * (100.0 - nUnkBias); + double nCorNew = sqrt(nNew) * nUnkBias; + if ((nCorTried + nCorNew)*GetRandInt(1<<30)/(1<<30) < nCorTried) + { + // use a tried node + double fChanceFactor = 1.0; + while(1) + { + int nKBucket = GetRandInt(vvTried.size()); + std::vector &vTried = vvTried[nKBucket]; + if (vTried.size() == 0) continue; + int nPos = GetRandInt(vTried.size()); + assert(mapInfo.count(vTried[nPos]) == 1); + CAddrInfo &info = mapInfo[vTried[nPos]]; + if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30)) + return info; + fChanceFactor *= 1.2; + } + } else { + // use an new node + double fChanceFactor = 1.0; + while(1) + { + int nUBucket = GetRandInt(vvNew.size()); + std::set &vNew = vvNew[nUBucket]; + if (vNew.size() == 0) continue; + int nPos = GetRandInt(vNew.size()); + std::set::iterator it = vNew.begin(); + while (nPos--) + it++; + assert(mapInfo.count(*it) == 1); + CAddrInfo &info = mapInfo[*it]; + if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30)) + return info; + fChanceFactor *= 1.2; + } + } +} + +#ifdef DEBUG_ADDRMAN +int CAddrMan::Check_() +{ + std::set setTried; + std::map mapNew; + + if (vRandom.size() != nTried + nNew) return -7; + + for (std::map::iterator it = mapInfo.begin(); it != mapInfo.end(); it++) + { + int n = (*it).first; + CAddrInfo &info = (*it).second; + if (info.fInTried) + { + + if (!info.nLastSuccess) return -1; + if (info.nRefCount) return -2; + setTried.insert(n); + } else { + if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS) return -3; + if (!info.nRefCount) return -4; + mapNew[n] = info.nRefCount; + } + if (mapAddr[info] != n) return -5; + if (info.nRandomPos<0 || info.nRandomPos>=vRandom.size() || vRandom[info.nRandomPos] != n) return -14; + if (info.nLastTry < 0) return -6; + if (info.nLastSuccess < 0) return -8; + } + + if (setTried.size() != nTried) return -9; + if (mapNew.size() != nNew) return -10; + + for (int n=0; n &vTried = vvTried[n]; + for (std::vector::iterator it = vTried.begin(); it != vTried.end(); it++) + { + if (!setTried.count(*it)) return -11; + setTried.erase(*it); + } + } + + for (int n=0; n &vNew = vvNew[n]; + for (std::set::iterator it = vNew.begin(); it != vNew.end(); it++) + { + if (!mapNew.count(*it)) return -12; + if (--mapNew[*it] == 0) + mapNew.erase(*it); + } + } + + if (setTried.size()) return -13; + if (mapNew.size()) return -15; + + return 0; +} +#endif + +void CAddrMan::GetAddr_(std::vector &vAddr) +{ + int nNodes = ADDRMAN_GETADDR_MAX_PCT*vRandom.size()/100; + if (nNodes > ADDRMAN_GETADDR_MAX) + nNodes = ADDRMAN_GETADDR_MAX; + + // perform a random shuffle over the first nNodes elements of vRandom (selecting from all) + for (int n = 0; n nUpdateInterval) + info.nTime = nTime; +} diff --git a/src/addrman.h b/src/addrman.h new file mode 100644 index 0000000..0392654 --- /dev/null +++ b/src/addrman.h @@ -0,0 +1,503 @@ +// Copyright (c) 2012 Pieter Wuille +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef _BITCOIN_ADDRMAN +#define _BITCOIN_ADDRMAN 1 + +#include "netbase.h" +#include "protocol.h" +#include "util.h" +#include "sync.h" + + +#include +#include + +#include + + +/** Extended statistics about a CAddress */ +class CAddrInfo : public CAddress +{ +private: + // where knowledge about this address first came from + CNetAddr source; + + // last successful connection by us + int64 nLastSuccess; + + // last try whatsoever by us: + // int64 CAddress::nLastTry + + // connection attempts since last successful attempt + int nAttempts; + + // reference count in new sets (memory only) + int nRefCount; + + // in tried set? (memory only) + bool fInTried; + + // position in vRandom + int nRandomPos; + + friend class CAddrMan; + +public: + + IMPLEMENT_SERIALIZE( + CAddress* pthis = (CAddress*)(this); + READWRITE(*pthis); + READWRITE(source); + READWRITE(nLastSuccess); + READWRITE(nAttempts); + ) + + void Init() + { + nLastSuccess = 0; + nLastTry = 0; + nAttempts = 0; + nRefCount = 0; + fInTried = false; + nRandomPos = -1; + } + + CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource) + { + Init(); + } + + CAddrInfo() : CAddress(), source() + { + Init(); + } + + // Calculate in which "tried" bucket this entry belongs + int GetTriedBucket(const std::vector &nKey) const; + + // Calculate in which "new" bucket this entry belongs, given a certain source + int GetNewBucket(const std::vector &nKey, const CNetAddr& src) const; + + // Calculate in which "new" bucket this entry belongs, using its default source + int GetNewBucket(const std::vector &nKey) const + { + return GetNewBucket(nKey, source); + } + + // Determine whether the statistics about this entry are bad enough so that it can just be deleted + bool IsTerrible(int64 nNow = GetAdjustedTime()) const; + + // Calculate the relative chance this entry should be given when selecting nodes to connect to + double GetChance(int64 nNow = GetAdjustedTime()) const; + +}; + +// Stochastic address manager +// +// Design goals: +// * Only keep a limited number of addresses around, so that addr.dat and memory requirements do not grow without bound. +// * Keep the address tables in-memory, and asynchronously dump the entire to able in addr.dat. +// * Make sure no (localized) attacker can fill the entire table with his nodes/addresses. +// +// To that end: +// * Addresses are organized into buckets. +// * Address that have not yet been tried go into 256 "new" buckets. +// * Based on the address range (/16 for IPv4) of source of the information, 32 buckets are selected at random +// * The actual bucket is chosen from one of these, based on the range the address itself is located. +// * One single address can occur in up to 4 different buckets, to increase selection chances for addresses that +// are seen frequently. The chance for increasing this multiplicity decreases exponentially. +// * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen +// ones) is removed from it first. +// * Addresses of nodes that are known to be accessible go into 64 "tried" buckets. +// * Each address range selects at random 4 of these buckets. +// * The actual bucket is chosen from one of these, based on the full address. +// * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently +// tried ones) is evicted from it, back to the "new" buckets. +// * Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not +// be observable by adversaries. +// * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN will introduce frequent (and expensive) +// consistency checks for the entire datastructure. + +// total number of buckets for tried addresses +#define ADDRMAN_TRIED_BUCKET_COUNT 64 + +// maximum allowed number of entries in buckets for tried addresses +#define ADDRMAN_TRIED_BUCKET_SIZE 64 + +// total number of buckets for new addresses +#define ADDRMAN_NEW_BUCKET_COUNT 256 + +// maximum allowed number of entries in buckets for new addresses +#define ADDRMAN_NEW_BUCKET_SIZE 64 + +// over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread +#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 4 + +// over how many buckets entries with new addresses originating from a single group are spread +#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 32 + +// in how many buckets for entries with new addresses a single address may occur +#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4 + +// how many entries in a bucket with tried addresses are inspected, when selecting one to replace +#define ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT 4 + +// how old addresses can maximally be +#define ADDRMAN_HORIZON_DAYS 30 + +// after how many failed attempts we give up on a new node +#define ADDRMAN_RETRIES 3 + +// how many successive failures are allowed ... +#define ADDRMAN_MAX_FAILURES 10 + +// ... in at least this many days +#define ADDRMAN_MIN_FAIL_DAYS 7 + +// the maximum percentage of nodes to return in a getaddr call +#define ADDRMAN_GETADDR_MAX_PCT 23 + +// the maximum number of nodes to return in a getaddr call +#define ADDRMAN_GETADDR_MAX 2500 + +/** Stochastical (IP) address manager */ +class CAddrMan +{ +private: + // critical section to protect the inner data structures + mutable CCriticalSection cs; + + // secret key to randomize bucket select with + std::vector nKey; + + // last used nId + int nIdCount; + + // table with information about all nId's + std::map mapInfo; + + // find an nId based on its network address + std::map mapAddr; + + // randomly-ordered vector of all nId's + std::vector vRandom; + + // number of "tried" entries + int nTried; + + // list of "tried" buckets + std::vector > vvTried; + + // number of (unique) "new" entries + int nNew; + + // list of "new" buckets + std::vector > vvNew; + +protected: + + // Find an entry. + CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL); + + // find an entry, creating it if necessary. + // nTime and nServices of found node is updated, if necessary. + CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = NULL); + + // Swap two elements in vRandom. + void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2); + + // Return position in given bucket to replace. + int SelectTried(int nKBucket); + + // Remove an element from a "new" bucket. + // This is the only place where actual deletes occur. + // They are never deleted while in the "tried" table, only possibly evicted back to the "new" table. + int ShrinkNew(int nUBucket); + + // Move an entry from the "new" table(s) to the "tried" table + // @pre vvUnkown[nOrigin].count(nId) != 0 + void MakeTried(CAddrInfo& info, int nId, int nOrigin); + + // Mark an entry "good", possibly moving it from "new" to "tried". + void Good_(const CService &addr, int64 nTime); + + // Add an entry to the "new" table. + bool Add_(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty); + + // Mark an entry as attempted to connect. + void Attempt_(const CService &addr, int64 nTime); + + // Select an address to connect to. + // nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100) + CAddress Select_(int nUnkBias); + +#ifdef DEBUG_ADDRMAN + // Perform consistency check. Returns an error code or zero. + int Check_(); +#endif + + // Select several addresses at once. + void GetAddr_(std::vector &vAddr); + + // Mark an entry as currently-connected-to. + void Connected_(const CService &addr, int64 nTime); + +public: + + IMPLEMENT_SERIALIZE + (({ + // serialized format: + // * version byte (currently 0) + // * nKey + // * nNew + // * nTried + // * number of "new" buckets + // * all nNew addrinfo's in vvNew + // * all nTried addrinfo's in vvTried + // * for each bucket: + // * number of elements + // * for each element: index + // + // Notice that vvTried, mapAddr and vVector are never encoded explicitly; + // they are instead reconstructed from the other information. + // + // vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change, + // otherwise it is reconstructed as well. + // + // This format is more complex, but significantly smaller (at most 1.5 MiB), and supports + // changes to the ADDRMAN_ parameters without breaking the on-disk structure. + { + LOCK(cs); + unsigned char nVersion = 0; + READWRITE(nVersion); + READWRITE(nKey); + READWRITE(nNew); + READWRITE(nTried); + + CAddrMan *am = const_cast(this); + if (fWrite) + { + int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT; + READWRITE(nUBuckets); + std::map mapUnkIds; + int nIds = 0; + for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) + { + if (nIds == nNew) break; // this means nNew was wrong, oh ow + mapUnkIds[(*it).first] = nIds; + CAddrInfo &info = (*it).second; + if (info.nRefCount) + { + READWRITE(info); + nIds++; + } + } + nIds = 0; + for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) + { + if (nIds == nTried) break; // this means nTried was wrong, oh ow + CAddrInfo &info = (*it).second; + if (info.fInTried) + { + READWRITE(info); + nIds++; + } + } + for (std::vector >::iterator it = am->vvNew.begin(); it != am->vvNew.end(); it++) + { + const std::set &vNew = (*it); + int nSize = vNew.size(); + READWRITE(nSize); + for (std::set::iterator it2 = vNew.begin(); it2 != vNew.end(); it2++) + { + int nIndex = mapUnkIds[*it2]; + READWRITE(nIndex); + } + } + } else { + int nUBuckets = 0; + READWRITE(nUBuckets); + am->nIdCount = 0; + am->mapInfo.clear(); + am->mapAddr.clear(); + am->vRandom.clear(); + am->vvTried = std::vector >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)); + am->vvNew = std::vector >(ADDRMAN_NEW_BUCKET_COUNT, std::set()); + for (int n = 0; n < am->nNew; n++) + { + CAddrInfo &info = am->mapInfo[n]; + READWRITE(info); + am->mapAddr[info] = n; + info.nRandomPos = vRandom.size(); + am->vRandom.push_back(n); + if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) + { + am->vvNew[info.GetNewBucket(am->nKey)].insert(n); + info.nRefCount++; + } + } + am->nIdCount = am->nNew; + int nLost = 0; + for (int n = 0; n < am->nTried; n++) + { + CAddrInfo info; + READWRITE(info); + std::vector &vTried = am->vvTried[info.GetTriedBucket(am->nKey)]; + if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) + { + info.nRandomPos = vRandom.size(); + info.fInTried = true; + am->vRandom.push_back(am->nIdCount); + am->mapInfo[am->nIdCount] = info; + am->mapAddr[info] = am->nIdCount; + vTried.push_back(am->nIdCount); + am->nIdCount++; + } else { + nLost++; + } + } + am->nTried -= nLost; + for (int b = 0; b < nUBuckets; b++) + { + std::set &vNew = am->vvNew[b]; + int nSize = 0; + READWRITE(nSize); + for (int n = 0; n < nSize; n++) + { + int nIndex = 0; + READWRITE(nIndex); + CAddrInfo &info = am->mapInfo[nIndex]; + if (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + { + info.nRefCount++; + vNew.insert(nIndex); + } + } + } + } + } + });) + + CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set()) + { + nKey.resize(32); + RAND_bytes(&nKey[0], 32); + + nIdCount = 0; + nTried = 0; + nNew = 0; + } + + // Return the number of (unique) addresses in all tables. + int size() + { + return vRandom.size(); + } + + // Consistency check + void Check() + { +#ifdef DEBUG_ADDRMAN + { + LOCK(cs); + int err; + if ((err=Check_())) + printf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err); + } +#endif + } + + // Add a single address. + bool Add(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty = 0) + { + bool fRet = false; + { + LOCK(cs); + Check(); + fRet |= Add_(addr, source, nTimePenalty); + Check(); + } + if (fRet) + printf("Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort().c_str(), source.ToString().c_str(), nTried, nNew); + return fRet; + } + + // Add multiple addresses. + bool Add(const std::vector &vAddr, const CNetAddr& source, int64 nTimePenalty = 0) + { + int nAdd = 0; + { + LOCK(cs); + Check(); + for (std::vector::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) + nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0; + Check(); + } + if (nAdd) + printf("Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString().c_str(), nTried, nNew); + return nAdd > 0; + } + + // Mark an entry as accessible. + void Good(const CService &addr, int64 nTime = GetAdjustedTime()) + { + { + LOCK(cs); + Check(); + Good_(addr, nTime); + Check(); + } + } + + // Mark an entry as connection attempted to. + void Attempt(const CService &addr, int64 nTime = GetAdjustedTime()) + { + { + LOCK(cs); + Check(); + Attempt_(addr, nTime); + Check(); + } + } + + // Choose an address to connect to. + // nUnkBias determines how much "new" entries are favored over "tried" ones (0-100). + CAddress Select(int nUnkBias = 50) + { + CAddress addrRet; + { + LOCK(cs); + Check(); + addrRet = Select_(nUnkBias); + Check(); + } + return addrRet; + } + + // Return a bunch of addresses, selected at random. + std::vector GetAddr() + { + Check(); + std::vector vAddr; + { + LOCK(cs); + GetAddr_(vAddr); + } + Check(); + return vAddr; + } + + // Mark an entry as currently-connected-to. + void Connected(const CService &addr, int64 nTime = GetAdjustedTime()) + { + { + LOCK(cs); + Check(); + Connected_(addr, nTime); + Check(); + } + } +}; + +#endif diff --git a/src/allocators.h b/src/allocators.h new file mode 100644 index 0000000..c82f633 --- /dev/null +++ b/src/allocators.h @@ -0,0 +1,124 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_ALLOCATORS_H +#define BITCOIN_ALLOCATORS_H + +#include +#include + +#ifdef WIN32 +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +// This is used to attempt to keep keying material out of swap +// Note that VirtualLock does not provide this as a guarantee on Windows, +// but, in practice, memory that has been VirtualLock'd almost never gets written to +// the pagefile except in rare circumstances where memory is extremely low. +#define mlock(p, n) VirtualLock((p), (n)); +#define munlock(p, n) VirtualUnlock((p), (n)); +#else +#include +#include +/* This comes from limits.h if it's not defined there set a sane default */ +#ifndef PAGESIZE +#include +#define PAGESIZE sysconf(_SC_PAGESIZE) +#endif +#define mlock(a,b) \ + mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\ + (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1)))) +#define munlock(a,b) \ + munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\ + (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1)))) +#endif + +// +// Allocator that locks its contents from being paged +// out of memory and clears its contents before deletion. +// +template +struct secure_allocator : public std::allocator +{ + // MSVC8 default copy constructor is broken + typedef std::allocator base; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + typedef typename base::value_type value_type; + secure_allocator() throw() {} + secure_allocator(const secure_allocator& a) throw() : base(a) {} + template + secure_allocator(const secure_allocator& a) throw() : base(a) {} + ~secure_allocator() throw() {} + template struct rebind + { typedef secure_allocator<_Other> other; }; + + T* allocate(std::size_t n, const void *hint = 0) + { + T *p; + p = std::allocator::allocate(n, hint); + if (p != NULL) + mlock(p, sizeof(T) * n); + return p; + } + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) + { + memset(p, 0, sizeof(T) * n); + munlock(p, sizeof(T) * n); + } + std::allocator::deallocate(p, n); + } +}; + + +// +// Allocator that clears its contents before deletion. +// +template +struct zero_after_free_allocator : public std::allocator +{ + // MSVC8 default copy constructor is broken + typedef std::allocator base; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + typedef typename base::value_type value_type; + zero_after_free_allocator() throw() {} + zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} + template + zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} + ~zero_after_free_allocator() throw() {} + template struct rebind + { typedef zero_after_free_allocator<_Other> other; }; + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) + memset(p, 0, sizeof(T) * n); + std::allocator::deallocate(p, n); + } +}; + +// This is exactly like std::string, but with a custom allocator. +typedef std::basic_string, secure_allocator > SecureString; + +#endif diff --git a/src/base58.h b/src/base58.h new file mode 100644 index 0000000..fe59cd9 --- /dev/null +++ b/src/base58.h @@ -0,0 +1,468 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin Developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +// +// Why base-58 instead of standard base-64 encoding? +// - Don't want 0OIl characters that look the same in some fonts and +// could be used to create visually identical looking account numbers. +// - A string with non-alphanumeric characters is not as easily accepted as an account number. +// - E-mail usually won't line-break if there's no punctuation to break at. +// - Doubleclicking selects the whole number as one word if it's all alphanumeric. +// +#ifndef BITCOIN_BASE58_H +#define BITCOIN_BASE58_H + +#include +#include +#include "bignum.h" +#include "key.h" +#include "script.h" + +static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +// Encode a byte sequence as a base58-encoded string +inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) +{ + CAutoBN_CTX pctx; + CBigNum bn58 = 58; + CBigNum bn0 = 0; + + // Convert big endian data to little endian + // Extra zero at the end make sure bignum will interpret as a positive number + std::vector vchTmp(pend-pbegin+1, 0); + reverse_copy(pbegin, pend, vchTmp.begin()); + + // Convert little endian data to bignum + CBigNum bn; + bn.setvch(vchTmp); + + // Convert bignum to std::string + std::string str; + // Expected size increase from base58 conversion is approximately 137% + // use 138% to be safe + str.reserve((pend - pbegin) * 138 / 100 + 1); + CBigNum dv; + CBigNum rem; + while (bn > bn0) + { + if (!BN_div(&dv, &rem, &bn, &bn58, pctx)) + throw bignum_error("EncodeBase58 : BN_div failed"); + bn = dv; + unsigned int c = rem.getulong(); + str += pszBase58[c]; + } + + // Leading zeroes encoded as base58 zeros + for (const unsigned char* p = pbegin; p < pend && *p == 0; p++) + str += pszBase58[0]; + + // Convert little endian std::string to big endian + reverse(str.begin(), str.end()); + return str; +} + +// Encode a byte vector as a base58-encoded string +inline std::string EncodeBase58(const std::vector& vch) +{ + return EncodeBase58(&vch[0], &vch[0] + vch.size()); +} + +// Decode a base58-encoded string psz into byte vector vchRet +// returns true if decoding is successful +inline bool DecodeBase58(const char* psz, std::vector& vchRet) +{ + CAutoBN_CTX pctx; + vchRet.clear(); + CBigNum bn58 = 58; + CBigNum bn = 0; + CBigNum bnChar; + while (isspace(*psz)) + psz++; + + // Convert big endian string to bignum + for (const char* p = psz; *p; p++) + { + const char* p1 = strchr(pszBase58, *p); + if (p1 == NULL) + { + while (isspace(*p)) + p++; + if (*p != '\0') + return false; + break; + } + bnChar.setulong(p1 - pszBase58); + if (!BN_mul(&bn, &bn, &bn58, pctx)) + throw bignum_error("DecodeBase58 : BN_mul failed"); + bn += bnChar; + } + + // Get bignum as little endian data + std::vector vchTmp = bn.getvch(); + + // Trim off sign byte if present + if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) + vchTmp.erase(vchTmp.end()-1); + + // Restore leading zeros + int nLeadingZeros = 0; + for (const char* p = psz; *p == pszBase58[0]; p++) + nLeadingZeros++; + vchRet.assign(nLeadingZeros + vchTmp.size(), 0); + + // Convert little endian data to big endian + reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); + return true; +} + +// Decode a base58-encoded string str into byte vector vchRet +// returns true if decoding is successful +inline bool DecodeBase58(const std::string& str, std::vector& vchRet) +{ + return DecodeBase58(str.c_str(), vchRet); +} + + + + +// Encode a byte vector to a base58-encoded string, including checksum +inline std::string EncodeBase58Check(const std::vector& vchIn) +{ + // add 4-byte hash check to the end + std::vector vch(vchIn); + uint256 hash = Hash(vch.begin(), vch.end()); + vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); + return EncodeBase58(vch); +} + +// Decode a base58-encoded string psz that includes a checksum, into byte vector vchRet +// returns true if decoding is successful +inline bool DecodeBase58Check(const char* psz, std::vector& vchRet) +{ + if (!DecodeBase58(psz, vchRet)) + return false; + if (vchRet.size() < 4) + { + vchRet.clear(); + return false; + } + uint256 hash = Hash(vchRet.begin(), vchRet.end()-4); + if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) + { + vchRet.clear(); + return false; + } + vchRet.resize(vchRet.size()-4); + return true; +} + +// Decode a base58-encoded string str that includes a checksum, into byte vector vchRet +// returns true if decoding is successful +inline bool DecodeBase58Check(const std::string& str, std::vector& vchRet) +{ + return DecodeBase58Check(str.c_str(), vchRet); +} + + + + + +/** Base class for all base58-encoded data */ +class CBase58Data +{ +protected: + // the version byte + unsigned char nVersion; + + // the actually encoded data + std::vector vchData; + + CBase58Data() + { + nVersion = 0; + vchData.clear(); + } + + ~CBase58Data() + { + // zero the memory, as it may contain sensitive data + if (!vchData.empty()) + memset(&vchData[0], 0, vchData.size()); + } + + void SetData(int nVersionIn, const void* pdata, size_t nSize) + { + nVersion = nVersionIn; + vchData.resize(nSize); + if (!vchData.empty()) + memcpy(&vchData[0], pdata, nSize); + } + + void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend) + { + SetData(nVersionIn, (void*)pbegin, pend - pbegin); + } + +public: + bool SetString(const char* psz) + { + std::vector vchTemp; + DecodeBase58Check(psz, vchTemp); + if (vchTemp.empty()) + { + vchData.clear(); + nVersion = 0; + return false; + } + nVersion = vchTemp[0]; + vchData.resize(vchTemp.size() - 1); + if (!vchData.empty()) + memcpy(&vchData[0], &vchTemp[1], vchData.size()); + memset(&vchTemp[0], 0, vchTemp.size()); + return true; + } + + bool SetString(const std::string& str) + { + return SetString(str.c_str()); + } + + std::string ToString() const + { + std::vector vch(1, nVersion); + vch.insert(vch.end(), vchData.begin(), vchData.end()); + return EncodeBase58Check(vch); + } + + int CompareTo(const CBase58Data& b58) const + { + if (nVersion < b58.nVersion) return -1; + if (nVersion > b58.nVersion) return 1; + if (vchData < b58.vchData) return -1; + if (vchData > b58.vchData) return 1; + return 0; + } + + bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; } + bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; } + bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; } + bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; } + bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; } +}; + +/** base58-encoded Bitcoin addresses. + * Public-key-hash-addresses have version 0 (or 111 testnet). + * The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key. + * 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 +{ +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: + enum + { + PUBKEY_ADDRESS = 28, // CasinoCoin addresses start with C + SCRIPT_ADDRESS = 5, + PUBKEY_ADDRESS_TEST = 87, + SCRIPT_ADDRESS_TEST = 196, + }; + + bool Set(const CKeyID &id) { + SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &id, 20); + return true; + } + + bool Set(const CScriptID &id) { + SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &id, 20); + return true; + } + + bool Set(const CTxDestination &dest) + { + return boost::apply_visitor(CBitcoinAddressVisitor(this), dest); + } + + bool IsValid() const + { + unsigned int nExpectedSize = 20; + bool fExpectTestNet = false; + switch(nVersion) + { + case PUBKEY_ADDRESS: + nExpectedSize = 20; // Hash of public key + fExpectTestNet = false; + break; + case SCRIPT_ADDRESS: + nExpectedSize = 20; // Hash of CScript + fExpectTestNet = false; + break; + + case PUBKEY_ADDRESS_TEST: + nExpectedSize = 20; + fExpectTestNet = true; + break; + case SCRIPT_ADDRESS_TEST: + nExpectedSize = 20; + fExpectTestNet = true; + break; + + default: + return false; + } + return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize; + } + + CBitcoinAddress() + { + } + + CBitcoinAddress(const CTxDestination &dest) + { + Set(dest); + } + + CBitcoinAddress(const std::string& strAddress) + { + SetString(strAddress); + } + + CBitcoinAddress(const char* pszAddress) + { + SetString(pszAddress); + } + + 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 +{ +public: + enum + { + PRIVKEY_ADDRESS = CBitcoinAddress::PUBKEY_ADDRESS + 128, + PRIVKEY_ADDRESS_TEST = CBitcoinAddress::PUBKEY_ADDRESS_TEST + 128, + }; + + void SetSecret(const CSecret& vchSecret, bool fCompressed) + { + assert(vchSecret.size() == 32); + SetData(fTestNet ? PRIVKEY_ADDRESS_TEST : PRIVKEY_ADDRESS, &vchSecret[0], vchSecret.size()); + if (fCompressed) + vchData.push_back(1); + } + + CSecret GetSecret(bool &fCompressedOut) + { + CSecret vchSecret; + vchSecret.resize(32); + memcpy(&vchSecret[0], &vchData[0], 32); + fCompressedOut = vchData.size() == 33; + return vchSecret; + } + + bool IsValid() const + { + bool fExpectTestNet = false; + switch(nVersion) + { + case PRIVKEY_ADDRESS: + break; + + case PRIVKEY_ADDRESS_TEST: + fExpectTestNet = true; + break; + + default: + return false; + } + return fExpectTestNet == fTestNet && (vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1)); + } + + bool SetString(const char* pszSecret) + { + return CBase58Data::SetString(pszSecret) && IsValid(); + } + + bool SetString(const std::string& strSecret) + { + return SetString(strSecret.c_str()); + } + + CBitcoinSecret(const CSecret& vchSecret, bool fCompressed) + { + SetSecret(vchSecret, fCompressed); + } + + CBitcoinSecret() + { + } +}; + +#endif diff --git a/src/bignum.h b/src/bignum.h new file mode 100644 index 0000000..cb36a1c --- /dev/null +++ b/src/bignum.h @@ -0,0 +1,550 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_BIGNUM_H +#define BITCOIN_BIGNUM_H + +#include +#include +#include + +#include "util.h" // for uint64 + +/** Errors thrown by the bignum class */ +class bignum_error : public std::runtime_error +{ +public: + explicit bignum_error(const std::string& str) : std::runtime_error(str) {} +}; + + +/** RAII encapsulated BN_CTX (OpenSSL bignum context) */ +class CAutoBN_CTX +{ +protected: + BN_CTX* pctx; + BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; } + +public: + CAutoBN_CTX() + { + pctx = BN_CTX_new(); + if (pctx == NULL) + throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL"); + } + + ~CAutoBN_CTX() + { + if (pctx != NULL) + BN_CTX_free(pctx); + } + + operator BN_CTX*() { return pctx; } + BN_CTX& operator*() { return *pctx; } + BN_CTX** operator&() { return &pctx; } + bool operator!() { return (pctx == NULL); } +}; + + +/** C++ wrapper for BIGNUM (OpenSSL bignum) */ +class CBigNum : public BIGNUM +{ +public: + CBigNum() + { + BN_init(this); + } + + CBigNum(const CBigNum& b) + { + BN_init(this); + if (!BN_copy(this, &b)) + { + BN_clear_free(this); + throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed"); + } + } + + CBigNum& operator=(const CBigNum& b) + { + if (!BN_copy(this, &b)) + throw bignum_error("CBigNum::operator= : BN_copy failed"); + return (*this); + } + + ~CBigNum() + { + BN_clear_free(this); + } + + //CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'. + CBigNum(signed char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int64 n) { BN_init(this); setint64(n); } + CBigNum(unsigned char n) { BN_init(this); setulong(n); } + CBigNum(unsigned short n) { BN_init(this); setulong(n); } + CBigNum(unsigned int n) { BN_init(this); setulong(n); } + CBigNum(unsigned long n) { BN_init(this); setulong(n); } + CBigNum(uint64 n) { BN_init(this); setuint64(n); } + explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); } + + explicit CBigNum(const std::vector& vch) + { + BN_init(this); + setvch(vch); + } + + void setulong(unsigned long n) + { + if (!BN_set_word(this, n)) + throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed"); + } + + unsigned long getulong() const + { + return BN_get_word(this); + } + + unsigned int getuint() const + { + return BN_get_word(this); + } + + int getint() const + { + unsigned long n = BN_get_word(this); + if (!BN_is_negative(this)) + return (n > (unsigned long)std::numeric_limits::max() ? std::numeric_limits::max() : n); + else + return (n > (unsigned long)std::numeric_limits::max() ? std::numeric_limits::min() : -(int)n); + } + + void setint64(int64 sn) + { + unsigned char pch[sizeof(sn) + 6]; + unsigned char* p = pch + 4; + bool fNegative; + uint64 n; + + if (sn < (int64)0) + { + // Since the minimum signed integer cannot be represented as positive so long as its type is signed, and it's not well-defined what happens if you make it unsigned before negating it, we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate + n = -(sn + 1); + ++n; + fNegative = true; + } else { + n = sn; + fNegative = false; + } + + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = (fNegative ? 0x80 : 0); + else if (fNegative) + c |= 0x80; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + void setuint64(uint64 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + void setuint256(uint256 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + unsigned char* pbegin = (unsigned char*)&n; + unsigned char* psrc = pbegin + sizeof(n); + while (psrc != pbegin) + { + unsigned char c = *(--psrc); + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize >> 0) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + uint256 getuint256() + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return 0; + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + if (vch.size() > 4) + vch[4] &= 0x7f; + uint256 n = 0; + for (unsigned int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--) + ((unsigned char*)&n)[i] = vch[j]; + return n; + } + + void setvch(const std::vector& vch) + { + std::vector vch2(vch.size() + 4); + unsigned int nSize = vch.size(); + // BIGNUM's byte stream format expects 4 bytes of + // big endian size data info at the front + vch2[0] = (nSize >> 24) & 0xff; + vch2[1] = (nSize >> 16) & 0xff; + vch2[2] = (nSize >> 8) & 0xff; + vch2[3] = (nSize >> 0) & 0xff; + // swap data to big endian + reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4); + BN_mpi2bn(&vch2[0], vch2.size(), this); + } + + std::vector getvch() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize <= 4) + return std::vector(); + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + vch.erase(vch.begin(), vch.begin() + 4); + reverse(vch.begin(), vch.end()); + return vch; + } + + CBigNum& SetCompact(unsigned int nCompact) + { + unsigned int nSize = nCompact >> 24; + std::vector vch(4 + nSize); + vch[3] = nSize; + if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff; + if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff; + if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff; + BN_mpi2bn(&vch[0], vch.size(), this); + return *this; + } + + unsigned int GetCompact() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + std::vector vch(nSize); + nSize -= 4; + BN_bn2mpi(this, &vch[0]); + unsigned int nCompact = nSize << 24; + if (nSize >= 1) nCompact |= (vch[4] << 16); + if (nSize >= 2) nCompact |= (vch[5] << 8); + if (nSize >= 3) nCompact |= (vch[6] << 0); + return nCompact; + } + + void SetHex(const std::string& str) + { + // skip 0x + const char* psz = str.c_str(); + while (isspace(*psz)) + psz++; + bool fNegative = false; + if (*psz == '-') + { + fNegative = true; + psz++; + } + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + while (isspace(*psz)) + psz++; + + // hex string to bignum + static signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + *this = 0; + while (isxdigit(*psz)) + { + *this <<= 4; + int n = phexdigit[(unsigned char)*psz++]; + *this += n; + } + if (fNegative) + *this = 0 - *this; + } + + std::string ToString(int nBase=10) const + { + CAutoBN_CTX pctx; + CBigNum bnBase = nBase; + CBigNum bn0 = 0; + std::string str; + CBigNum bn = *this; + BN_set_negative(&bn, false); + CBigNum dv; + CBigNum rem; + if (BN_cmp(&bn, &bn0) == 0) + return "0"; + while (BN_cmp(&bn, &bn0) > 0) + { + if (!BN_div(&dv, &rem, &bn, &bnBase, pctx)) + throw bignum_error("CBigNum::ToString() : BN_div failed"); + bn = dv; + unsigned int c = rem.getulong(); + str += "0123456789abcdef"[c]; + } + if (BN_is_negative(this)) + str += "-"; + reverse(str.begin(), str.end()); + return str; + } + + std::string GetHex() const + { + return ToString(16); + } + + unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const + { + return ::GetSerializeSize(getvch(), nType, nVersion); + } + + template + void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const + { + ::Serialize(s, getvch(), nType, nVersion); + } + + template + void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) + { + std::vector vch; + ::Unserialize(s, vch, nType, nVersion); + setvch(vch); + } + + + bool operator!() const + { + return BN_is_zero(this); + } + + CBigNum& operator+=(const CBigNum& b) + { + if (!BN_add(this, this, &b)) + throw bignum_error("CBigNum::operator+= : BN_add failed"); + return *this; + } + + CBigNum& operator-=(const CBigNum& b) + { + *this = *this - b; + return *this; + } + + CBigNum& operator*=(const CBigNum& b) + { + CAutoBN_CTX pctx; + if (!BN_mul(this, this, &b, pctx)) + throw bignum_error("CBigNum::operator*= : BN_mul failed"); + return *this; + } + + CBigNum& operator/=(const CBigNum& b) + { + *this = *this / b; + return *this; + } + + CBigNum& operator%=(const CBigNum& b) + { + *this = *this % b; + return *this; + } + + CBigNum& operator<<=(unsigned int shift) + { + if (!BN_lshift(this, this, shift)) + throw bignum_error("CBigNum:operator<<= : BN_lshift failed"); + return *this; + } + + CBigNum& operator>>=(unsigned int shift) + { + // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number + // if built on ubuntu 9.04 or 9.10, probably depends on version of openssl + CBigNum a = 1; + a <<= shift; + if (BN_cmp(&a, this) > 0) + { + *this = 0; + return *this; + } + + if (!BN_rshift(this, this, shift)) + throw bignum_error("CBigNum:operator>>= : BN_rshift failed"); + return *this; + } + + + CBigNum& operator++() + { + // prefix operator + if (!BN_add(this, this, BN_value_one())) + throw bignum_error("CBigNum::operator++ : BN_add failed"); + return *this; + } + + const CBigNum operator++(int) + { + // postfix operator + const CBigNum ret = *this; + ++(*this); + return ret; + } + + CBigNum& operator--() + { + // prefix operator + CBigNum r; + if (!BN_sub(&r, this, BN_value_one())) + throw bignum_error("CBigNum::operator-- : BN_sub failed"); + *this = r; + return *this; + } + + const CBigNum operator--(int) + { + // postfix operator + const CBigNum ret = *this; + --(*this); + return ret; + } + + + friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b); +}; + + + +inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_add(&r, &a, &b)) + throw bignum_error("CBigNum::operator+ : BN_add failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_sub(&r, &a, &b)) + throw bignum_error("CBigNum::operator- : BN_sub failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a) +{ + CBigNum r(a); + BN_set_negative(&r, !BN_is_negative(&r)); + return r; +} + +inline const CBigNum operator*(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mul(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator* : BN_mul failed"); + return r; +} + +inline const CBigNum operator/(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_div(&r, NULL, &a, &b, pctx)) + throw bignum_error("CBigNum::operator/ : BN_div failed"); + return r; +} + +inline const CBigNum operator%(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mod(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator% : BN_div failed"); + return r; +} + +inline const CBigNum operator<<(const CBigNum& a, unsigned int shift) +{ + CBigNum r; + if (!BN_lshift(&r, &a, shift)) + throw bignum_error("CBigNum:operator<< : BN_lshift failed"); + return r; +} + +inline const CBigNum operator>>(const CBigNum& a, unsigned int shift) +{ + CBigNum r = a; + r >>= shift; + return r; +} + +inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); } +inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); } +inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); } +inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); } +inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); } +inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); } + +#endif diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp new file mode 100644 index 0000000..93eeef6 --- /dev/null +++ b/src/bitcoinrpc.cpp @@ -0,0 +1,3399 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 The CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "main.h" +#include "wallet.h" +#include "db.h" +#include "walletdb.h" +#include "net.h" +#include "init.h" +#include "ui_interface.h" +#include "base58.h" +#include "bitcoinrpc.h" + +#undef printf +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define printf OutputDebugStringF + +using namespace std; +using namespace boost; +using namespace boost::asio; +using namespace json_spirit; + +void ThreadRPCServer2(void* parg); + +static std::string strRPCUserColonPass; + +static int64 nWalletUnlockTime; +static CCriticalSection cs_nWalletUnlockTime; + +extern Value getconnectioncount(const Array& params, bool fHelp); // in rpcnet.cpp +extern Value getpeerinfo(const Array& params, bool fHelp); +extern Value dumpprivkey(const Array& params, bool fHelp); // in rpcdump.cpp +extern Value importprivkey(const Array& params, bool fHelp); +extern Value getrawtransaction(const Array& params, bool fHelp); // in rcprawtransaction.cpp +extern Value listunspent(const Array& params, bool fHelp); +extern Value createrawtransaction(const Array& params, bool fHelp); +extern Value decoderawtransaction(const Array& params, bool fHelp); +extern Value signrawtransaction(const Array& params, bool fHelp); +extern Value sendrawtransaction(const Array& params, bool fHelp); + +const Object emptyobj; + +void ThreadRPCServer3(void* parg); + +Object JSONRPCError(int code, const string& message) +{ + Object error; + error.push_back(Pair("code", code)); + error.push_back(Pair("message", message)); + return error; +} +void RPCTypeCheck(const Array& params, + const list& typesExpected) +{ + unsigned int i = 0; + BOOST_FOREACH(Value_type t, typesExpected) + { + if (params.size() <= i) + break; + + const Value& v = params[i]; + if (v.type() != t) + { + string err = strprintf("Expected type %s, got %s", + Value_type_name[t], Value_type_name[v.type()]); + throw JSONRPCError(-3, err); + } + i++; + } +} +void RPCTypeCheck(const Object& o, + const map& typesExpected) +{ + BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) + { + const Value& v = find_value(o, t.first); + if (v.type() == null_type) + throw JSONRPCError(-3, strprintf("Missing %s", t.first.c_str())); + if (v.type() != t.second) + { + string err = strprintf("Expected type %s for %s, got %s", + Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]); + throw JSONRPCError(-3, err); + } + } +} + +double GetDifficulty(const CBlockIndex* blockindex = NULL) +{ + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + if (blockindex == NULL) + { + if (pindexBest == NULL) + return 1.0; + else + blockindex = pindexBest; + } + + int nShift = (blockindex->nBits >> 24) & 0xff; + + double dDiff = + (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff); + + while (nShift < 29) + { + dDiff *= 256.0; + nShift++; + } + while (nShift > 29) + { + dDiff /= 256.0; + nShift--; + } + + return dDiff; +} + + +int64 AmountFromValue(const Value& value) +{ + double dAmount = value.get_real(); + if (dAmount <= 0.0 || dAmount > 84000000.0) + throw JSONRPCError(-3, "Invalid amount"); + int64 nAmount = roundint64(dAmount * COIN); + if (!MoneyRange(nAmount)) + throw JSONRPCError(-3, "Invalid amount"); + return nAmount; +} + +Value ValueFromAmount(int64 amount) +{ + return (double)amount / (double)COIN; +} + +std::string +HexBits(unsigned int nBits) +{ + union { + int32_t nBits; + char cBits[4]; + } uBits; + uBits.nBits = htonl((int32_t)nBits); + return HexStr(BEGIN(uBits.cBits), END(uBits.cBits)); +} + +std::string +HelpRequiringPassphrase() +{ + return pwalletMain->IsCrypted() + ? "\nrequires wallet passphrase to be set with walletpassphrase first" + : ""; +} + +void +EnsureWalletIsUnlocked() +{ + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); +} + +void WalletTxToJSON(const CWalletTx& wtx, Object& entry) +{ + int confirms = wtx.GetDepthInMainChain(); + entry.push_back(Pair("confirmations", confirms)); + if (confirms) + { + entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); + entry.push_back(Pair("blockindex", wtx.nIndex)); + } + entry.push_back(Pair("txid", wtx.GetHash().GetHex())); + entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime())); + BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) + entry.push_back(Pair(item.first, item.second)); +} + +string AccountFromValue(const Value& value) +{ + string strAccount = value.get_str(); + if (strAccount == "*") + throw JSONRPCError(-11, "Invalid account name"); + return strAccount; +} + +Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) +{ + Object result; + result.push_back(Pair("hash", block.GetHash().GetHex())); + CMerkleTx txGen(block.vtx[0]); + txGen.SetMerkleBranch(&block); + result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain())); + result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); + Array txs; + BOOST_FOREACH(const CTransaction&tx, block.vtx) + txs.push_back(tx.GetHash().GetHex()); + result.push_back(Pair("tx", txs)); + result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime())); + result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce)); + result.push_back(Pair("bits", HexBits(block.nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + if (blockindex->pnext) + result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex())); + return result; +} + +/// Note: This interface may still be subject to change. + +string CRPCTable::help(string strCommand) const +{ + string strRet; + set setDone; + for (map::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi) + { + const CRPCCommand *pcmd = mi->second; + string strMethod = mi->first; + // We already filter duplicates, but these deprecated screw up the sort order + if (strMethod.find("label") != string::npos) + continue; + if (strCommand != "" && strMethod != strCommand) + continue; + try + { + Array params; + rpcfn_type pfn = pcmd->actor; + if (setDone.insert(pfn).second) + (*pfn)(params, true); + } + catch (std::exception& e) + { + // Help text is returned in an exception + string strHelp = string(e.what()); + if (strCommand == "") + if (strHelp.find('\n') != string::npos) + strHelp = strHelp.substr(0, strHelp.find('\n')); + strRet += strHelp + "\n"; + } + } + if (strRet == "") + strRet = strprintf("help: unknown command: %s\n", strCommand.c_str()); + strRet = strRet.substr(0,strRet.size()-1); + return strRet; +} + +Value help(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "help [command]\n" + "List commands, or get help for a command."); + + string strCommand; + if (params.size() > 0) + strCommand = params[0].get_str(); + + return tableRPC.help(strCommand); +} + + +Value stop(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "stop\n" + "Stop CasinoCoin server."); + // Shutdown will take long enough that the response should get back + StartShutdown(); + return "CasinoCoin server has now stopped running!"; +} + + +Value getblockcount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getblockcount\n" + "Returns the number of blocks in the longest block chain."); + + return nBestHeight; +} + + +Value getdifficulty(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getdifficulty\n" + "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); + + return GetDifficulty(); +} + + +// CasinoCoin: Return average network hashes per second based on last number of blocks. +Value GetNetworkHashPS(int lookup) { + if (pindexBest == NULL) + return 0; + + // If lookup is -1, then use blocks since last difficulty change. + if (lookup <= 0) + lookup = pindexBest->nHeight % 2016 + 1; + + // If lookup is larger than chain, then set it to chain length. + if (lookup > pindexBest->nHeight) + lookup = pindexBest->nHeight; + + CBlockIndex* pindexPrev = pindexBest; + for (int i = 0; i < lookup; i++) + pindexPrev = pindexPrev->pprev; + + double timeDiff = pindexBest->GetBlockTime() - pindexPrev->GetBlockTime(); + double timePerBlock = timeDiff / lookup; + + return (boost::int64_t)(((double)GetDifficulty() * pow(2.0, 32)) / timePerBlock); +} + +Value getnetworkhashps(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getnetworkhashps [blocks]\n" + "Returns the estimated network hashes per second based on the last 8 blocks.\n" + "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change."); + + return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120); +} + + +Value getgenerate(const Array& params, bool fHelp) +{ + throw runtime_error("The getgenerate command has been disabled."); + return false; + + if (fHelp || params.size() != 0) + throw runtime_error( + "getgenerate\n" + "Returns true or false."); + + return GetBoolArg("-gen"); +} + + +Value setgenerate(const Array& params, bool fHelp) +{ + throw runtime_error("The setgenerate command has been disabled."); + return Value::null; + + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "setgenerate [genproclimit]\n" + " is true or false to turn generation on or off.\n" + "Generation is limited to [genproclimit] processors, -1 is unlimited."); + + bool fGenerate = true; + if (params.size() > 0) + fGenerate = params[0].get_bool(); + + if (params.size() > 1) + { + int nGenProcLimit = params[1].get_int(); + mapArgs["-genproclimit"] = itostr(nGenProcLimit); + if (nGenProcLimit == 0) + fGenerate = false; + } + mapArgs["-gen"] = (fGenerate ? "1" : "0"); + + GenerateBitcoins(fGenerate, pwalletMain); + return Value::null; +} + + +Value gethashespersec(const Array& params, bool fHelp) +{ + // Disabled mining, so therefore we will return 0. + return (boost::int64_t)0; + + if (fHelp || params.size() != 0) + throw runtime_error( + "gethashespersec\n" + "Returns a recent hashes per second performance measurement while generating."); + + if (GetTimeMillis() - nHPSTimerStart > 8000) + return (boost::int64_t)0; + return (boost::int64_t)dHashesPerSec; +} + + +Value getinfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "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)); + obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); + 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", (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())); + obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize())); + obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); + obj.push_back(Pair("mininput", ValueFromAmount(nMinimumInputValue))); + if (pwalletMain->IsCrypted()) + obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000)); + obj.push_back(Pair("errors", GetWarnings("statusbar"))); + return obj; +} + + +Value getmininginfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getmininginfo\n" + "Returns an object containing mining-related information."); + + Object obj; + obj.push_back(Pair("blocks", (int)nBestHeight)); + obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize)); + obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx)); + obj.push_back(Pair("difficulty", (double)GetDifficulty())); + obj.push_back(Pair("errors", GetWarnings("statusbar"))); + obj.push_back(Pair("generate", GetBoolArg("-gen"))); + obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); + obj.push_back(Pair("hashespersec", gethashespersec(params, false))); + obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); + obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); + obj.push_back(Pair("testnet", fTestNet)); + return obj; +} + + +Value getnewaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getnewaddress [account]\n" + "Returns a new CasinoCoin address for receiving payments. " + "If [account] is specified (recommended), it is added to the address book " + "so payments received with the address will be credited to [account]."); + + // Parse the account first so we don't generate a key if there's an error + string strAccount; + if (params.size() > 0) + strAccount = AccountFromValue(params[0]); + + if (!pwalletMain->IsLocked()) + pwalletMain->TopUpKeyPool(); + + // Generate a new key that is added to wallet + CPubKey newKey; + if (!pwalletMain->GetKeyFromPool(newKey, false)) + throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); + CKeyID keyID = newKey.GetID(); + + pwalletMain->SetAddressBookName(keyID, strAccount); + + return CBitcoinAddress(keyID).ToString(); +} + + +CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) +{ + CWalletDB walletdb(pwalletMain->strWalletFile); + + CAccount account; + walletdb.ReadAccount(strAccount, account); + + bool bKeyUsed = false; + + // Check if the current key has been used + if (account.vchPubKey.IsValid()) + { + CScript scriptPubKey; + scriptPubKey.SetDestination(account.vchPubKey.GetID()); + for (map::iterator it = pwalletMain->mapWallet.begin(); + it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); + ++it) + { + const CWalletTx& wtx = (*it).second; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + bKeyUsed = true; + } + } + + // Generate a new key + 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(account.vchPubKey.GetID(), strAccount); + walletdb.WriteAccount(strAccount, account); + } + + return CBitcoinAddress(account.vchPubKey.GetID()); +} + +Value getaccountaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaccountaddress \n" + "Returns the current CasinoCoin address for receiving payments to this account."); + + // Parse the account first so we don't generate a key if there's an error + string strAccount = AccountFromValue(params[0]); + + Value ret; + + ret = GetAccountAddress(strAccount).ToString(); + + return ret; +} + + + +Value setaccount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "setaccount \n" + "Sets the account associated with the given address."); + + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(-5, "Invalid CasinoCoin address"); + + + string strAccount; + if (params.size() > 1) + 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.Get())) + { + string strOldAccount = pwalletMain->mapAddressBook[address.Get()]; + if (address == GetAccountAddress(strOldAccount)) + GetAccountAddress(strOldAccount, true); + } + + pwalletMain->SetAddressBookName(address.Get(), strAccount); + + return Value::null; +} + + +Value getaccount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaccount \n" + "Returns the account associated with the given address."); + + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(-5, "Invalid CasinoCoin address"); + + string strAccount; + map::iterator mi = pwalletMain->mapAddressBook.find(address.Get()); + if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) + strAccount = (*mi).second; + return strAccount; +} + + +Value getaddressesbyaccount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getaddressesbyaccount \n" + "Returns the list of addresses for the given account."); + + string strAccount = AccountFromValue(params[0]); + + // Find all addresses that have the given account + Array ret; + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + const string& strName = item.second; + if (strName == strAccount) + ret.push_back(address.ToString()); + } + return ret; +} + +Value settxfee(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1) + throw runtime_error( + "settxfee \n" + " is a real and is rounded to the nearest 0.00000001"); + + // Amount + int64 nAmount = 0; + if (params[0].get_real() != 0.0) + nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts + + nTransactionFee = nAmount; + return true; +} + +Value setmininput(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1) + throw runtime_error( + "setmininput \n" + " is a real and is rounded to the nearest 0.00000001"); + + // Amount + int64 nAmount = 0; + if (params[0].get_real() != 0.0) + nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts + + nMinimumInputValue = nAmount; + return true; +} + +Value sendtoaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 4) + throw runtime_error( + "sendtoaddress [comment] [comment-to]\n" + " is a real and is rounded to the nearest 0.00000001" + + HelpRequiringPassphrase()); + + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(-5, "Invalid CasinoCoin address"); + + // Amount + int64 nAmount = AmountFromValue(params[1]); + + // Wallet comments + CWalletTx wtx; + if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty()) + wtx.mapValue["comment"] = params[2].get_str(); + if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + wtx.mapValue["to"] = params[3].get_str(); + + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); + + string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); + if (strError != "") + throw JSONRPCError(-4, strError); + + return wtx.GetHash().GetHex(); +} + +Value signmessage(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error( + "signmessage \n" + "Sign a message with the private key of an address"); + + EnsureWalletIsUnlocked(); + + string strAddress = params[0].get_str(); + string strMessage = params[1].get_str(); + + CBitcoinAddress addr(strAddress); + 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(keyID, key)) + throw JSONRPCError(-4, "Private key not available"); + + CDataStream ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << strMessage; + + vector vchSig; + if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) + throw JSONRPCError(-5, "Sign failed"); + + return EncodeBase64(&vchSig[0], vchSig.size()); +} + +Value verifymessage(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 3) + throw runtime_error( + "verifymessage \n" + "Verify a signed message"); + + string strAddress = params[0].get_str(); + string strSign = params[1].get_str(); + string strMessage = params[2].get_str(); + + CBitcoinAddress addr(strAddress); + 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 vchSig = DecodeBase64(strSign.c_str(), &fInvalid); + + if (fInvalid) + throw JSONRPCError(-5, "Malformed base64 encoding"); + + CDataStream ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << strMessage; + + CKey key; + if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig)) + return false; + + return (key.GetPubKey().GetID() == keyID); +} + + +Value getreceivedbyaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getreceivedbyaddress [minconf=1]\n" + "Returns the total amount received by in transactions with at least [minconf] confirmations."); + + // CasinoCoin address + CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); + CScript scriptPubKey; + if (!address.IsValid()) + throw JSONRPCError(-5, "Invalid CasinoCoin address"); + scriptPubKey.SetDestination(address.Get()); + if (!IsMine(*pwalletMain,scriptPubKey)) + return (double)0.0; + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + // Tally + int64 nAmount = 0; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + + return ValueFromAmount(nAmount); +} + + +void GetAccountAddresses(string strAccount, set& setAddress) +{ + BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& item, pwalletMain->mapAddressBook) + { + 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) + throw runtime_error( + "getreceivedbyaccount [minconf=1]\n" + "Returns the total amount received by addresses with in transactions with at least [minconf] confirmations."); + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + // Get the set of pub keys assigned to account + string strAccount = AccountFromValue(params[0]); + set setAddress; + GetAccountAddresses(strAccount, setAddress); + + // Tally + int64 nAmount = 0; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + } + + return (double)nAmount / (double)COIN; +} + + +int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth) +{ + int64 nBalance = 0; + + // Tally wallet transactions + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (!wtx.IsFinal()) + continue; + + int64 nGenerated, nReceived, nSent, nFee; + wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee); + + if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) + nBalance += nReceived; + nBalance += nGenerated - nSent - nFee; + } + + // Tally internal accounting entries + nBalance += walletdb.GetAccountCreditDebit(strAccount); + + return nBalance; +} + +int64 GetAccountBalance(const string& strAccount, int nMinDepth) +{ + CWalletDB walletdb(pwalletMain->strWalletFile); + return GetAccountBalance(walletdb, strAccount, nMinDepth); +} + + +Value getbalance(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "getbalance [account] [minconf=1]\n" + "If [account] is not specified, returns the server's total available balance.\n" + "If [account] is specified, returns the balance in the account."); + + if (params.size() == 0) + return ValueFromAmount(pwalletMain->GetBalance()); + + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + if (params[0].get_str() == "*") { + // Calculate total balance a different way from GetBalance() + // (GetBalance() sums up all unspent TxOuts) + // getbalance and getbalance '*' should always return the same number. + int64 nBalance = 0; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (!wtx.IsFinal()) + continue; + + int64 allGeneratedImmature, allGeneratedMature, allFee; + allGeneratedImmature = allGeneratedMature = allFee = 0; + string strSentAccount; + list > listReceived; + list > listSent; + wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); + if (wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived) + nBalance += r.second; + } + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent) + nBalance -= r.second; + nBalance -= allFee; + nBalance += allGeneratedMature; + } + return ValueFromAmount(nBalance); + } + + string strAccount = AccountFromValue(params[0]); + + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + + return ValueFromAmount(nBalance); +} + + +Value movecmd(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 3 || params.size() > 5) + throw runtime_error( + "move [minconf=1] [comment]\n" + "Move from one account in your wallet to another."); + + string strFrom = AccountFromValue(params[0]); + string strTo = AccountFromValue(params[1]); + int64 nAmount = AmountFromValue(params[2]); + if (params.size() > 3) + // unused parameter, used to be nMinDepth, keep type-checking it though + (void)params[3].get_int(); + string strComment; + if (params.size() > 4) + strComment = params[4].get_str(); + + CWalletDB walletdb(pwalletMain->strWalletFile); + if (!walletdb.TxnBegin()) + throw JSONRPCError(-20, "database error"); + + int64 nNow = GetAdjustedTime(); + + // Debit + CAccountingEntry debit; + debit.strAccount = strFrom; + debit.nCreditDebit = -nAmount; + debit.nTime = nNow; + debit.strOtherAccount = strTo; + debit.strComment = strComment; + walletdb.WriteAccountingEntry(debit); + + // Credit + CAccountingEntry credit; + credit.strAccount = strTo; + credit.nCreditDebit = nAmount; + credit.nTime = nNow; + credit.strOtherAccount = strFrom; + credit.strComment = strComment; + walletdb.WriteAccountingEntry(credit); + + if (!walletdb.TxnCommit()) + throw JSONRPCError(-20, "database error"); + + return true; +} + + +Value sendfrom(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 3 || params.size() > 6) + throw runtime_error( + "sendfrom [minconf=1] [comment] [comment-to]\n" + " is a real and is rounded to the nearest 0.00000001" + + HelpRequiringPassphrase()); + + string strAccount = AccountFromValue(params[0]); + CBitcoinAddress address(params[1].get_str()); + if (!address.IsValid()) + throw JSONRPCError(-5, "Invalid CasinoCoin address"); + int64 nAmount = AmountFromValue(params[2]); + int nMinDepth = 1; + if (params.size() > 3) + nMinDepth = params[3].get_int(); + + CWalletTx wtx; + wtx.strFromAccount = strAccount; + if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty()) + wtx.mapValue["comment"] = params[4].get_str(); + if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty()) + wtx.mapValue["to"] = params[5].get_str(); + + EnsureWalletIsUnlocked(); + + // Check funds + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + if (nAmount > nBalance) + throw JSONRPCError(-6, "Account has insufficient funds"); + + // Send + string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); + if (strError != "") + throw JSONRPCError(-4, strError); + + return wtx.GetHash().GetHex(); +} + + +Value sendmany(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 4) + throw runtime_error( + "sendmany {address:amount,...} [minconf=1] [comment]\n" + "amounts are double-precision floating point numbers" + + HelpRequiringPassphrase()); + + string strAccount = AccountFromValue(params[0]); + Object sendTo = params[1].get_obj(); + int nMinDepth = 1; + if (params.size() > 2) + nMinDepth = params[2].get_int(); + + CWalletTx wtx; + wtx.strFromAccount = strAccount; + if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + wtx.mapValue["comment"] = params[3].get_str(); + + set setAddress; + vector > vecSend; + + int64 totalAmount = 0; + BOOST_FOREACH(const Pair& s, sendTo) + { + CBitcoinAddress address(s.name_); + if (!address.IsValid()) + throw JSONRPCError(-5, string("Invalid CasinoCoin address:")+s.name_); + + if (setAddress.count(address)) + throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_); + setAddress.insert(address); + + CScript scriptPubKey; + scriptPubKey.SetDestination(address.Get()); + int64 nAmount = AmountFromValue(s.value_); + totalAmount += nAmount; + + vecSend.push_back(make_pair(scriptPubKey, nAmount)); + } + + EnsureWalletIsUnlocked(); + + // Check funds + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + if (totalAmount > nBalance) + throw JSONRPCError(-6, "Account has insufficient funds"); + + // Send + CReserveKey keyChange(pwalletMain); + int64 nFeeRequired = 0; + bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); + if (!fCreated) + { + if (totalAmount + nFeeRequired > pwalletMain->GetBalance()) + throw JSONRPCError(-6, "Insufficient funds"); + throw JSONRPCError(-4, "Transaction creation failed"); + } + if (!pwalletMain->CommitTransaction(wtx, keyChange)) + throw JSONRPCError(-4, "Transaction commit failed"); + + return wtx.GetHash().GetHex(); +} + +Value addmultisigaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 3) + { + string msg = "addmultisigaddress <'[\"key\",\"key\"]'> [account]\n" + "Add a nrequired-to-sign multisignature address to the wallet\"\n" + "each key is a CasinoCoin address or hex-encoded public key\n" + "If [account] is specified, assign address to [account]."; + throw runtime_error(msg); + } + + int nRequired = params[0].get_int(); + const Array& keys = params[1].get_array(); + string strAccount; + if (params.size() > 2) + strAccount = AccountFromValue(params[2]); + + // Gather public keys + if (nRequired < 1) + throw runtime_error("a multisignature address must require at least one key to redeem"); + if ((int)keys.size() < nRequired) + throw runtime_error( + strprintf("not enough keys supplied " + "(got %d keys, but need at least %d to redeem)", keys.size(), nRequired)); + std::vector pubkeys; + pubkeys.resize(keys.size()); + for (unsigned int i = 0; i < keys.size(); i++) + { + const std::string& ks = keys[i].get_str(); + + // Case 1: CasinoCoin address and we have full public key: + CBitcoinAddress address(ks); + if (address.IsValid()) + { + CKeyID keyID; + if (!address.GetKeyID(keyID)) + throw runtime_error( + 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.IsValid() || !pubkeys[i].SetPubKey(vchPubKey)) + throw runtime_error(" Invalid public key: "+ks); + } + + // Case 2: hex public key + else if (IsHex(ks)) + { + CPubKey vchPubKey(ParseHex(ks)); + if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey)) + throw runtime_error(" Invalid public key: "+ks); + } + else + { + throw runtime_error(" Invalid public key: "+ks); + } + } + + // Construct using pay-to-script-hash: + CScript inner; + inner.SetMultisig(nRequired, pubkeys); + CScriptID innerID = inner.GetID(); + pwalletMain->AddCScript(inner); + + pwalletMain->SetAddressBookName(innerID, strAccount); + return CBitcoinAddress(innerID).ToString(); +} + + +struct tallyitem +{ + int64 nAmount; + int nConf; + tallyitem() + { + nAmount = 0; + nConf = std::numeric_limits::max(); + } +}; + +Value ListReceived(const Array& params, bool fByAccounts) +{ + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + // Whether to include empty accounts + bool fIncludeEmpty = false; + if (params.size() > 1) + fIncludeEmpty = params[1].get_bool(); + + // Tally + map mapTally; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + int nDepth = wtx.GetDepthInMainChain(); + if (nDepth < nMinDepth) + continue; + + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + CTxDestination address; + if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address)) + continue; + + tallyitem& item = mapTally[address]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); + } + } + + // Reply + Array ret; + map mapAccountTally; + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + const string& strAccount = item.second; + map::iterator it = mapTally.find(address); + if (it == mapTally.end() && !fIncludeEmpty) + continue; + + int64 nAmount = 0; + int nConf = std::numeric_limits::max(); + if (it != mapTally.end()) + { + nAmount = (*it).second.nAmount; + nConf = (*it).second.nConf; + } + + if (fByAccounts) + { + tallyitem& item = mapAccountTally[strAccount]; + item.nAmount += nAmount; + item.nConf = min(item.nConf, nConf); + } + else + { + Object obj; + obj.push_back(Pair("address", address.ToString())); + obj.push_back(Pair("account", strAccount)); + obj.push_back(Pair("amount", ValueFromAmount(nAmount))); + obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); + ret.push_back(obj); + } + } + + if (fByAccounts) + { + for (map::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it) + { + int64 nAmount = (*it).second.nAmount; + int nConf = (*it).second.nConf; + Object obj; + obj.push_back(Pair("account", (*it).first)); + obj.push_back(Pair("amount", ValueFromAmount(nAmount))); + obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); + ret.push_back(obj); + } + } + + return ret; +} + +Value listreceivedbyaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "listreceivedbyaddress [minconf=1] [includeempty=false]\n" + "[minconf] is the minimum number of confirmations before payments are included.\n" + "[includeempty] whether to include addresses that haven't received any payments.\n" + "Returns an array of objects containing:\n" + " \"address\" : receiving address\n" + " \"account\" : the account of the receiving address\n" + " \"amount\" : total amount received by the address\n" + " \"confirmations\" : number of confirmations of the most recent transaction included"); + + return ListReceived(params, false); +} + +Value listreceivedbyaccount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "listreceivedbyaccount [minconf=1] [includeempty=false]\n" + "[minconf] is the minimum number of confirmations before payments are included.\n" + "[includeempty] whether to include accounts that haven't received any payments.\n" + "Returns an array of objects containing:\n" + " \"account\" : the account of the receiving addresses\n" + " \"amount\" : total amount received by addresses with this account\n" + " \"confirmations\" : number of confirmations of the most recent transaction included"); + + return ListReceived(params, true); +} + +void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret) +{ + int64 nGeneratedImmature, nGeneratedMature, nFee; + string strSentAccount; + list > listReceived; + list > listSent; + + wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); + + bool fAllAccounts = (strAccount == string("*")); + + // Generated blocks assigned to account "" + if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount == "")) + { + Object entry; + entry.push_back(Pair("account", string(""))); + if (nGeneratedImmature) + { + entry.push_back(Pair("category", wtx.GetDepthInMainChain() ? "immature" : "orphan")); + entry.push_back(Pair("amount", ValueFromAmount(nGeneratedImmature))); + } + else + { + entry.push_back(Pair("category", "generate")); + entry.push_back(Pair("amount", ValueFromAmount(nGeneratedMature))); + } + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + + // Sent + if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent) + { + Object entry; + entry.push_back(Pair("account", strSentAccount)); + 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))); + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + } + + // Received + if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived) + { + string account; + if (pwalletMain->mapAddressBook.count(r.first)) + account = pwalletMain->mapAddressBook[r.first]; + if (fAllAccounts || (account == strAccount)) + { + Object entry; + entry.push_back(Pair("account", account)); + 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) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + } + } +} + +void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) +{ + bool fAllAccounts = (strAccount == string("*")); + + if (fAllAccounts || acentry.strAccount == strAccount) + { + Object entry; + entry.push_back(Pair("account", acentry.strAccount)); + entry.push_back(Pair("category", "move")); + entry.push_back(Pair("time", (boost::int64_t)acentry.nTime)); + entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit))); + entry.push_back(Pair("otheraccount", acentry.strOtherAccount)); + entry.push_back(Pair("comment", acentry.strComment)); + ret.push_back(entry); + } +} + +Value listtransactions(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 3) + throw runtime_error( + "listtransactions [account] [count=10] [from=0]\n" + "Returns up to [count] most recent transactions skipping the first [from] transactions for account [account]."); + + string strAccount = "*"; + if (params.size() > 0) + strAccount = params[0].get_str(); + int nCount = 10; + if (params.size() > 1) + nCount = params[1].get_int(); + int nFrom = 0; + if (params.size() > 2) + nFrom = params[2].get_int(); + + if (nCount < 0) + throw JSONRPCError(-8, "Negative count"); + if (nFrom < 0) + throw JSONRPCError(-8, "Negative from"); + + Array ret; + CWalletDB walletdb(pwalletMain->strWalletFile); + + // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap. + typedef pair TxPair; + typedef multimap TxItems; + TxItems txByTime; + + // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry + // would make this much faster for applications that do this a lot. + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + CWalletTx* wtx = &((*it).second); + txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0))); + } + list acentries; + walletdb.ListAccountCreditDebit(strAccount, acentries); + BOOST_FOREACH(CAccountingEntry& entry, acentries) + { + txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); + } + + // iterate backwards until we have nCount items to return: + for (TxItems::reverse_iterator it = txByTime.rbegin(); it != txByTime.rend(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx != 0) + ListTransactions(*pwtx, strAccount, 0, true, ret); + CAccountingEntry *const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); + + if ((int)ret.size() >= (nCount+nFrom)) break; + } + // ret is newest to oldest + + if (nFrom > (int)ret.size()) + nFrom = ret.size(); + if ((nFrom + nCount) > (int)ret.size()) + nCount = ret.size() - nFrom; + Array::iterator first = ret.begin(); + std::advance(first, nFrom); + Array::iterator last = ret.begin(); + std::advance(last, nFrom+nCount); + + if (last != ret.end()) ret.erase(last, ret.end()); + if (first != ret.begin()) ret.erase(ret.begin(), first); + + std::reverse(ret.begin(), ret.end()); // Return oldest to newest + + return ret; +} + +Value listaccounts(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "listaccounts [minconf=1]\n" + "Returns Object that has account names as keys, account balances as values."); + + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + map mapAccountBalances; + BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) { + if (IsMine(*pwalletMain, entry.first)) // This address belongs to me + mapAccountBalances[entry.second] = 0; + } + + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + int64 nGeneratedImmature, nGeneratedMature, nFee; + string strSentAccount; + list > listReceived; + list > listSent; + wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); + mapAccountBalances[strSentAccount] -= nFee; + BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent) + mapAccountBalances[strSentAccount] -= s.second; + if (wtx.GetDepthInMainChain() >= nMinDepth) + { + mapAccountBalances[""] += nGeneratedMature; + BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived) + if (pwalletMain->mapAddressBook.count(r.first)) + mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; + else + mapAccountBalances[""] += r.second; + } + } + + list acentries; + CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries); + BOOST_FOREACH(const CAccountingEntry& entry, acentries) + mapAccountBalances[entry.strAccount] += entry.nCreditDebit; + + Object ret; + BOOST_FOREACH(const PAIRTYPE(string, int64)& accountBalance, mapAccountBalances) { + ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); + } + return ret; +} + +Value listsinceblock(const Array& params, bool fHelp) +{ + if (fHelp) + throw runtime_error( + "listsinceblock [blockhash] [target-confirmations]\n" + "Get all transactions in blocks since block [blockhash], or all transactions if omitted"); + + CBlockIndex *pindex = NULL; + int target_confirms = 1; + + if (params.size() > 0) + { + uint256 blockId = 0; + + blockId.SetHex(params[0].get_str()); + pindex = CBlockLocator(blockId).GetBlockIndex(); + } + + if (params.size() > 1) + { + target_confirms = params[1].get_int(); + + if (target_confirms < 1) + throw JSONRPCError(-8, "Invalid parameter"); + } + + int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1; + + Array transactions; + + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) + { + CWalletTx tx = (*it).second; + + if (depth == -1 || tx.GetDepthInMainChain() < depth) + ListTransactions(tx, "*", 0, true, transactions); + } + + uint256 lastblock; + + if (target_confirms == 1) + { + lastblock = hashBestChain; + } + else + { + int target_height = pindexBest->nHeight + 1 - target_confirms; + + CBlockIndex *block; + for (block = pindexBest; + block && block->nHeight > target_height; + block = block->pprev) { } + + lastblock = block ? block->GetBlockHash() : 0; + } + + Object ret; + ret.push_back(Pair("transactions", transactions)); + ret.push_back(Pair("lastblock", lastblock.GetHex())); + + return ret; +} + +Value gettransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "gettransaction \n" + "Get detailed information about in-wallet transaction "); + + uint256 hash; + hash.SetHex(params[0].get_str()); + + Object entry; + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(-5, "Invalid or non-wallet transaction id"); + const CWalletTx& wtx = pwalletMain->mapWallet[hash]; + + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0); + + entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); + if (wtx.IsFromMe()) + entry.push_back(Pair("fee", ValueFromAmount(nFee))); + + WalletTxToJSON(wtx, entry); + + Array details; + ListTransactions(wtx, "*", 0, false, details); + entry.push_back(Pair("details", details)); + + return entry; +} + + +Value backupwallet(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "backupwallet \n" + "Safely copies wallet.dat to destination, which can be a directory or a path with filename."); + + string strDest = params[0].get_str(); + BackupWallet(*pwalletMain, strDest); + + return Value::null; +} + + +Value keypoolrefill(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 0) + throw runtime_error( + "keypoolrefill\n" + "Fills the keypool." + + HelpRequiringPassphrase()); + + EnsureWalletIsUnlocked(); + + pwalletMain->TopUpKeyPool(); + + if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100)) + throw JSONRPCError(-4, "Error refreshing keypool."); + + return Value::null; +} + + +void ThreadTopUpKeyPool(void* parg) +{ + // Make this thread recognisable as the key-topping-up thread + RenameThread("bitcoin-key-top"); + + pwalletMain->TopUpKeyPool(); +} + +void ThreadCleanWalletPassphrase(void* parg) +{ + // Make this thread recognisable as the wallet relocking thread + RenameThread("bitcoin-lock-wa"); + + int64 nMyWakeTime = GetTimeMillis() + *((int64*)parg) * 1000; + + ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime); + + if (nWalletUnlockTime == 0) + { + nWalletUnlockTime = nMyWakeTime; + + do + { + if (nWalletUnlockTime==0) + break; + int64 nToSleep = nWalletUnlockTime - GetTimeMillis(); + if (nToSleep <= 0) + break; + + LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime); + Sleep(nToSleep); + ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime); + + } while(1); + + if (nWalletUnlockTime) + { + nWalletUnlockTime = 0; + pwalletMain->Lock(); + } + } + else + { + if (nWalletUnlockTime < nMyWakeTime) + nWalletUnlockTime = nMyWakeTime; + } + + LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime); + + delete (int64*)parg; +} + +Value walletpassphrase(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + throw runtime_error( + "walletpassphrase \n" + "Stores the wallet decryption key in memory for seconds."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrase was called."); + + if (!pwalletMain->IsLocked()) + throw JSONRPCError(-17, "Error: Wallet is already unlocked."); + + // Note that the walletpassphrase is stored in params[0] which is not mlock()ed + SecureString strWalletPass; + strWalletPass.reserve(100); + // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) + // Alternately, find a way to make params[0] mlock()'d to begin with. + strWalletPass = params[0].get_str().c_str(); + + if (strWalletPass.length() > 0) + { + if (!pwalletMain->Unlock(strWalletPass)) + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + } + else + throw runtime_error( + "walletpassphrase \n" + "Stores the wallet decryption key in memory for seconds."); + + CreateThread(ThreadTopUpKeyPool, NULL); + int64* pnSleepTime = new int64(params[1].get_int64()); + CreateThread(ThreadCleanWalletPassphrase, pnSleepTime); + + return Value::null; +} + + +Value walletpassphrasechange(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + throw runtime_error( + "walletpassphrasechange \n" + "Changes the wallet passphrase from to ."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); + + // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string) + // Alternately, find a way to make params[0] mlock()'d to begin with. + SecureString strOldWalletPass; + strOldWalletPass.reserve(100); + strOldWalletPass = params[0].get_str().c_str(); + + SecureString strNewWalletPass; + strNewWalletPass.reserve(100); + strNewWalletPass = params[1].get_str().c_str(); + + if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1) + throw runtime_error( + "walletpassphrasechange \n" + "Changes the wallet passphrase from to ."); + + if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + + return Value::null; +} + + +Value walletlock(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) + throw runtime_error( + "walletlock\n" + "Removes the wallet encryption key from memory, locking the wallet.\n" + "After calling this method, you will need to call walletpassphrase again\n" + "before being able to call any methods which require the wallet to be unlocked."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called."); + + { + LOCK(cs_nWalletUnlockTime); + pwalletMain->Lock(); + nWalletUnlockTime = 0; + } + + return Value::null; +} + + +Value encryptwallet(const Array& params, bool fHelp) +{ + if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) + throw runtime_error( + "encryptwallet \n" + "Encrypts the wallet with ."); + if (fHelp) + return true; + if (pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called."); + + // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) + // Alternately, find a way to make params[0] mlock()'d to begin with. + SecureString strWalletPass; + strWalletPass.reserve(100); + strWalletPass = params[0].get_str().c_str(); + + if (strWalletPass.length() < 1) + throw runtime_error( + "encryptwallet \n" + "Encrypts the wallet with ."); + + if (!pwalletMain->EncryptWallet(strWalletPass)) + throw JSONRPCError(-16, "Error: Failed to encrypt the wallet."); + + // 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: + StartShutdown(); + return "wallet encrypted; CasinoCoin server stopping, restart to run with encrypted wallet"; +} + +class DescribeAddressVisitor : public boost::static_visitor +{ +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 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) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "validateaddress \n" + "Return information about ."); + + CBitcoinAddress address(params[0].get_str()); + bool isValid = address.IsValid(); + + Object ret; + ret.push_back(Pair("isvalid", isValid)); + if (isValid) + { + CTxDestination dest = address.Get(); + string currentAddress = address.ToString(); + ret.push_back(Pair("address", currentAddress)); + 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()); + } + if (pwalletMain->mapAddressBook.count(dest)) + ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest])); + } + return ret; +} + +Value getworkex(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "getworkex [data, coinbase]\n" + "If [data, coinbase] is not specified, returns extended work data.\n" + ); + + if (vNodes.empty()) + throw JSONRPCError(-9, "CasinoCoin is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(-10, "CasinoCoin is downloading blocks..."); + + typedef map > mapNewBlock_t; + static mapNewBlock_t mapNewBlock; + static vector vNewBlock; + static CReserveKey reservekey(pwalletMain); + + if (params.size() == 0) + { + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)) + { + if (pindexPrev != pindexBest) + { + // Deallocate old blocks since they're obsolete now + mapNewBlock.clear(); + BOOST_FOREACH(CBlock* pblock, vNewBlock) + delete pblock; + vNewBlock.clear(); + } + nTransactionsUpdatedLast = nTransactionsUpdated; + pindexPrev = pindexBest; + nStart = GetTime(); + + // Create new block + pblock = CreateNewBlock(reservekey); + if (!pblock) + throw JSONRPCError(-7, "Out of memory"); + vNewBlock.push_back(pblock); + } + + // Update nTime + pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + pblock->nNonce = 0; + + // Update nExtraNonce + static unsigned int nExtraNonce = 0; + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); + + // Save + mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig); + + // Prebuild hash buffers + char pmidstate[32]; + char pdata[128]; + char phash1[64]; + FormatHashBuffers(pblock, pmidstate, pdata, phash1); + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + CTransaction coinbaseTx = pblock->vtx[0]; + std::vector merkle = pblock->GetMerkleBranch(0); + + Object result; + result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); + result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << coinbaseTx; + result.push_back(Pair("coinbase", HexStr(ssTx.begin(), ssTx.end()))); + + Array merkle_arr; + printf("DEBUG: merkle size %i\n", merkle.size()); + + BOOST_FOREACH(uint256 merkleh, merkle) { + printf("%s\n", merkleh.ToString().c_str()); + merkle_arr.push_back(HexStr(BEGIN(merkleh), END(merkleh))); + } + + result.push_back(Pair("merkle", merkle_arr)); + + + return result; + } + else + { + // Parse parameters + vector vchData = ParseHex(params[0].get_str()); + vector coinbase; + + if(params.size() == 2) + coinbase = ParseHex(params[1].get_str()); + + if (vchData.size() != 128) + throw JSONRPCError(-8, "Invalid parameter"); + + CBlock* pdata = (CBlock*)&vchData[0]; + + // Byte reverse + for (int i = 0; i < 128/4; i++) + ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]); + + // Get saved block + if (!mapNewBlock.count(pdata->hashMerkleRoot)) + return false; + CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first; + + pblock->nTime = pdata->nTime; + pblock->nNonce = pdata->nNonce; + + if(coinbase.size() == 0) + pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second; + else + CDataStream(coinbase, SER_NETWORK, PROTOCOL_VERSION) >> pblock->vtx[0]; // FIXME - HACK! + + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + + return CheckWork(pblock, *pwalletMain, reservekey); + } +} + +Value getwork(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getwork [data]\n" + "If [data] is not specified, returns formatted hash data to work on:\n" + " \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated + " \"data\" : block data\n" + " \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated + " \"target\" : little endian hash target\n" + "If [data] is specified, tries to solve the block and returns true if it was successful."); + + if (vNodes.empty()) + throw JSONRPCError(-9, "CasinoCoin is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(-10, "CasinoCoin is downloading blocks..."); + + typedef map > mapNewBlock_t; + static mapNewBlock_t mapNewBlock; // FIXME: thread safety + static vector vNewBlock; + static CReserveKey reservekey(pwalletMain); + + if (params.size() == 0) + { + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)) + { + if (pindexPrev != pindexBest) + { + // Deallocate old blocks since they're obsolete now + mapNewBlock.clear(); + BOOST_FOREACH(CBlock* pblock, vNewBlock) + delete pblock; + vNewBlock.clear(); + } + nTransactionsUpdatedLast = nTransactionsUpdated; + pindexPrev = pindexBest; + nStart = GetTime(); + + // Create new block + pblock = CreateNewBlock(reservekey); + if (!pblock) + throw JSONRPCError(-7, "Out of memory"); + vNewBlock.push_back(pblock); + } + + // Update nTime + pblock->UpdateTime(pindexPrev); + pblock->nNonce = 0; + + // Update nExtraNonce + static unsigned int nExtraNonce = 0; + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); + + // Save + mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig); + + // Prebuild hash buffers + char pmidstate[32]; + char pdata[128]; + char phash1[64]; + FormatHashBuffers(pblock, pmidstate, pdata, phash1); + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + Object result; + result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated + result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); + result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated + result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); + result.push_back(Pair("algorithm", "scrypt:1024,1,1")); // CasinoCoin: specify that we should use the scrypt algorithm + return result; + } + else + { + // Parse parameters + vector vchData = ParseHex(params[0].get_str()); + if (vchData.size() != 128) + throw JSONRPCError(-8, "Invalid parameter"); + CBlock* pdata = (CBlock*)&vchData[0]; + + // Byte reverse + for (int i = 0; i < 128/4; i++) + ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]); + + // Get saved block + if (!mapNewBlock.count(pdata->hashMerkleRoot)) + return false; + CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first; + + pblock->nTime = pdata->nTime; + pblock->nNonce = pdata->nNonce; + pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second; + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + + return CheckWork(pblock, *pwalletMain, reservekey); + } +} + + +Value getblocktemplate(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getblocktemplate [params]\n" + "If [params] does not contain a \"data\" key, returns data needed to construct a block to work on:\n" + " \"version\" : block version\n" + " \"previousblockhash\" : hash of current highest block\n" + " \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n" + " \"coinbaseaux\" : data that should be included in coinbase\n" + " \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n" + " \"target\" : hash target\n" + " \"mintime\" : minimum timestamp appropriate for next block\n" + " \"curtime\" : current timestamp\n" + " \"mutable\" : list of ways the block template may be changed\n" + " \"noncerange\" : range of valid nonces\n" + " \"sigoplimit\" : limit of sigops in blocks\n" + " \"sizelimit\" : limit of block size\n" + " \"bits\" : compressed target of next block\n" + " \"height\" : height of the next block\n" + "If [params] does contain a \"data\" key, tries to solve the block and returns null if it was successful (and \"rejected\" if not)\n" + "See https://en.bitcoin.it/wiki/BIP_0022 for full specification."); + + const Object& oparam = params[0].get_obj(); + std::string strMode; + { + const Value& modeval = find_value(oparam, "mode"); + if (modeval.type() == str_type) + strMode = modeval.get_str(); + else + if (find_value(oparam, "data").type() == null_type) + strMode = "template"; + else + strMode = "submit"; + } + + if (strMode == "template") + { + if (vNodes.empty()) + throw JSONRPCError(-9, "CasinoCoin is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(-10, "CasinoCoin is downloading blocks..."); + + static CReserveKey reservekey(pwalletMain); + + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5)) + { + nTransactionsUpdatedLast = nTransactionsUpdated; + pindexPrev = pindexBest; + nStart = GetTime(); + + // Create new block + if(pblock) + delete pblock; + pblock = CreateNewBlock(reservekey); + if (!pblock) + throw JSONRPCError(-7, "Out of memory"); + } + + // Update nTime + pblock->UpdateTime(pindexPrev); + pblock->nNonce = 0; + + Array transactions; + map setTxIndex; + int i = 0; + CTxDB txdb("r"); + BOOST_FOREACH (CTransaction& tx, pblock->vtx) + { + uint256 txHash = tx.GetHash(); + setTxIndex[txHash] = i++; + + if (tx.IsCoinBase()) + continue; + + Object entry; + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end()))); + + entry.push_back(Pair("hash", txHash.GetHex())); + + MapPrevTx mapInputs; + map mapUnused; + bool fInvalid = false; + if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) + { + entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut()))); + + Array deps; + BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs) + { + if (setTxIndex.count(inp.first)) + deps.push_back(setTxIndex[inp.first]); + } + entry.push_back(Pair("depends", deps)); + + int64_t nSigOps = tx.GetLegacySigOpCount(); + nSigOps += tx.GetP2SHSigOpCount(mapInputs); + entry.push_back(Pair("sigops", nSigOps)); + } + + transactions.push_back(entry); + } + + Object aux; + aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + static Array aMutable; + if (aMutable.empty()) + { + aMutable.push_back("time"); + aMutable.push_back("transactions"); + aMutable.push_back("prevblock"); + } + + Object result; + result.push_back(Pair("version", pblock->nVersion)); + result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); + result.push_back(Pair("transactions", transactions)); + result.push_back(Pair("coinbaseaux", aux)); + result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); + result.push_back(Pair("target", hashTarget.GetHex())); + result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); + result.push_back(Pair("mutable", aMutable)); + result.push_back(Pair("noncerange", "00000000ffffffff")); + result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE)); + result.push_back(Pair("curtime", (int64_t)pblock->nTime)); + result.push_back(Pair("bits", HexBits(pblock->nBits))); + result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); + + return result; + } + else + if (strMode == "submit") + { + // Parse parameters + CDataStream ssBlock(ParseHex(find_value(oparam, "data").get_str()), SER_NETWORK, PROTOCOL_VERSION); + CBlock pblock; + ssBlock >> pblock; + + bool fAccepted = ProcessBlock(NULL, &pblock); + + return fAccepted ? Value::null : "rejected"; + } + + throw JSONRPCError(-8, "Invalid mode"); +} + +Value getrawmempool(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getrawmempool\n" + "Returns all transaction ids in memory pool."); + + vector vtxid; + mempool.queryHashes(vtxid); + + Array a; + BOOST_FOREACH(const uint256& hash, vtxid) + a.push_back(hash.ToString()); + + return a; +} + +Value getblockhash(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getblockhash \n" + "Returns hash of block in best-block-chain at ."); + + int nHeight = params[0].get_int(); + if (nHeight < 0 || nHeight > nBestHeight) + throw runtime_error("Block number out of range."); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hashBestChain]; + while (pblockindex->nHeight > nHeight) + pblockindex = pblockindex->pprev; + return pblockindex->phashBlock->GetHex(); +} + +Value getblock(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getblock \n" + "Returns details of a block with given block-hash."); + + std::string strHash = params[0].get_str(); + uint256 hash(strHash); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(-5, "Block not found"); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + block.ReadFromDisk(pblockindex, true); + + return blockToJSON(block, pblockindex); +} + + + + + + + +// +// Call Table +// + + +static const CRPCCommand vRPCCommands[] = +{ // name function safe mode? + // ------------------------ ----------------------- ---------- + { "help", &help, true }, + { "stop", &stop, true }, + { "getblockcount", &getblockcount, true }, + { "getconnectioncount", &getconnectioncount, true }, + { "getpeerinfo", &getpeerinfo, true }, + { "getdifficulty", &getdifficulty, true }, + { "getnetworkhashps", &getnetworkhashps, true }, + { "getgenerate", &getgenerate, true }, + { "setgenerate", &setgenerate, true }, + { "gethashespersec", &gethashespersec, true }, + { "getinfo", &getinfo, true }, + { "getmininginfo", &getmininginfo, true }, + { "getnewaddress", &getnewaddress, true }, + { "getaccountaddress", &getaccountaddress, true }, + { "setaccount", &setaccount, true }, + { "getaccount", &getaccount, false }, + { "getaddressesbyaccount", &getaddressesbyaccount, true }, + { "sendtoaddress", &sendtoaddress, false }, + { "getreceivedbyaddress", &getreceivedbyaddress, false }, + { "getreceivedbyaccount", &getreceivedbyaccount, false }, + { "listreceivedbyaddress", &listreceivedbyaddress, false }, + { "listreceivedbyaccount", &listreceivedbyaccount, false }, + { "backupwallet", &backupwallet, true }, + { "keypoolrefill", &keypoolrefill, true }, + { "walletpassphrase", &walletpassphrase, true }, + { "walletpassphrasechange", &walletpassphrasechange, false }, + { "walletlock", &walletlock, true }, + { "encryptwallet", &encryptwallet, false }, + { "validateaddress", &validateaddress, true }, + { "getbalance", &getbalance, false }, + { "move", &movecmd, false }, + { "sendfrom", &sendfrom, false }, + { "sendmany", &sendmany, false }, + { "addmultisigaddress", &addmultisigaddress, false }, + { "getrawmempool", &getrawmempool, true }, + { "getblock", &getblock, false }, + { "getblockhash", &getblockhash, false }, + { "gettransaction", &gettransaction, false }, + { "listtransactions", &listtransactions, false }, + { "signmessage", &signmessage, false }, + { "verifymessage", &verifymessage, false }, + { "getwork", &getwork, true }, + { "getworkex", &getworkex, true }, + { "listaccounts", &listaccounts, false }, + { "settxfee", &settxfee, false }, + { "setmininput", &setmininput, false }, + { "getblocktemplate", &getblocktemplate, true }, + { "listsinceblock", &listsinceblock, false }, + { "dumpprivkey", &dumpprivkey, false }, + { "importprivkey", &importprivkey, false }, + { "listunspent", &listunspent, false }, + { "getrawtransaction", &getrawtransaction, false }, + { "createrawtransaction", &createrawtransaction, false }, + { "decoderawtransaction", &decoderawtransaction, false }, + { "signrawtransaction", &signrawtransaction, false }, + { "sendrawtransaction", &sendrawtransaction, false }, +}; + +CRPCTable::CRPCTable() +{ + unsigned int vcidx; + for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++) + { + const CRPCCommand *pcmd; + + pcmd = &vRPCCommands[vcidx]; + mapCommands[pcmd->name] = pcmd; + } +} + +const CRPCCommand *CRPCTable::operator[](string name) const +{ + map::const_iterator it = mapCommands.find(name); + if (it == mapCommands.end()) + return NULL; + return (*it).second; +} + +// +// HTTP protocol +// +// This ain't Apache. We're just using HTTP header for the length field +// and to be compatible with other JSON-RPC implementations. +// + +string HTTPPost(const string& strMsg, const map& mapRequestHeaders) +{ + ostringstream s; + s << "POST / HTTP/1.1\r\n" + << "User-Agent: casinocoin-json-rpc/" << FormatFullVersion() << "\r\n" + << "Host: 127.0.0.1\r\n" + << "Content-Type: application/json\r\n" + << "Content-Length: " << strMsg.size() << "\r\n" + << "Connection: close\r\n" + << "Accept: application/json\r\n"; + BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders) + s << item.first << ": " << item.second << "\r\n"; + s << "\r\n" << strMsg; + + return s.str(); +} + +string rfc1123Time() +{ + char buffer[64]; + time_t now; + time(&now); + struct tm* now_gmt = gmtime(&now); + string locale(setlocale(LC_TIME, NULL)); + setlocale(LC_TIME, "C"); // we want posix (aka "C") weekday/month strings + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt); + setlocale(LC_TIME, locale.c_str()); + return string(buffer); +} + +static string HTTPReply(int nStatus, const string& strMsg, bool keepalive) +{ + if (nStatus == 401) + return strprintf("HTTP/1.0 401 Authorization Required\r\n" + "Date: %s\r\n" + "Server: casinocoin-json-rpc/%s\r\n" + "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 296\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "Error\r\n" + "\r\n" + "\r\n" + "

401 Unauthorized.

\r\n" + "\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str()); + const char *cStatus; + if (nStatus == 200) cStatus = "OK"; + else if (nStatus == 400) cStatus = "Bad Request"; + else if (nStatus == 403) cStatus = "Forbidden"; + else if (nStatus == 404) cStatus = "Not Found"; + else if (nStatus == 500) cStatus = "Internal Server Error"; + else cStatus = ""; + return strprintf( + "HTTP/1.1 %d %s\r\n" + "Date: %s\r\n" + "Connection: %s\r\n" + "Content-Length: %d\r\n" + "Content-Type: application/json\r\n" + "Server: casinocoin-json-rpc/%s\r\n" + "\r\n" + "%s", + nStatus, + cStatus, + rfc1123Time().c_str(), + keepalive ? "keep-alive" : "close", + strMsg.size(), + FormatFullVersion().c_str(), + strMsg.c_str()); +} + +int ReadHTTPStatus(std::basic_istream& stream, int &proto) +{ + string str; + getline(stream, str); + vector vWords; + boost::split(vWords, str, boost::is_any_of(" ")); + if (vWords.size() < 2) + return 500; + proto = 0; + const char *ver = strstr(str.c_str(), "HTTP/1."); + if (ver != NULL) + proto = atoi(ver+7); + return atoi(vWords[1].c_str()); +} + +int ReadHTTPHeader(std::basic_istream& stream, map& mapHeadersRet) +{ + int nLen = 0; + loop + { + string str; + std::getline(stream, str); + if (str.empty() || str == "\r") + break; + string::size_type nColon = str.find(":"); + if (nColon != string::npos) + { + string strHeader = str.substr(0, nColon); + boost::trim(strHeader); + boost::to_lower(strHeader); + string strValue = str.substr(nColon+1); + boost::trim(strValue); + mapHeadersRet[strHeader] = strValue; + if (strHeader == "content-length") + nLen = atoi(strValue.c_str()); + } + } + return nLen; +} + +int ReadHTTP(std::basic_istream& stream, map& mapHeadersRet, string& strMessageRet) +{ + mapHeadersRet.clear(); + strMessageRet = ""; + + // Read status + int nProto = 0; + int nStatus = ReadHTTPStatus(stream, nProto); + + // Read header + int nLen = ReadHTTPHeader(stream, mapHeadersRet); + if (nLen < 0 || nLen > (int)MAX_SIZE) + return 500; + + // Read message + if (nLen > 0) + { + vector vch(nLen); + stream.read(&vch[0], nLen); + strMessageRet = string(vch.begin(), vch.end()); + } + + string sConHdr = mapHeadersRet["connection"]; + + if ((sConHdr != "close") && (sConHdr != "keep-alive")) + { + if (nProto >= 1) + mapHeadersRet["connection"] = "keep-alive"; + else + mapHeadersRet["connection"] = "close"; + } + + return nStatus; +} + +bool HTTPAuthorized(map& mapHeaders) +{ + string strAuth = mapHeaders["authorization"]; + if (strAuth.substr(0,6) != "Basic ") + return false; + string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); + string strUserPass = DecodeBase64(strUserPass64); + return strUserPass == strRPCUserColonPass; +} + +// +// JSON-RPC protocol. CasinoCoin speaks version 1.0 for maximum compatibility, +// but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were +// unspecified (HTTP errors and contents of 'error'). +// +// 1.0 spec: http://json-rpc.org/wiki/specification +// 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http +// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx +// + +string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) +{ + Object request; + request.push_back(Pair("method", strMethod)); + request.push_back(Pair("params", params)); + request.push_back(Pair("id", id)); + return write_string(Value(request), false) + "\n"; +} + +Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) +{ + Object reply; + if (error.type() != null_type) + reply.push_back(Pair("result", Value::null)); + else + reply.push_back(Pair("result", result)); + reply.push_back(Pair("error", error)); + reply.push_back(Pair("id", id)); + return reply; +} + +string JSONRPCReply(const Value& result, const Value& error, const Value& id) +{ + Object reply = JSONRPCReplyObj(result, error, id); + return write_string(Value(reply), false) + "\n"; +} + +void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) +{ + // Send error reply from json-rpc error object + int nStatus = 500; + int code = find_value(objError, "code").get_int(); + if (code == -32600) nStatus = 400; + else if (code == -32601) nStatus = 404; + string strReply = JSONRPCReply(Value::null, objError, id); + stream << HTTPReply(nStatus, strReply, false) << std::flush; +} + +bool ClientAllowed(const boost::asio::ip::address& address) +{ + // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses + if (address.is_v6() + && (address.to_v6().is_v4_compatible() + || address.to_v6().is_v4_mapped())) + return ClientAllowed(address.to_v6().to_v4()); + + if (address == asio::ip::address_v4::loopback() + || address == asio::ip::address_v6::loopback() + || (address.is_v4() + // Chech whether IPv4 addresses match 127.0.0.0/8 (loopback subnet) + && (address.to_v4().to_ulong() & 0xff000000) == 0x7f000000)) + return true; + + const string strAddress = address.to_string(); + const vector& vAllow = mapMultiArgs["-rpcallowip"]; + BOOST_FOREACH(string strAllow, vAllow) + if (WildcardMatch(strAddress, strAllow)) + return true; + return false; +} + +// +// IOStream device that speaks SSL but can also speak non-SSL +// +template +class SSLIOStreamDevice : public iostreams::device { +public: + SSLIOStreamDevice(asio::ssl::stream &streamIn, bool fUseSSLIn) : stream(streamIn) + { + fUseSSL = fUseSSLIn; + fNeedHandshake = fUseSSLIn; + } + + void handshake(ssl::stream_base::handshake_type role) + { + if (!fNeedHandshake) return; + fNeedHandshake = false; + stream.handshake(role); + } + std::streamsize read(char* s, std::streamsize n) + { + handshake(ssl::stream_base::server); // HTTPS servers read first + if (fUseSSL) return stream.read_some(asio::buffer(s, n)); + return stream.next_layer().read_some(asio::buffer(s, n)); + } + std::streamsize write(const char* s, std::streamsize n) + { + handshake(ssl::stream_base::client); // HTTPS clients write first + if (fUseSSL) return asio::write(stream, asio::buffer(s, n)); + return asio::write(stream.next_layer(), asio::buffer(s, n)); + } + bool connect(const std::string& server, const std::string& port) + { + ip::tcp::resolver resolver(stream.get_io_service()); + ip::tcp::resolver::query query(server.c_str(), port.c_str()); + ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); + ip::tcp::resolver::iterator end; + boost::system::error_code error = asio::error::host_not_found; + while (error && endpoint_iterator != end) + { + stream.lowest_layer().close(); + stream.lowest_layer().connect(*endpoint_iterator++, error); + } + if (error) + return false; + return true; + } + +private: + bool fNeedHandshake; + bool fUseSSL; + asio::ssl::stream& stream; +}; + +class AcceptedConnection +{ +public: + virtual ~AcceptedConnection() {} + + virtual std::iostream& stream() = 0; + virtual std::string peer_address_to_string() const = 0; + virtual void close() = 0; +}; + +template +class AcceptedConnectionImpl : public AcceptedConnection +{ +public: + AcceptedConnectionImpl( + asio::io_service& io_service, + ssl::context &context, + bool fUseSSL) : + sslStream(io_service, context), + _d(sslStream, fUseSSL), + _stream(_d) + { + } + + virtual std::iostream& stream() + { + return _stream; + } + + virtual std::string peer_address_to_string() const + { + return peer.address().to_string(); + } + + virtual void close() + { + _stream.close(); + } + + typename Protocol::endpoint peer; + asio::ssl::stream sslStream; + +private: + SSLIOStreamDevice _d; + iostreams::stream< SSLIOStreamDevice > _stream; +}; + +void ThreadRPCServer(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg)); + + // Make this thread recognisable as the RPC listener + RenameThread("bitcoin-rpclist"); + + try + { + vnThreadsRunning[THREAD_RPCLISTENER]++; + ThreadRPCServer2(parg); + vnThreadsRunning[THREAD_RPCLISTENER]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_RPCLISTENER]--; + PrintException(&e, "ThreadRPCServer()"); + } catch (...) { + vnThreadsRunning[THREAD_RPCLISTENER]--; + PrintException(NULL, "ThreadRPCServer()"); + } + printf("ThreadRPCServer exited\n"); +} + +// Forward declaration required for RPCListen +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + bool fUseSSL, + AcceptedConnection* conn, + const boost::system::error_code& error); + +/** + * Sets up I/O resources to accept and handle a new connection. + */ +template +static void RPCListen(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + const bool fUseSSL) +{ + // Accept connection + AcceptedConnectionImpl* conn = new AcceptedConnectionImpl(acceptor->get_io_service(), context, fUseSSL); + + acceptor->async_accept( + conn->sslStream.lowest_layer(), + conn->peer, + boost::bind(&RPCAcceptHandler, + acceptor, + boost::ref(context), + fUseSSL, + conn, + boost::asio::placeholders::error)); +} + +/** + * Accept and handle incoming connection. + */ +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + const bool fUseSSL, + AcceptedConnection* conn, + const boost::system::error_code& error) +{ + vnThreadsRunning[THREAD_RPCLISTENER]++; + + // Immediately start accepting new connections, except when we're canceled or our socket is closed. + if (error != asio::error::operation_aborted + && acceptor->is_open()) + RPCListen(acceptor, context, fUseSSL); + + AcceptedConnectionImpl* tcp_conn = dynamic_cast< AcceptedConnectionImpl* >(conn); + + // TODO: Actually handle errors + if (error) + { + delete conn; + } + + // Restrict callers by IP. It is important to + // do this before starting client thread, to filter out + // certain DoS and misbehaving clients. + else if (tcp_conn + && !ClientAllowed(tcp_conn->peer.address())) + { + // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake. + if (!fUseSSL) + conn->stream() << HTTPReply(403, "", false) << std::flush; + delete conn; + } + + // start HTTP client thread + else if (!CreateThread(ThreadRPCServer3, conn)) { + printf("Failed to create RPC server client thread\n"); + delete conn; + } + + vnThreadsRunning[THREAD_RPCLISTENER]--; +} + +void ThreadRPCServer2(void* parg) +{ + printf("ThreadRPCServer started\n"); + + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + if (mapArgs["-rpcpassword"] == "") + { + unsigned char rand_pwd[32]; + RAND_bytes(rand_pwd, 32); + string strWhatAmI = "To use casinocoind"; + if (mapArgs.count("-server")) + strWhatAmI = strprintf(_("To use the %s option"), "\"-server\""); + else if (mapArgs.count("-daemon")) + strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\""); + uiInterface.ThreadSafeMessageBox(strprintf( + _("%s, you must set a rpcpassword in the configuration file:\n %s\n" + "It is recommended you use the following random password:\n" + "rpcuser=casinocoinrpc\n" + "rpcpassword=%s\n" + "(you do not need to remember this password)\n" + "If the file does not exist, create it with owner-readable-only file permissions.\n"), + strWhatAmI.c_str(), + GetConfigFile().string().c_str(), + EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()), + _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); + StartShutdown(); + return; + } + + const bool fUseSSL = GetBoolArg("-rpcssl"); + + asio::io_service io_service; + + ssl::context context(io_service, ssl::context::sslv23); + if (fUseSSL) + { + context.set_options(ssl::context::no_sslv2); + + filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); + if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile; + if (filesystem::exists(pathCertFile)) context.use_certificate_chain_file(pathCertFile.string()); + else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str()); + + filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); + if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile; + if (filesystem::exists(pathPKFile)) context.use_private_key_file(pathPKFile.string(), ssl::context::pem); + else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str()); + + string strCiphers = GetArg("-rpcsslciphers", "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH"); + SSL_CTX_set_cipher_list(context.impl(), strCiphers.c_str()); + } + + // Try a dual IPv6/IPv4 socket, falling back to separate IPv4 and IPv6 sockets + const bool loopback = !mapArgs.count("-rpcallowip"); + asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any(); + ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 47970)); + boost::system::error_code v6_only_error; + boost::shared_ptr acceptor(new ip::tcp::acceptor(io_service)); + + boost::signals2::signal StopRequests; + + bool fListening = false; + std::string strerr; + try + { + acceptor->open(endpoint.protocol()); + acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + + // Try making the socket dual IPv6/IPv4 (if listening on the "any" address) + acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error); + + acceptor->bind(endpoint); + acceptor->listen(socket_base::max_connections); + + RPCListen(acceptor, context, fUseSSL); + // Cancel outstanding listen-requests for this acceptor when shutting down + StopRequests.connect(signals2::slot( + static_cast(&ip::tcp::acceptor::close), acceptor.get()) + .track(acceptor)); + + fListening = true; + } + catch(boost::system::system_error &e) + { + strerr = strprintf(_("An error occurred while setting up the RPC port %i for listening on IPv6, falling back to IPv4: %s"), endpoint.port(), e.what()); + } + + try { + // If dual IPv6/IPv4 failed (or we're opening loopback interfaces only), open IPv4 separately + if (!fListening || loopback || v6_only_error) + { + bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any(); + endpoint.address(bindAddress); + + acceptor.reset(new ip::tcp::acceptor(io_service)); + acceptor->open(endpoint.protocol()); + acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + acceptor->bind(endpoint); + acceptor->listen(socket_base::max_connections); + + RPCListen(acceptor, context, fUseSSL); + // Cancel outstanding listen-requests for this acceptor when shutting down + StopRequests.connect(signals2::slot( + static_cast(&ip::tcp::acceptor::close), acceptor.get()) + .track(acceptor)); + + fListening = true; + + } + } + catch(boost::system::system_error &e) + { + strerr = strprintf(_("An error occurred while setting up the RPC port %i for listening on IPv4: %s"), endpoint.port(), e.what()); + } + + if (!fListening) { + uiInterface.ThreadSafeMessageBox(strerr, _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); + StartShutdown(); + return; + } + + vnThreadsRunning[THREAD_RPCLISTENER]--; + while (!fShutdown) + io_service.run_one(); + vnThreadsRunning[THREAD_RPCLISTENER]++; + StopRequests(); +} + +class JSONRequest +{ +public: + Value id; + string strMethod; + Array params; + + JSONRequest() { id = Value::null; } + void parse(const Value& valRequest); +}; + +void JSONRequest::parse(const Value& valRequest) +{ + // Parse request + if (valRequest.type() != obj_type) + throw JSONRPCError(-32600, "Invalid Request object"); + const Object& request = valRequest.get_obj(); + + // Parse id now so errors from here on will have the id + id = find_value(request, "id"); + + // Parse method + Value valMethod = find_value(request, "method"); + if (valMethod.type() == null_type) + throw JSONRPCError(-32600, "Missing method"); + if (valMethod.type() != str_type) + throw JSONRPCError(-32600, "Method must be a string"); + strMethod = valMethod.get_str(); + if (strMethod != "getwork" && strMethod != "getblocktemplate") + printf("ThreadRPCServer method=%s\n", strMethod.c_str()); + + // Parse params + Value valParams = find_value(request, "params"); + if (valParams.type() == array_type) + params = valParams.get_array(); + else if (valParams.type() == null_type) + params = Array(); + else + throw JSONRPCError(-32600, "Params must be an array"); +} + +static Object JSONRPCExecOne(const Value& req) +{ + Object rpc_result; + + JSONRequest jreq; + try { + jreq.parse(req); + + Value result = tableRPC.execute(jreq.strMethod, jreq.params); + rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id); + } + catch (Object& objError) + { + rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); + } + catch (std::exception& e) + { + rpc_result = JSONRPCReplyObj(Value::null, + JSONRPCError(-32700, e.what()), jreq.id); + } + + return rpc_result; +} + +static string JSONRPCExecBatch(const Array& vReq) +{ + Array ret; + for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) + ret.push_back(JSONRPCExecOne(vReq[reqIdx])); + + return write_string(Value(ret), false) + "\n"; +} + +static CCriticalSection cs_THREAD_RPCHANDLER; + +void ThreadRPCServer3(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer3(parg)); + + // Make this thread recognisable as the RPC handler + RenameThread("bitcoin-rpchand"); + + { + LOCK(cs_THREAD_RPCHANDLER); + vnThreadsRunning[THREAD_RPCHANDLER]++; + } + AcceptedConnection *conn = (AcceptedConnection *) parg; + + bool fRun = true; + loop { + if (fShutdown || !fRun) + { + conn->close(); + delete conn; + { + LOCK(cs_THREAD_RPCHANDLER); + --vnThreadsRunning[THREAD_RPCHANDLER]; + } + return; + } + map mapHeaders; + string strRequest; + + ReadHTTP(conn->stream(), mapHeaders, strRequest); + + // Check authorization + if (mapHeaders.count("authorization") == 0) + { + conn->stream() << HTTPReply(401, "", false) << std::flush; + break; + } + if (!HTTPAuthorized(mapHeaders)) + { + printf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string().c_str()); + /* Deter brute-forcing short passwords. + If this results in a DOS the user really + shouldn't have their RPC port exposed.*/ + if (mapArgs["-rpcpassword"].size() < 20) + Sleep(250); + + conn->stream() << HTTPReply(401, "", false) << std::flush; + break; + } + if (mapHeaders["connection"] == "close") + fRun = false; + + JSONRequest jreq; + try + { + // Parse request + Value valRequest; + if (!read_string(strRequest, valRequest)) + throw JSONRPCError(-32700, "Parse error"); + + string strReply; + + // singleton request + if (valRequest.type() == obj_type) { + jreq.parse(valRequest); + + Value result = tableRPC.execute(jreq.strMethod, jreq.params); + + // Send reply + strReply = JSONRPCReply(result, Value::null, jreq.id); + + // array of requests + } else if (valRequest.type() == array_type) + strReply = JSONRPCExecBatch(valRequest.get_array()); + else + throw JSONRPCError(-32700, "Top-level object parse error"); + + conn->stream() << HTTPReply(200, strReply, fRun) << std::flush; + } + catch (Object& objError) + { + ErrorReply(conn->stream(), objError, jreq.id); + break; + } + catch (std::exception& e) + { + ErrorReply(conn->stream(), JSONRPCError(-32700, e.what()), jreq.id); + break; + } + } + + delete conn; + { + LOCK(cs_THREAD_RPCHANDLER); + vnThreadsRunning[THREAD_RPCHANDLER]--; + } +} + +json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const +{ + // Find method + const CRPCCommand *pcmd = tableRPC[strMethod]; + if (!pcmd) + throw JSONRPCError(-32601, "Method not found"); + + // Observe safe mode + string strWarning = GetWarnings("rpc"); + if (strWarning != "" && !GetBoolArg("-disablesafemode") && + !pcmd->okSafeMode) + throw JSONRPCError(-2, string("Safe mode: ") + strWarning); + + try + { + // Execute + Value result; + { + LOCK2(cs_main, pwalletMain->cs_wallet); + result = pcmd->actor(params, false); + } + return result; + } + catch (std::exception& e) + { + throw JSONRPCError(-1, e.what()); + } +} + + +Object CallRPC(const string& strMethod, const Array& params) +{ + if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "") + throw runtime_error(strprintf( + _("You must set rpcpassword= in the configuration file:\n%s\n" + "If the file does not exist, create it with owner-readable-only file permissions."), + GetConfigFile().string().c_str())); + + // Connect to localhost + bool fUseSSL = GetBoolArg("-rpcssl"); + asio::io_service io_service; + ssl::context context(io_service, ssl::context::sslv23); + context.set_options(ssl::context::no_sslv2); + asio::ssl::stream sslStream(io_service, context); + SSLIOStreamDevice d(sslStream, fUseSSL); + iostreams::stream< SSLIOStreamDevice > stream(d); + if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "47970"))) + throw runtime_error("couldn't connect to server"); + + // HTTP basic authentication + string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); + map mapRequestHeaders; + mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64; + + // Send request + string strRequest = JSONRPCRequest(strMethod, params, 1); + string strPost = HTTPPost(strRequest, mapRequestHeaders); + stream << strPost << std::flush; + + // Receive reply + map mapHeaders; + string strReply; + int nStatus = ReadHTTP(stream, mapHeaders, strReply); + if (nStatus == 401) + throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); + else if (nStatus >= 400 && nStatus != 400 && nStatus != 404 && nStatus != 500) + throw runtime_error(strprintf("server returned HTTP error %d", nStatus)); + else if (strReply.empty()) + throw runtime_error("no response from server"); + + // Parse reply + Value valReply; + if (!read_string(strReply, valReply)) + throw runtime_error("couldn't parse reply from server"); + const Object& reply = valReply.get_obj(); + if (reply.empty()) + throw runtime_error("expected reply to have result, error and id properties"); + + return reply; +} + + + + +template +void ConvertTo(Value& value) +{ + if (value.type() == str_type) + { + // reinterpret string as unquoted json value + Value value2; + string strJSON = value.get_str(); + if (!read_string(strJSON, value2)) + throw runtime_error(string("Error parsing JSON:")+strJSON); + value = value2.get_value(); + } + else + { + value = value.get_value(); + } +} + +// Convert strings to command-specific RPC representation +Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams) +{ + Array params; + BOOST_FOREACH(const std::string ¶m, strParams) + params.push_back(param); + + int n = params.size(); + + // + // Special case non-string parameter types + // + if (strMethod == "setgenerate" && n > 0) ConvertTo(params[0]); + if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "settxfee" && n > 0) ConvertTo(params[0]); + if (strMethod == "setmininput" && n > 0) ConvertTo(params[0]); + if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo(params[1]); + if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo(params[0]); + if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo(params[0]); + if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo(params[1]); + if (strMethod == "getbalance" && n > 1) ConvertTo(params[1]); + if (strMethod == "getblockhash" && n > 0) ConvertTo(params[0]); + if (strMethod == "move" && n > 2) ConvertTo(params[2]); + if (strMethod == "move" && n > 3) ConvertTo(params[3]); + if (strMethod == "sendfrom" && n > 2) ConvertTo(params[2]); + if (strMethod == "sendfrom" && n > 3) ConvertTo(params[3]); + if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); + if (strMethod == "listtransactions" && n > 2) ConvertTo(params[2]); + if (strMethod == "listaccounts" && n > 0) ConvertTo(params[0]); + if (strMethod == "walletpassphrase" && n > 1) ConvertTo(params[1]); + if (strMethod == "getblocktemplate" && n > 0) ConvertTo(params[0]); + if (strMethod == "listsinceblock" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendmany" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendmany" && n > 2) ConvertTo(params[2]); + if (strMethod == "addmultisigaddress" && n > 0) ConvertTo(params[0]); + if (strMethod == "addmultisigaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "listunspent" && n > 0) ConvertTo(params[0]); + if (strMethod == "listunspent" && n > 1) ConvertTo(params[1]); + if (strMethod == "getrawtransaction" && n > 1) ConvertTo(params[1]); + if (strMethod == "createrawtransaction" && n > 0) ConvertTo(params[0]); + if (strMethod == "createrawtransaction" && n > 1) ConvertTo(params[1]); + if (strMethod == "signrawtransaction" && n > 1) ConvertTo(params[1]); + if (strMethod == "signrawtransaction" && n > 2) ConvertTo(params[2]); + + return params; +} + +int CommandLineRPC(int argc, char *argv[]) +{ + string strPrint; + int nRet = 0; + try + { + // Skip switches + while (argc > 1 && IsSwitchChar(argv[1][0])) + { + argc--; + argv++; + } + + // Method + if (argc < 2) + throw runtime_error("too few parameters"); + string strMethod = argv[1]; + + // Parameters default to strings + std::vector strParams(&argv[2], &argv[argc]); + Array params = RPCConvertValues(strMethod, strParams); + + // Execute + Object reply = CallRPC(strMethod, params); + + // Parse reply + const Value& result = find_value(reply, "result"); + const Value& error = find_value(reply, "error"); + + if (error.type() != null_type) + { + // Error + strPrint = "error: " + write_string(error, false); + int code = find_value(error.get_obj(), "code").get_int(); + nRet = abs(code); + } + else + { + // Result + if (result.type() == null_type) + strPrint = ""; + else if (result.type() == str_type) + strPrint = result.get_str(); + else + strPrint = write_string(result, true); + } + } + catch (std::exception& e) + { + strPrint = string("error: ") + e.what(); + nRet = 87; + } + catch (...) + { + PrintException(NULL, "CommandLineRPC()"); + } + + if (strPrint != "") + { + fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str()); + } + return nRet; +} + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ +#ifdef _MSC_VER + // Turn off microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif + setbuf(stdin, NULL); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + try + { + if (argc >= 2 && string(argv[1]) == "-server") + { + printf("server ready\n"); + ThreadRPCServer(NULL); + } + else + { + return CommandLineRPC(argc, argv); + } + } + catch (std::exception& e) { + PrintException(&e, "main()"); + } catch (...) { + PrintException(NULL, "main()"); + } + return 0; +} +#endif + +const CRPCTable tableRPC; diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h new file mode 100644 index 0000000..4b84272 --- /dev/null +++ b/src/bitcoinrpc.h @@ -0,0 +1,75 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef _BITCOINRPC_H_ +#define _BITCOINRPC_H_ 1 + +#include +#include +#include + +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" + +json_spirit::Object JSONRPCError(int code, const std::string& message); + +void ThreadRPCServer(void* parg); +int CommandLineRPC(int argc, char *argv[]); + +/** Convert parameter values for RPC call from strings to command-specific JSON objects. */ +json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams); + +/* + Type-check arguments; throws JSONRPCError if wrong type given. Does not check that + the right number of arguments are passed, just that any passed are the correct type. + Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); +*/ +void RPCTypeCheck(const json_spirit::Array& params, + const std::list& typesExpected); +/* + Check for expected keys/value types in an Object. + Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); +*/ +void RPCTypeCheck(const json_spirit::Object& o, + const std::map& typesExpected); + +typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp); + +class CRPCCommand +{ +public: + std::string name; + rpcfn_type actor; + bool okSafeMode; +}; + +/** + * Bitcoin RPC command dispatcher. + */ +class CRPCTable +{ +private: + std::map mapCommands; +public: + CRPCTable(); + const CRPCCommand* operator[](std::string name) const; + std::string help(std::string name) const; + + /** + * Execute a method. + * @param method Method to execute + * @param params Array of arguments (JSON objects) + * @returns Result of the call. + * @throws an exception (json_spirit::Value) when an error happens. + */ + json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const; +}; + +extern const CRPCTable tableRPC; + +#endif diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp new file mode 100644 index 0000000..3ffaf33 --- /dev/null +++ b/src/checkpoints.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include // for 'map_list_of()' +#include + +#include "checkpoints.h" + +#include "main.h" +#include "uint256.h" + +namespace Checkpoints +{ + typedef std::map MapCheckpoints; + + // + // What makes a good checkpoint block? + // + Is surrounded by blocks with reasonable timestamps + // (no blocks before with a timestamp after, none after with + // timestamp before) + // + Contains no strange transactions + // + static MapCheckpoints mapCheckpoints = + boost::assign::map_list_of + ( 0, uint256("0x4f46c9af6d88a14114b7dc53a37d81ba4064cda5ae2ede1213ca28fea9b86e9c")) + ; + + bool CheckBlock(int nHeight, const uint256& hash) + { + if (fTestNet) return true; // Testnet has no checkpoints + + MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight); + if (i == mapCheckpoints.end()) return true; + return hash == i->second; + } + + int GetTotalBlocksEstimate() + { + if (fTestNet) return 0; + + return mapCheckpoints.rbegin()->first; + } + + CBlockIndex* GetLastCheckpoint(const std::map& mapBlockIndex) + { + if (fTestNet) return NULL; + + BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints) + { + const uint256& hash = i.second; + std::map::const_iterator t = mapBlockIndex.find(hash); + if (t != mapBlockIndex.end()) + return t->second; + } + return NULL; + } +} diff --git a/src/checkpoints.h b/src/checkpoints.h new file mode 100644 index 0000000..662fc13 --- /dev/null +++ b/src/checkpoints.h @@ -0,0 +1,29 @@ +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_CHECKPOINT_H +#define BITCOIN_CHECKPOINT_H + +#include + +class uint256; +class CBlockIndex; + +/** Block-chain checkpoints are compiled-in sanity checks. + * They are updated every release or three. + */ +namespace Checkpoints +{ + // Returns true if block passes checkpoint checks + bool CheckBlock(int nHeight, const uint256& hash); + + // Return conservative estimate of total number of blocks, 0 if unknown + int GetTotalBlocksEstimate(); + + // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint + CBlockIndex* GetLastCheckpoint(const std::map& mapBlockIndex); +} + +#endif diff --git a/src/compat.h b/src/compat.h new file mode 100644 index 0000000..bf81e33 --- /dev/null +++ b/src/compat.h @@ -0,0 +1,65 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef _BITCOIN_COMPAT_H +#define _BITCOIN_COMPAT_H 1 + +#ifdef WIN32 +#define _WIN32_WINNT 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +typedef u_int SOCKET; +#ifdef WIN32 +#define MSG_NOSIGNAL 0 +#define MSG_DONTWAIT 0 +typedef int socklen_t; +#else +#include "errno.h" +#define WSAGetLastError() errno +#define WSAEINVAL EINVAL +#define WSAEALREADY EALREADY +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEMSGSIZE EMSGSIZE +#define WSAEINTR EINTR +#define WSAEINPROGRESS EINPROGRESS +#define WSAEADDRINUSE EADDRINUSE +#define WSAENOTSOCK EBADF +#define INVALID_SOCKET (SOCKET)(~0) +#define SOCKET_ERROR -1 +#endif + +inline int myclosesocket(SOCKET& hSocket) +{ + if (hSocket == INVALID_SOCKET) + return WSAENOTSOCK; +#ifdef WIN32 + int ret = closesocket(hSocket); +#else + int ret = close(hSocket); +#endif + hSocket = INVALID_SOCKET; + return ret; +} +#define closesocket(s) myclosesocket(s) + + +#endif diff --git a/src/crypter.cpp b/src/crypter.cpp new file mode 100644 index 0000000..72cedfc --- /dev/null +++ b/src/crypter.cpp @@ -0,0 +1,135 @@ +// Copyright (c) 2009-2012 The Bitcoin Developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include +#ifdef WIN32 +#include +#endif + +#include "crypter.h" + +bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) +{ + if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) + return false; + + // Try to keep the keydata out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap) + // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) + // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process. + mlock(&chKey[0], sizeof chKey); + mlock(&chIV[0], sizeof chIV); + + int i = 0; + if (nDerivationMethod == 0) + i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], + (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); + + if (i != (int)WALLET_CRYPTO_KEY_SIZE) + { + memset(&chKey, 0, sizeof chKey); + memset(&chIV, 0, sizeof chIV); + return false; + } + + fKeySet = true; + return true; +} + +bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector& chNewIV) +{ + if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE) + return false; + + // Try to keep the keydata out of swap + // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) + // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process. + mlock(&chKey[0], sizeof chKey); + mlock(&chIV[0], sizeof chIV); + + memcpy(&chKey[0], &chNewKey[0], sizeof chKey); + memcpy(&chIV[0], &chNewIV[0], sizeof chIV); + + fKeySet = true; + return true; +} + +bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector &vchCiphertext) +{ + if (!fKeySet) + return false; + + // max ciphertext len for a n bytes of plaintext is + // n + AES_BLOCK_SIZE - 1 bytes + int nLen = vchPlaintext.size(); + int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0; + vchCiphertext = std::vector (nCLen); + + EVP_CIPHER_CTX ctx; + + bool fOk = true; + + EVP_CIPHER_CTX_init(&ctx); + if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); + if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen); + if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen); + EVP_CIPHER_CTX_cleanup(&ctx); + + if (!fOk) return false; + + vchCiphertext.resize(nCLen + nFLen); + return true; +} + +bool CCrypter::Decrypt(const std::vector& vchCiphertext, CKeyingMaterial& vchPlaintext) +{ + if (!fKeySet) + return false; + + // plaintext will always be equal to or lesser than length of ciphertext + int nLen = vchCiphertext.size(); + int nPLen = nLen, nFLen = 0; + + vchPlaintext = CKeyingMaterial(nPLen); + + EVP_CIPHER_CTX ctx; + + bool fOk = true; + + EVP_CIPHER_CTX_init(&ctx); + if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); + if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen); + if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen); + EVP_CIPHER_CTX_cleanup(&ctx); + + if (!fOk) return false; + + vchPlaintext.resize(nPLen + nFLen); + return true; +} + + +bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext) +{ + CCrypter cKeyCrypter; + std::vector chIV(WALLET_CRYPTO_KEY_SIZE); + memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); + if(!cKeyCrypter.SetKey(vMasterKey, chIV)) + return false; + return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext); +} + +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext) +{ + CCrypter cKeyCrypter; + std::vector chIV(WALLET_CRYPTO_KEY_SIZE); + memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); + if(!cKeyCrypter.SetKey(vMasterKey, chIV)) + return false; + return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)); +} diff --git a/src/crypter.h b/src/crypter.h new file mode 100644 index 0000000..0a41f56 --- /dev/null +++ b/src/crypter.h @@ -0,0 +1,102 @@ +// Copyright (c) 2009-2012 The Bitcoin Developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef __CRYPTER_H__ +#define __CRYPTER_H__ + +#include "allocators.h" /* for SecureString */ +#include "key.h" +#include "serialize.h" + +const unsigned int WALLET_CRYPTO_KEY_SIZE = 32; +const unsigned int WALLET_CRYPTO_SALT_SIZE = 8; + +/* +Private key encryption is done based on a CMasterKey, +which holds a salt and random encryption key. + +CMasterKeys are encrypted using AES-256-CBC using a key +derived using derivation method nDerivationMethod +(0 == EVP_sha512()) and derivation iterations nDeriveIterations. +vchOtherDerivationParameters is provided for alternative algorithms +which may require more parameters (such as scrypt). + +Wallet Private Keys are then encrypted using AES-256-CBC +with the double-sha256 of the public key as the IV, and the +master key's key as the encryption key (see keystore.[ch]). +*/ + +/** Master key for wallet encryption */ +class CMasterKey +{ +public: + std::vector vchCryptedKey; + std::vector vchSalt; + // 0 = EVP_sha512() + // 1 = scrypt() + unsigned int nDerivationMethod; + unsigned int nDeriveIterations; + // Use this for more parameters to key derivation, + // such as the various parameters to scrypt + std::vector vchOtherDerivationParameters; + + IMPLEMENT_SERIALIZE + ( + READWRITE(vchCryptedKey); + READWRITE(vchSalt); + READWRITE(nDerivationMethod); + READWRITE(nDeriveIterations); + READWRITE(vchOtherDerivationParameters); + ) + CMasterKey() + { + // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M + // ie slightly lower than the lowest hardware we need bother supporting + nDeriveIterations = 25000; + nDerivationMethod = 0; + vchOtherDerivationParameters = std::vector(0); + } +}; + +typedef std::vector > CKeyingMaterial; + +/** Encryption/decryption context with key information */ +class CCrypter +{ +private: + unsigned char chKey[WALLET_CRYPTO_KEY_SIZE]; + unsigned char chIV[WALLET_CRYPTO_KEY_SIZE]; + bool fKeySet; + +public: + bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod); + bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector &vchCiphertext); + bool Decrypt(const std::vector& vchCiphertext, CKeyingMaterial& vchPlaintext); + bool SetKey(const CKeyingMaterial& chNewKey, const std::vector& chNewIV); + + void CleanKey() + { + memset(&chKey, 0, sizeof chKey); + memset(&chIV, 0, sizeof chIV); + munlock(&chKey, sizeof chKey); + munlock(&chIV, sizeof chIV); + fKeySet = false; + } + + CCrypter() + { + fKeySet = false; + } + + ~CCrypter() + { + CleanKey(); + } +}; + +bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector &vchCiphertext); +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector &vchCiphertext, const uint256& nIV, CSecret &vchPlaintext); + +#endif diff --git a/src/db.cpp b/src/db.cpp new file mode 100644 index 0000000..1830f67 --- /dev/null +++ b/src/db.cpp @@ -0,0 +1,842 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "db.h" +#include "util.h" +#include "main.h" +#include "init.h" +#include +#include +#include + +#ifndef WIN32 +#include "sys/stat.h" +#endif + +using namespace std; +using namespace boost; + + +unsigned int nWalletDBUpdated; + + + +// +// CDB +// + +CDBEnv bitdb; + +void CDBEnv::EnvShutdown() +{ + if (!fDbEnvInit) + return; + + fDbEnvInit = false; + try + { + dbenv.close(0); + } + catch (const DbException& e) + { + printf("EnvShutdown exception: %s (%d)\n", e.what(), e.get_errno()); + } + DbEnv(0).remove(GetDataDir().string().c_str(), 0); +} + +CDBEnv::CDBEnv() : dbenv(0) +{ +} + +CDBEnv::~CDBEnv() +{ + EnvShutdown(); +} + +void CDBEnv::Close() +{ + EnvShutdown(); +} + +bool CDBEnv::Open(boost::filesystem::path pathEnv_) +{ + if (fDbEnvInit) + return true; + + if (fShutdown) + return false; + + pathEnv = pathEnv_; + filesystem::path pathDataDir = pathEnv; + filesystem::path pathLogDir = pathDataDir / "database"; + filesystem::create_directory(pathLogDir); + filesystem::path pathErrorFile = pathDataDir / "db.log"; + printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str()); + + unsigned int nEnvFlags = 0; + if (GetBoolArg("-privdb", true)) + nEnvFlags |= DB_PRIVATE; + + int nDbCache = GetArg("-dbcache", 25); + dbenv.set_lg_dir(pathLogDir.string().c_str()); + dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1); + dbenv.set_lg_bsize(1048576); + dbenv.set_lg_max(10485760); + dbenv.set_lk_max_locks(537000); + dbenv.set_lk_max_objects(10000); + dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug + dbenv.set_flags(DB_AUTO_COMMIT, 1); + dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1); + dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); + int ret = dbenv.open(pathDataDir.string().c_str(), + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_RECOVER | + nEnvFlags, + S_IRUSR | S_IWUSR); + if (ret > 0) + return error("CDB() : error %d opening database environment", ret); + + // Check that the number of locks is sufficient + u_int32_t nMaxLocks; + if (!dbenv.get_lk_max_locks(&nMaxLocks)) + { + int nBlocks, nDeepReorg; + std::string strMessage; + + nBlocks = nMaxLocks / 48768; + nDeepReorg = (nBlocks - 1) / 2; + printf("Final lk_max_locks is %lu, sufficient for (worst case) %d block%s in a single transaction (up to a %d-deep reorganization)\n", (unsigned long)nMaxLocks, nBlocks, (nBlocks == 1) ? "" : "s", nDeepReorg); + if (nDeepReorg < 3) + { + if (nBlocks < 1) + strMessage = strprintf(_("Warning: DB_CONFIG has set_lk_max_locks %lu, which may be too low for a single block. If this limit is reached, Bitcoin may stop working."), (unsigned long)nMaxLocks); + else + strMessage = strprintf(_("Warning: DB_CONFIG has set_lk_max_locks %lu, which may be too low for a common blockchain reorganization. If this limit is reached, Bitcoin may stop working."), (unsigned long)nMaxLocks); + + strMiscWarning = strMessage; + printf("*** %s\n", strMessage.c_str()); + } + } + + fDbEnvInit = true; + return true; +} + +void CDBEnv::CheckpointLSN(std::string strFile) +{ + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(strFile.c_str(), 0); +} + + +CDB::CDB(const char *pszFile, const char* pszMode) : + pdb(NULL), activeTxn(NULL) +{ + int ret; + if (pszFile == NULL) + return; + + fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); + bool fCreate = strchr(pszMode, 'c'); + unsigned int nFlags = DB_THREAD; + if (fCreate) + nFlags |= DB_CREATE; + + { + LOCK(bitdb.cs_db); + if (!bitdb.Open(GetDataDir())) + throw runtime_error("env open failed"); + + strFile = pszFile; + ++bitdb.mapFileUseCount[strFile]; + pdb = bitdb.mapDb[strFile]; + if (pdb == NULL) + { + pdb = new Db(&bitdb.dbenv, 0); + + ret = pdb->open(NULL, // Txn pointer + pszFile, // Filename + "main", // Logical db name + DB_BTREE, // Database type + nFlags, // Flags + 0); + + if (ret > 0) + { + delete pdb; + pdb = NULL; + { + LOCK(bitdb.cs_db); + --bitdb.mapFileUseCount[strFile]; + } + strFile = ""; + throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret)); + } + + if (fCreate && !Exists(string("version"))) + { + bool fTmp = fReadOnly; + fReadOnly = false; + WriteVersion(CLIENT_VERSION); + fReadOnly = fTmp; + } + + bitdb.mapDb[strFile] = pdb; + } + } +} + +static bool IsChainFile(std::string strFile) +{ + if (strFile == "blkindex.dat") + return true; + + return false; +} + +void CDB::Close() +{ + if (!pdb) + return; + if (activeTxn) + activeTxn->abort(); + activeTxn = NULL; + pdb = NULL; + + // Flush database activity from memory pool to disk log + unsigned int nMinutes = 0; + if (fReadOnly) + nMinutes = 1; + if (IsChainFile(strFile)) + nMinutes = 2; + if (IsChainFile(strFile) && IsInitialBlockDownload()) + nMinutes = 5; + + bitdb.dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0); + + { + LOCK(bitdb.cs_db); + --bitdb.mapFileUseCount[strFile]; + } +} + +void CDBEnv::CloseDb(const string& strFile) +{ + { + LOCK(cs_db); + if (mapDb[strFile] != NULL) + { + // Close the database handle + Db* pdb = mapDb[strFile]; + pdb->close(0); + delete pdb; + mapDb[strFile] = NULL; + } + } +} + +bool CDB::Rewrite(const string& strFile, const char* pszSkip) +{ + while (!fShutdown) + { + { + LOCK(bitdb.cs_db); + if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) + { + // Flush log data to the dat file + bitdb.CloseDb(strFile); + bitdb.CheckpointLSN(strFile); + bitdb.mapFileUseCount.erase(strFile); + + bool fSuccess = true; + printf("Rewriting %s...\n", strFile.c_str()); + string strFileRes = strFile + ".rewrite"; + { // surround usage of db with extra {} + CDB db(strFile.c_str(), "r"); + Db* pdbCopy = new Db(&bitdb.dbenv, 0); + + int ret = pdbCopy->open(NULL, // Txn pointer + strFileRes.c_str(), // Filename + "main", // Logical db name + DB_BTREE, // Database type + DB_CREATE, // Flags + 0); + if (ret > 0) + { + printf("Cannot create database file %s\n", strFileRes.c_str()); + fSuccess = false; + } + + Dbc* pcursor = db.GetCursor(); + if (pcursor) + while (fSuccess) + { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); + if (ret == DB_NOTFOUND) + { + pcursor->close(); + break; + } + else if (ret != 0) + { + pcursor->close(); + fSuccess = false; + break; + } + if (pszSkip && + strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) + continue; + if (strncmp(&ssKey[0], "\x07version", 8) == 0) + { + // Update version: + ssValue.clear(); + ssValue << CLIENT_VERSION; + } + Dbt datKey(&ssKey[0], ssKey.size()); + Dbt datValue(&ssValue[0], ssValue.size()); + int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE); + if (ret2 > 0) + fSuccess = false; + } + if (fSuccess) + { + db.Close(); + bitdb.CloseDb(strFile); + if (pdbCopy->close(0)) + fSuccess = false; + delete pdbCopy; + } + } + if (fSuccess) + { + Db dbA(&bitdb.dbenv, 0); + if (dbA.remove(strFile.c_str(), NULL, 0)) + fSuccess = false; + Db dbB(&bitdb.dbenv, 0); + if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) + fSuccess = false; + } + if (!fSuccess) + printf("Rewriting of %s FAILED!\n", strFileRes.c_str()); + return fSuccess; + } + } + Sleep(100); + } + return false; +} + + +void CDBEnv::Flush(bool fShutdown) +{ + int64 nStart = GetTimeMillis(); + // Flush log data to the actual data file + // on all files that are not in use + printf("Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); + if (!fDbEnvInit) + return; + { + LOCK(cs_db); + map::iterator mi = mapFileUseCount.begin(); + while (mi != mapFileUseCount.end()) + { + string strFile = (*mi).first; + int nRefCount = (*mi).second; + printf("%s refcount=%d\n", strFile.c_str(), nRefCount); + if (nRefCount == 0) + { + // Move log data to the dat file + CloseDb(strFile); + printf("%s checkpoint\n", strFile.c_str()); + dbenv.txn_checkpoint(0, 0, 0); + if (!IsChainFile(strFile) || fDetachDB) { + printf("%s detach\n", strFile.c_str()); + dbenv.lsn_reset(strFile.c_str(), 0); + } + printf("%s closed\n", strFile.c_str()); + mapFileUseCount.erase(mi++); + } + else + mi++; + } + printf("DBFlush(%s)%s ended %15"PRI64d"ms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started", GetTimeMillis() - nStart); + if (fShutdown) + { + char** listp; + if (mapFileUseCount.empty()) + { + dbenv.log_archive(&listp, DB_ARCH_REMOVE); + Close(); + } + } + } +} + + + + + + +// +// CTxDB +// + +bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex) +{ + assert(!fClient); + txindex.SetNull(); + return Read(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex) +{ + assert(!fClient); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight) +{ + assert(!fClient); + + // Add to tx index + uint256 hash = tx.GetHash(); + CTxIndex txindex(pos, tx.vout.size()); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::EraseTxIndex(const CTransaction& tx) +{ + assert(!fClient); + uint256 hash = tx.GetHash(); + + return Erase(make_pair(string("tx"), hash)); +} + +bool CTxDB::ContainsTx(uint256 hash) +{ + assert(!fClient); + return Exists(make_pair(string("tx"), hash)); +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex) +{ + assert(!fClient); + tx.SetNull(); + if (!ReadTxIndex(hash, txindex)) + return false; + return (tx.ReadFromDisk(txindex.pos)); +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex) +{ + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) +{ + return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex); +} + +bool CTxDB::ReadHashBestChain(uint256& hashBestChain) +{ + return Read(string("hashBestChain"), hashBestChain); +} + +bool CTxDB::WriteHashBestChain(uint256 hashBestChain) +{ + return Write(string("hashBestChain"), hashBestChain); +} + +bool CTxDB::ReadBestInvalidWork(CBigNum& bnBestInvalidWork) +{ + return Read(string("bnBestInvalidWork"), bnBestInvalidWork); +} + +bool CTxDB::WriteBestInvalidWork(CBigNum bnBestInvalidWork) +{ + return Write(string("bnBestInvalidWork"), bnBestInvalidWork); +} + +CBlockIndex static * InsertBlockIndex(uint256 hash) +{ + if (hash == 0) + return NULL; + + // Return existing + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + return (*mi).second; + + // Create new + CBlockIndex* pindexNew = new CBlockIndex(); + if (!pindexNew) + throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); + mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + + return pindexNew; +} + +bool CTxDB::LoadBlockIndex() +{ + if (!LoadBlockIndexGuts()) + return false; + + if (fRequestShutdown) + return true; + + // Calculate bnChainWork + vector > vSortedByHeight; + vSortedByHeight.reserve(mapBlockIndex.size()); + BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) + { + CBlockIndex* pindex = item.second; + vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); + } + sort(vSortedByHeight.begin(), vSortedByHeight.end()); + BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) + { + CBlockIndex* pindex = item.second; + pindex->bnChainWork = (pindex->pprev ? pindex->pprev->bnChainWork : 0) + pindex->GetBlockWork(); + } + + // Load hashBestChain pointer to end of best chain + if (!ReadHashBestChain(hashBestChain)) + { + if (pindexGenesisBlock == NULL) + return true; + return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded"); + } + if (!mapBlockIndex.count(hashBestChain)) + return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index"); + pindexBest = mapBlockIndex[hashBestChain]; + nBestHeight = pindexBest->nHeight; + bnBestChainWork = pindexBest->bnChainWork; + printf("LoadBlockIndex(): hashBestChain=%s height=%d date=%s\n", + hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, + DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); + + // Load bnBestInvalidWork, OK if it doesn't exist + ReadBestInvalidWork(bnBestInvalidWork); + + // Verify blocks in the best chain + int nCheckLevel = GetArg("-checklevel", 1); + int nCheckDepth = GetArg( "-checkblocks", 2500); + if (nCheckDepth == 0) + nCheckDepth = 1000000000; // suffices until the year 19000 + if (nCheckDepth > nBestHeight) + nCheckDepth = nBestHeight; + printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); + CBlockIndex* pindexFork = NULL; + map, CBlockIndex*> mapBlockPos; + for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) + { + if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) + break; + CBlock block; + if (!block.ReadFromDisk(pindex)) + return error("LoadBlockIndex() : block.ReadFromDisk failed"); + // check level 1: verify block validity + if (nCheckLevel>0 && !block.CheckBlock()) + { + printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); + pindexFork = pindex->pprev; + } + // check level 2: verify transaction index validity + if (nCheckLevel>1) + { + pair pos = make_pair(pindex->nFile, pindex->nBlockPos); + mapBlockPos[pos] = pindex; + BOOST_FOREACH(const CTransaction &tx, block.vtx) + { + uint256 hashTx = tx.GetHash(); + CTxIndex txindex; + if (ReadTxIndex(hashTx, txindex)) + { + // check level 3: checker transaction hashes + if (nCheckLevel>2 || pindex->nFile != txindex.pos.nFile || pindex->nBlockPos != txindex.pos.nBlockPos) + { + // either an error or a duplicate transaction + CTransaction txFound; + if (!txFound.ReadFromDisk(txindex.pos)) + { + printf("LoadBlockIndex() : *** cannot read mislocated transaction %s\n", hashTx.ToString().c_str()); + pindexFork = pindex->pprev; + } + else + if (txFound.GetHash() != hashTx) // not a duplicate tx + { + printf("LoadBlockIndex(): *** invalid tx position for %s\n", hashTx.ToString().c_str()); + pindexFork = pindex->pprev; + } + } + // check level 4: check whether spent txouts were spent within the main chain + unsigned int nOutput = 0; + if (nCheckLevel>3) + { + BOOST_FOREACH(const CDiskTxPos &txpos, txindex.vSpent) + { + if (!txpos.IsNull()) + { + pair posFind = make_pair(txpos.nFile, txpos.nBlockPos); + if (!mapBlockPos.count(posFind)) + { + printf("LoadBlockIndex(): *** found bad spend at %d, hashBlock=%s, hashTx=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), hashTx.ToString().c_str()); + pindexFork = pindex->pprev; + } + // check level 6: check whether spent txouts were spent by a valid transaction that consume them + if (nCheckLevel>5) + { + CTransaction txSpend; + if (!txSpend.ReadFromDisk(txpos)) + { + printf("LoadBlockIndex(): *** cannot read spending transaction of %s:%i from disk\n", hashTx.ToString().c_str(), nOutput); + pindexFork = pindex->pprev; + } + else if (!txSpend.CheckTransaction()) + { + printf("LoadBlockIndex(): *** spending transaction of %s:%i is invalid\n", hashTx.ToString().c_str(), nOutput); + pindexFork = pindex->pprev; + } + else + { + bool fFound = false; + BOOST_FOREACH(const CTxIn &txin, txSpend.vin) + if (txin.prevout.hash == hashTx && txin.prevout.n == nOutput) + fFound = true; + if (!fFound) + { + printf("LoadBlockIndex(): *** spending transaction of %s:%i does not spend it\n", hashTx.ToString().c_str(), nOutput); + pindexFork = pindex->pprev; + } + } + } + } + nOutput++; + } + } + } + // check level 5: check whether all prevouts are marked spent + if (nCheckLevel>4) + { + BOOST_FOREACH(const CTxIn &txin, tx.vin) + { + CTxIndex txindex; + if (ReadTxIndex(txin.prevout.hash, txindex)) + if (txindex.vSpent.size()-1 < txin.prevout.n || txindex.vSpent[txin.prevout.n].IsNull()) + { + printf("LoadBlockIndex(): *** found unspent prevout %s:%i in %s\n", txin.prevout.hash.ToString().c_str(), txin.prevout.n, hashTx.ToString().c_str()); + pindexFork = pindex->pprev; + } + } + } + } + } + } + if (pindexFork && !fRequestShutdown) + { + // Reorg back to the fork + printf("LoadBlockIndex() : *** moving best chain pointer back to block %d\n", pindexFork->nHeight); + CBlock block; + if (!block.ReadFromDisk(pindexFork)) + return error("LoadBlockIndex() : block.ReadFromDisk failed"); + CTxDB txdb; + block.SetBestChain(txdb, pindexFork); + } + + return true; +} + + + +bool CTxDB::LoadBlockIndexGuts() +{ + // Get database cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + // Load mapBlockIndex + unsigned int fFlags = DB_SET_RANGE; + loop + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + if (fFlags == DB_SET_RANGE) + ssKey << make_pair(string("blockindex"), uint256(0)); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + + try { + string strType; + ssKey >> strType; + if (strType == "blockindex" && !fRequestShutdown) + { + CDiskBlockIndex diskindex; + ssValue >> diskindex; + + // Construct block index object + CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); + pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); + pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); + pindexNew->nFile = diskindex.nFile; + pindexNew->nBlockPos = diskindex.nBlockPos; + pindexNew->nHeight = diskindex.nHeight; + pindexNew->nVersion = diskindex.nVersion; + pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; + pindexNew->nTime = diskindex.nTime; + pindexNew->nBits = diskindex.nBits; + pindexNew->nNonce = diskindex.nNonce; + + // Watch for genesis block + if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) + pindexGenesisBlock = pindexNew; + + if (!pindexNew->CheckIndex()) + return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); + } + else + { + break; // if shutdown requested or finished loading block index + } + } // try + catch (std::exception &e) { + return error("%s() : deserialize error", __PRETTY_FUNCTION__); + } + } + pcursor->close(); + + return true; +} + + + + + +// +// CAddrDB +// + + +CAddrDB::CAddrDB() +{ + pathAddr = GetDataDir() / "peers.dat"; +} + +bool CAddrDB::Write(const CAddrMan& addr) +{ + // Generate random temporary filename + unsigned short randv = 0; + RAND_bytes((unsigned char *)&randv, sizeof(randv)); + std::string tmpfn = strprintf("peers.dat.%04x", randv); + + // serialize addresses, checksum data up to that point, then append csum + CDataStream ssPeers(SER_DISK, CLIENT_VERSION); + ssPeers << FLATDATA(pchMessageStart); + ssPeers << addr; + uint256 hash = Hash(ssPeers.begin(), ssPeers.end()); + ssPeers << hash; + + // open temp output file, and associate with CAutoFile + boost::filesystem::path pathTmp = GetDataDir() / tmpfn; + FILE *file = fopen(pathTmp.string().c_str(), "wb"); + CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION); + if (!fileout) + return error("CAddrman::Write() : open failed"); + + // Write and commit header, data + try { + fileout << ssPeers; + } + catch (std::exception &e) { + return error("CAddrman::Write() : I/O error"); + } + FileCommit(fileout); + fileout.fclose(); + + // replace existing peers.dat, if any, with new peers.dat.XXXX + if (!RenameOver(pathTmp, pathAddr)) + return error("CAddrman::Write() : Rename-into-place failed"); + + return true; +} + +bool CAddrDB::Read(CAddrMan& addr) +{ + // open input file, and associate with CAutoFile + FILE *file = fopen(pathAddr.string().c_str(), "rb"); + CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); + if (!filein) + return error("CAddrman::Read() : open failed"); + + // use file size to size memory buffer + int fileSize = GetFilesize(filein); + int dataSize = fileSize - sizeof(uint256); + vector vchData; + vchData.resize(dataSize); + uint256 hashIn; + + // read data and checksum from file + try { + filein.read((char *)&vchData[0], dataSize); + filein >> hashIn; + } + catch (std::exception &e) { + return error("CAddrman::Read() 2 : I/O error or stream data corrupted"); + } + filein.fclose(); + + CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION); + + // verify stored checksum matches input data + uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); + if (hashIn != hashTmp) + return error("CAddrman::Read() : checksum mismatch; data corrupted"); + + // de-serialize address data + unsigned char pchMsgTmp[4]; + try { + ssPeers >> FLATDATA(pchMsgTmp); + ssPeers >> addr; + } + catch (std::exception &e) { + return error("CAddrman::Read() : I/O error or stream data corrupted"); + } + + // finally, verify the network matches ours + if (memcmp(pchMsgTmp, pchMessageStart, sizeof(pchMsgTmp))) + return error("CAddrman::Read() : invalid network magic number"); + + return true; +} + diff --git a/src/db.h b/src/db.h new file mode 100644 index 0000000..3ceff18 --- /dev/null +++ b/src/db.h @@ -0,0 +1,340 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_DB_H +#define BITCOIN_DB_H + +#include "main.h" + +#include +#include +#include + +#include + +class CAddress; +class CAddrMan; +class CBlockLocator; +class CDiskBlockIndex; +class CDiskTxPos; +class CMasterKey; +class COutPoint; +class CTxIndex; +class CWallet; +class CWalletTx; + +extern unsigned int nWalletDBUpdated; + +void ThreadFlushWalletDB(void* parg); +bool BackupWallet(const CWallet& wallet, const std::string& strDest); + + +class CDBEnv +{ +private: + bool fDetachDB; + bool fDbEnvInit; + boost::filesystem::path pathEnv; + + void EnvShutdown(); + +public: + mutable CCriticalSection cs_db; + DbEnv dbenv; + std::map mapFileUseCount; + std::map mapDb; + + CDBEnv(); + ~CDBEnv(); + bool Open(boost::filesystem::path pathEnv_); + void Close(); + void Flush(bool fShutdown); + void CheckpointLSN(std::string strFile); + void SetDetach(bool fDetachDB_) { fDetachDB = fDetachDB_; } + bool GetDetach() { return fDetachDB; } + + void CloseDb(const std::string& strFile); + + DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC) + { + DbTxn* ptxn = NULL; + int ret = dbenv.txn_begin(NULL, &ptxn, flags); + if (!ptxn || ret != 0) + return NULL; + return ptxn; + } +}; + +extern CDBEnv bitdb; + + +/** RAII class that provides access to a Berkeley database */ +class CDB +{ +protected: + Db* pdb; + std::string strFile; + DbTxn *activeTxn; + bool fReadOnly; + + explicit CDB(const char* pszFile, const char* pszMode="r+"); + ~CDB() { Close(); } +public: + void Close(); +private: + CDB(const CDB&); + void operator=(const CDB&); + +protected: + template + bool Read(const K& key, T& value) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Read + Dbt datValue; + datValue.set_flags(DB_DBT_MALLOC); + int ret = pdb->get(activeTxn, &datKey, &datValue, 0); + memset(datKey.get_data(), 0, datKey.get_size()); + if (datValue.get_data() == NULL) + return false; + + // Unserialize value + try { + CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); + ssValue >> value; + } + catch (std::exception &e) { + return false; + } + + // Clear and free memory + memset(datValue.get_data(), 0, datValue.get_size()); + free(datValue.get_data()); + return (ret == 0); + } + + template + bool Write(const K& key, const T& value, bool fOverwrite=true) + { + if (!pdb) + return false; + if (fReadOnly) + assert(!"Write called on database in read-only mode"); + + // Key + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Value + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + ssValue.reserve(10000); + ssValue << value; + Dbt datValue(&ssValue[0], ssValue.size()); + + // Write + int ret = pdb->put(activeTxn, &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); + + // Clear memory in case it was a private key + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + return (ret == 0); + } + + template + bool Erase(const K& key) + { + if (!pdb) + return false; + if (fReadOnly) + assert(!"Erase called on database in read-only mode"); + + // Key + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Erase + int ret = pdb->del(activeTxn, &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0 || ret == DB_NOTFOUND); + } + + template + bool Exists(const K& key) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Exists + int ret = pdb->exists(activeTxn, &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0); + } + + Dbc* GetCursor() + { + if (!pdb) + return NULL; + Dbc* pcursor = NULL; + int ret = pdb->cursor(NULL, &pcursor, 0); + if (ret != 0) + return NULL; + return pcursor; + } + + int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT) + { + // Read at cursor + Dbt datKey; + if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) + { + datKey.set_data(&ssKey[0]); + datKey.set_size(ssKey.size()); + } + Dbt datValue; + if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) + { + datValue.set_data(&ssValue[0]); + datValue.set_size(ssValue.size()); + } + datKey.set_flags(DB_DBT_MALLOC); + datValue.set_flags(DB_DBT_MALLOC); + int ret = pcursor->get(&datKey, &datValue, fFlags); + if (ret != 0) + return ret; + else if (datKey.get_data() == NULL || datValue.get_data() == NULL) + return 99999; + + // Convert to streams + ssKey.SetType(SER_DISK); + ssKey.clear(); + ssKey.write((char*)datKey.get_data(), datKey.get_size()); + ssValue.SetType(SER_DISK); + ssValue.clear(); + ssValue.write((char*)datValue.get_data(), datValue.get_size()); + + // Clear and free memory + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + free(datKey.get_data()); + free(datValue.get_data()); + return 0; + } + +public: + bool TxnBegin() + { + if (!pdb || activeTxn) + return false; + DbTxn* ptxn = bitdb.TxnBegin(); + if (!ptxn) + return false; + activeTxn = ptxn; + return true; + } + + bool TxnCommit() + { + if (!pdb || !activeTxn) + return false; + int ret = activeTxn->commit(0); + activeTxn = NULL; + return (ret == 0); + } + + bool TxnAbort() + { + if (!pdb || !activeTxn) + return false; + int ret = activeTxn->abort(); + activeTxn = NULL; + return (ret == 0); + } + + bool ReadVersion(int& nVersion) + { + nVersion = 0; + return Read(std::string("version"), nVersion); + } + + bool WriteVersion(int nVersion) + { + return Write(std::string("version"), nVersion); + } + + bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL); +}; + + + + + + + +/** Access to the transaction database (blkindex.dat) */ +class CTxDB : public CDB +{ +public: + CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { } +private: + CTxDB(const CTxDB&); + void operator=(const CTxDB&); +public: + bool ReadTxIndex(uint256 hash, CTxIndex& txindex); + bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); + bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight); + bool EraseTxIndex(const CTransaction& tx); + bool ContainsTx(uint256 hash); + bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(uint256 hash, CTransaction& tx); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); + bool WriteBlockIndex(const CDiskBlockIndex& blockindex); + bool ReadHashBestChain(uint256& hashBestChain); + bool WriteHashBestChain(uint256 hashBestChain); + bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork); + bool WriteBestInvalidWork(CBigNum bnBestInvalidWork); + bool LoadBlockIndex(); +private: + bool LoadBlockIndexGuts(); +}; + + + + +/** Access to the (IP) address database (peers.dat) */ +class CAddrDB +{ +private: + boost::filesystem::path pathAddr; +public: + CAddrDB(); + bool Write(const CAddrMan& addr); + bool Read(CAddrMan& addr); +}; + +#endif // BITCOIN_DB_H diff --git a/src/init.cpp b/src/init.cpp new file mode 100644 index 0000000..36d4612 --- /dev/null +++ b/src/init.cpp @@ -0,0 +1,774 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "db.h" +#include "walletdb.h" +#include "bitcoinrpc.h" +#include "net.h" +#include "init.h" +#include "util.h" +#include "ui_interface.h" +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +using namespace std; +using namespace boost; + +CWallet* pwalletMain; +CClientUIInterface uiInterface; + +////////////////////////////////////////////////////////////////////////////// +// +// Shutdown +// + +void ExitTimeout(void* parg) +{ +#ifdef WIN32 + Sleep(5000); + ExitProcess(0); +#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; + static bool fTaken; + + // Make this thread recognisable as the shutdown thread + RenameThread("bitcoin-shutoff"); + + bool fFirstThread = false; + { + TRY_LOCK(cs_Shutdown, lockShutdown); + if (lockShutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + } + static bool fExit; + if (fFirstThread) + { + fShutdown = true; + nTransactionsUpdated++; + bitdb.Flush(false); + StopNode(); + bitdb.Flush(true); + boost::filesystem::remove(GetPidFile()); + UnregisterWallet(pwalletMain); + delete pwalletMain; + CreateThread(ExitTimeout, NULL); + Sleep(50); + printf("CasinoCoin 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 + { + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); + } +} + +void HandleSIGTERM(int) +{ + fRequestShutdown = true; +} + +void HandleSIGHUP(int) +{ + fReopenDebugLog = true; +} + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Start +// +#if !defined(QT_GUI) +bool AppInit(int argc, char* argv[]) +{ + bool fRet = false; + try + { + // + // Parameters + // + // If Qt is used, parameters/casinocoin.conf are parsed in qt/bitcoin.cpp's main() + ParseParameters(argc, argv); + if (!boost::filesystem::is_directory(GetDataDir(false))) + { + fprintf(stderr, "Error: Specified directory does not exist\n"); + Shutdown(NULL); + } + ReadConfigFile(mapArgs, mapMultiArgs); + + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + // First part of help message is specific to casinocoind / RPC client + std::string strUsage = _("CasinoCoin version") + " " + FormatFullVersion() + "\n\n" + + _("Usage:") + "\n" + + " casinocoind [options] " + "\n" + + " casinocoind [options] [params] " + _("Send command to -server or casinocoind") + "\n" + + " casinocoind [options] help " + _("List commands") + "\n" + + " casinocoind [options] help " + _("Get help for a command") + "\n"; + + strUsage += "\n" + HelpMessage(); + + fprintf(stderr, "%s", strUsage.c_str()); + return false; + } + + // Command-line RPC + for (int i = 1; i < argc; i++) + if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "casinocoin:")) + fCommandLine = true; + + if (fCommandLine) + { + int ret = CommandLineRPC(argc, argv); + exit(ret); + } + + fRet = AppInit2(); + } + catch (std::exception& e) { + PrintException(&e, "AppInit()"); + } catch (...) { + PrintException(NULL, "AppInit()"); + } + if (!fRet) + Shutdown(NULL); + return fRet; +} + +extern void noui_connect(); +int main(int argc, char* argv[]) +{ + bool fRet = false; + + // Connect casinocoind signal handlers + noui_connect(); + + fRet = AppInit(argc, argv); + + if (fRet && fDaemon) + return 0; + + return 1; +} +#endif + +bool static InitError(const std::string &str) +{ + uiInterface.ThreadSafeMessageBox(str, _("CasinoCoin"), CClientUIInterface::OK | CClientUIInterface::MODAL); + return false; +} + +bool static InitWarning(const std::string &str) +{ + uiInterface.ThreadSafeMessageBox(str, _("CasinoCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + return true; +} + + +bool static Bind(const CService &addr, bool fError = true) { + if (IsLimited(addr)) + return false; + std::string strError; + if (!BindListenPort(addr, strError)) { + if (fError) + return InitError(strError); + return false; + } + return true; +} + +// Core-specific options shared between UI and daemon +std::string HelpMessage() +{ + string strUsage = _("Options:") + "\n" + + " -conf= " + _("Specify configuration file (default: casinocoin.conf)") + "\n" + + " -pid= " + _("Specify pid file (default: casinocoind.pid)") + "\n" + + " -gen " + _("Generate coins") + "\n" + + " -gen=0 " + _("Don't generate coins") + "\n" + + " -datadir= " + _("Specify data directory") + "\n" + + " -dbcache= " + _("Set database cache size in megabytes (default: 25)") + "\n" + + " -dblogsize= " + _("Set database disk log size in megabytes (default: 100)") + "\n" + + " -timeout= " + _("Specify connection timeout (in milliseconds)") + "\n" + + " -proxy= " + _("Connect through socks proxy") + "\n" + + " -socks= " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" + + " -tor= " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n" + " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" + + " -port= " + _("Listen for connections on (default: 47950 or testnet: 17950)") + "\n" + + " -maxconnections= " + _("Maintain at most connections to peers (default: 125)") + "\n" + + " -addnode= " + _("Add a node to connect to and attempt to keep the connection open") + "\n" + + " -connect= " + _("Connect only to the specified node(s)") + "\n" + + " -seednode= " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" + + " -externalip= " + _("Specify your own public address") + "\n" + + " -onlynet= " + _("Only connect to nodes in network (IPv4, IPv6 or Tor)") + "\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 if no -proxy or -connect)") + "\n" + + " -bind= " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" + + " -dnsseed " + _("Find peers using DNS lookup (default: 1 unless -connect)") + "\n" + + " -banscore= " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" + + " -bantime= " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" + + " -maxreceivebuffer= " + _("Maximum per-connection receive buffer, *1000 bytes (default: 5000)") + "\n" + + " -maxsendbuffer= " + _("Maximum per-connection send buffer, *1000 bytes (default: 1000)") + "\n" + +#ifdef USE_UPNP +#if USE_UPNP + " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n" + +#else + " -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" + + " -paytxfee= " + _("Fee per KB to add to transactions you send") + "\n" + + " -mininput= " + _("When creating transactions, ignore inputs with value less than this (default: 0.0001)") + "\n" + +#ifdef QT_GUI + " -server " + _("Accept command line and JSON-RPC commands") + "\n" + +#endif +#if !defined(WIN32) && !defined(QT_GUI) + " -daemon " + _("Run in the background as a daemon and accept commands") + "\n" + +#endif + " -testnet " + _("Use the test network") + "\n" + + " -debug " + _("Output extra debugging information. Implies all other -debug* options") + "\n" + + " -debugnet " + _("Output extra network debugging information") + "\n" + + " -logtimestamps " + _("Prepend debug output with timestamp") + "\n" + + " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n" + +#ifdef WIN32 + " -printtodebugger " + _("Send trace/debug info to debugger") + "\n" + +#endif + " -rpcuser= " + _("Username for JSON-RPC connections") + "\n" + + " -rpcpassword= " + _("Password for JSON-RPC connections") + "\n" + + " -rpcport= " + _("Listen for JSON-RPC connections on (default: 47970)") + "\n" + + " -rpcallowip= " + _("Allow JSON-RPC connections from specified IP address") + "\n" + + " -rpcconnect= " + _("Send commands to node running on (default: 127.0.0.1)") + "\n" + + " -blocknotify= " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" + + " -upgradewallet " + _("Upgrade wallet to latest format") + "\n" + + " -keypool= " + _("Set key pool size to (default: 100)") + "\n" + + " -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" + + " -checkblocks= " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" + + " -checklevel= " + _("How thorough the block verification is (0-6, default: 1)") + "\n" + + " -loadblock= " + _("Imports blocks from external blk000?.dat file") + "\n" + + " -? " + _("This help message") + "\n"; + + strUsage += string() + + _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" + + " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n" + + " -rpcsslcertificatechainfile= " + _("Server certificate file (default: server.cert)") + "\n" + + " -rpcsslprivatekeyfile= " + _("Server private key (default: server.pem)") + "\n" + + " -rpcsslciphers= " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n"; + + return strUsage; +} + +/** Initialize casinocoin. + * @pre Parameters should be parsed and config file should be read. + */ +bool AppInit2() +{ + // ********************************************************* Step 1: setup +#ifdef _MSC_VER + // Turn off microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif +#if _MSC_VER >= 1400 + // Disable confusing "helpful" text message on abort, ctrl-c + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +#endif +#ifndef WIN32 + umask(077); +#endif +#ifndef WIN32 + // Clean shutdown on SIGTERM + struct sigaction sa; + sa.sa_handler = HandleSIGTERM; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + // Reopen debug.log on SIGHUP + struct sigaction sa_hup; + sa_hup.sa_handler = HandleSIGHUP; + sigemptyset(&sa_hup.sa_mask); + sa_hup.sa_flags = 0; + sigaction(SIGHUP, &sa_hup, NULL); +#endif + + // ********************************************************* Step 2: parameter interactions + + fTestNet = GetBoolArg("-testnet"); + + SoftSetBoolArg("-irc", false); + + 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); + } + + 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); + } + + 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"); + + // -debug implies fDebug* + if (fDebug) + fDebugNet = true; + else + fDebugNet = GetBoolArg("-debugnet"); + + bitdb.SetDetach(GetBoolArg("-detachdb", false)); + +#if !defined(WIN32) && !defined(QT_GUI) + fDaemon = GetBoolArg("-daemon"); +#else + fDaemon = false; +#endif + + if (fDaemon) + fServer = true; + else + fServer = GetBoolArg("-server"); + + /* force fServer when running without GUI */ +#if !defined(QT_GUI) + fServer = true; +#endif + fPrintToConsole = GetBoolArg("-printtoconsole"); + fPrintToDebugger = GetBoolArg("-printtodebugger"); + fLogTimestamps = GetBoolArg("-logtimestamps"); + + if (mapArgs.count("-timeout")) + { + int nNewTimeout = GetArg("-timeout", 5000); + if (nNewTimeout > 0 && nNewTimeout < 600000) + nConnectTimeout = nNewTimeout; + } + + // Continue to put "/P2SH/" in the coinbase to monitor + // BIP16 support. + // This can be removed eventually... + const char* pszP2SH = "/P2SH/"; + COINBASE_FLAGS << std::vector(pszP2SH, pszP2SH+strlen(pszP2SH)); + + + if (mapArgs.count("-paytxfee")) + { + if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee)) + return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s'"), mapArgs["-paytxfee"].c_str())); + if (nTransactionFee > 0.25 * COIN) + InitWarning(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.")); + } + + if (mapArgs.count("-mininput")) + { + if (!ParseMoney(mapArgs["-mininput"], nMinimumInputValue)) + return InitError(strprintf(_("Invalid amount for -mininput=: '%s'"), mapArgs["-mininput"].c_str())); + } + + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log + + // Make sure only a single CasinoCoin process is using the data directory. + boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; + FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. + if (file) fclose(file); + static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); + if (!lock.try_lock()) + return InitError(strprintf(_("Cannot obtain a lock on data directory %s. CasinoCoin is probably already running."), GetDataDir().string().c_str())); + +#if !defined(WIN32) && !defined(QT_GUI) + if (fDaemon) + { + // Daemonize + pid_t pid = fork(); + if (pid < 0) + { + fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); + return false; + } + if (pid > 0) + { + CreatePidFile(GetPidFile(), pid); + return true; + } + + pid_t sid = setsid(); + if (sid < 0) + fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); + } +#endif + + if (!fDebug) + ShrinkDebugFile(); + printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + printf("CasinoCoin 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) + fprintf(stdout, "CasinoCoin server starting\n"); + + int64 nStart; + + // ********************************************************* Step 5: network initialization + + int nSocksVersion = GetArg("-socks", 5); + + if (nSocksVersion != 4 && nSocksVersion != 5) + return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion)); + + if (mapArgs.count("-onlynet")) { + std::set nets; + BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) { + enum Network net = ParseNetwork(snet); + if (net == NET_UNROUTABLE) + return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str())); + nets.insert(net); + } + for (int n = 0; n < NET_MAX; n++) { + enum Network net = (enum Network)n; + if (!nets.count(net)) + SetLimited(net); + } + } + + CService addrProxy; + bool fProxy = false; + if (mapArgs.count("-proxy")) { + 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); + } + fProxy = true; + } + + // -tor can override normal proxy, -notor disables tor entirely + if (!(mapArgs.count("-tor") && mapArgs["-tor"] == "0") && (fProxy || mapArgs.count("-tor"))) { + CService addrOnion; + if (!mapArgs.count("-tor")) + addrOnion = addrProxy; + else + addrOnion = CService(mapArgs["-tor"], 9050); + if (!addrOnion.IsValid()) + return InitError(strprintf(_("Invalid -tor address: '%s'"), mapArgs["-tor"].c_str())); + SetProxy(NET_TOR, addrOnion, 5); + SetReachable(NET_TOR); + } + + // 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) + { + std::string strError; + if (mapArgs.count("-bind")) { + BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) { + CService addrBind; + if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) + return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str())); + fBound |= Bind(addrBind); + } + } else { + struct in_addr inaddr_any; + inaddr_any.s_addr = INADDR_ANY; +#ifdef USE_IPV6 + if (!IsLimited(NET_IPV6)) + fBound |= Bind(CService(in6addr_any, GetListenPort()), false); +#endif + if (!IsLimited(NET_IPV4)) + fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound); + } + if (!fBound) + return InitError(_("Failed to listen on any port. Use -listen=0 if you want this.")); + } + + if (mapArgs.count("-externalip")) + { + BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) { + CService addrLocal(strAddr, GetListenPort(), fNameLookup); + if (!addrLocal.IsValid()) + return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str())); + AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); + } + } + + BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) + AddOneShot(strDest); + + // ********************************************************* Step 6: load blockchain + + if (GetBoolArg("-loadblockindextest")) + { + CTxDB txdb("r"); + txdb.LoadBlockIndex(); + PrintBlockTree(); + return false; + } + + uiInterface.InitMessage(_("Loading block index...")); + printf("Loading block index...\n"); + nStart = GetTimeMillis(); + if (!LoadBlockIndex()) + strErrors << _("Error loading blkindex.dat") << "\n"; + + // as LoadBlockIndex can take several minutes, it's possible the user + // requested to kill casinocoin-qt during the last operation. If so, exit. + // As the program has not fully started yet, Shutdown() is possibly overkill. + if (fRequestShutdown) + { + printf("Shutdown requested. Exiting.\n"); + return false; + } + printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree")) + { + PrintBlockTree(); + return false; + } + + if (mapArgs.count("-printblock")) + { + string strMatch = mapArgs["-printblock"]; + int nFound = 0; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + uint256 hash = (*mi).first; + if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) + { + CBlockIndex* pindex = (*mi).second; + CBlock block; + block.ReadFromDisk(pindex); + block.BuildMerkleTree(); + block.print(); + printf("\n"); + nFound++; + } + } + if (nFound == 0) + printf("No blocks matching %s were found\n", strMatch.c_str()); + return false; + } + + // ********************************************************* Step 7: load wallet + + uiInterface.InitMessage(_("Loading wallet...")); + printf("Loading wallet...\n"); + nStart = GetTimeMillis(); + bool fFirstRun; + pwalletMain = new CWallet("wallet.dat"); + int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun); + if (nLoadWalletRet != DB_LOAD_OK) + { + if (nLoadWalletRet == DB_CORRUPT) + strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n"; + else if (nLoadWalletRet == DB_TOO_NEW) + strErrors << _("Error loading wallet.dat: Wallet requires newer version of CasinoCoin") << "\n"; + else if (nLoadWalletRet == DB_NEED_REWRITE) + { + strErrors << _("Wallet needed to be rewritten: restart CasinoCoin to complete") << "\n"; + printf("%s", strErrors.str().c_str()); + return InitError(strErrors.str()); + } + else + strErrors << _("Error loading wallet.dat") << "\n"; + } + + if (GetBoolArg("-upgradewallet", fFirstRun)) + { + int nMaxVersion = GetArg("-upgradewallet", 0); + if (nMaxVersion == 0) // the -upgradewallet without argument case + { + printf("Performing wallet upgrade to %i\n", FEATURE_LATEST); + nMaxVersion = CLIENT_VERSION; + pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately + } + else + printf("Allowing wallet upgrade up to %i\n", nMaxVersion); + if (nMaxVersion < pwalletMain->GetVersion()) + { + printf("Max version: %i\n", nMaxVersion); + printf("Wallet version: %i\n", pwalletMain->GetVersion()); + strErrors << _("Cannot downgrade wallet") << "\n"; + } + pwalletMain->SetMaxVersion(nMaxVersion); + } + + if (fFirstRun) + { + // Create new keyUser and set as default key + RandAddSeedPerfmon(); + + CPubKey newDefaultKey; + if (!pwalletMain->GetKeyFromPool(newDefaultKey, false)) + strErrors << _("Cannot initialize keypool") << "\n"; + pwalletMain->SetDefaultKey(newDefaultKey); + if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), "")) + strErrors << _("Cannot write default address") << "\n"; + } + + printf("%s", strErrors.str().c_str()); + printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + RegisterWallet(pwalletMain); + + CBlockIndex *pindexRescan = pindexBest; + if (GetBoolArg("-rescan")) + pindexRescan = pindexGenesisBlock; + else + { + CWalletDB walletdb("wallet.dat"); + CBlockLocator locator; + if (walletdb.ReadBestBlock(locator)) + pindexRescan = locator.GetBlockIndex(); + } + if (pindexBest != pindexRescan) + { + uiInterface.InitMessage(_("Rescanning...")); + printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight); + nStart = GetTimeMillis(); + pwalletMain->ScanForWalletTransactions(pindexRescan, true); + printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart); + } + + // ********************************************************* Step 8: import blocks + + if (mapArgs.count("-loadblock")) + { + BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"]) + { + FILE *file = fopen(strFile.c_str(), "rb"); + if (file) + LoadExternalBlockFile(file); + } + } + + // ********************************************************* Step 9: load peers + + uiInterface.InitMessage(_("Loading addresses...")); + printf("Loading addresses...\n"); + nStart = GetTimeMillis(); + + { + CAddrDB adb; + if (!adb.Read(addrman)) + printf("Invalid or missing peers.dat; recreating\n"); + } + + printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n", + addrman.size(), GetTimeMillis() - nStart); + + // ********************************************************* Step 10: start node + + if (!CheckDiskSpace()) + return false; + + RandAddSeedPerfmon(); + + //// debug print + printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); + printf("nBestHeight = %d\n", nBestHeight); + printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size()); + printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size()); + printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size()); + + if (!CreateThread(StartNode, NULL)) + InitError(_("Error: could not start node")); + + if (fServer) + CreateThread(ThreadRPCServer, NULL); + + // ********************************************************* Step 11: finished + + uiInterface.InitMessage(_("Done loading")); + printf("Done loading\n"); + + if (!strErrors.str().empty()) + return InitError(strErrors.str()); + + // Add wallet transactions that aren't already in a block to mapTransactions + pwalletMain->ReacceptWalletTransactions(); + +#if !defined(QT_GUI) + // Loop until process is exit()ed from shutdown() function, + // called from ThreadRPCServer thread when a "stop" command is received. + while (1) + Sleep(5000); +#endif + + return true; +} + diff --git a/src/init.h b/src/init.h new file mode 100644 index 0000000..89230f1 --- /dev/null +++ b/src/init.h @@ -0,0 +1,19 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_INIT_H +#define BITCOIN_INIT_H + +#include "wallet.h" + +extern CWallet* pwalletMain; + +void StartShutdown(); +void Shutdown(void* parg); +bool AppInit2(); +std::string HelpMessage(); + +#endif diff --git a/src/irc.cpp b/src/irc.cpp new file mode 100644 index 0000000..35d15d9 --- /dev/null +++ b/src/irc.cpp @@ -0,0 +1,396 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "irc.h" +#include "net.h" +#include "strlcpy.h" +#include "base58.h" + +using namespace std; +using namespace boost; + +int nGotIRCAddresses = 0; + +void ThreadIRCSeed2(void* parg); + + + + +#pragma pack(push, 1) +struct ircaddr +{ + struct in_addr ip; + short port; +}; +#pragma pack(pop) + +string EncodeAddress(const CService& addr) +{ + struct ircaddr tmp; + if (addr.GetInAddr(&tmp.ip)) + { + tmp.port = htons(addr.GetPort()); + + vector vch(UBEGIN(tmp), UEND(tmp)); + return string("u") + EncodeBase58Check(vch); + } + return ""; +} + +bool DecodeAddress(string str, CService& addr) +{ + vector vch; + if (!DecodeBase58Check(str.substr(1), vch)) + return false; + + struct ircaddr tmp; + if (vch.size() != sizeof(tmp)) + return false; + memcpy(&tmp, &vch[0], sizeof(tmp)); + + addr = CService(tmp.ip, ntohs(tmp.port)); + return true; +} + + + + + + +static bool Send(SOCKET hSocket, const char* pszSend) +{ + if (strstr(pszSend, "PONG") != pszSend) + printf("IRC SENDING: %s\n", pszSend); + const char* psz = pszSend; + const char* pszEnd = psz + strlen(psz); + while (psz < pszEnd) + { + int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL); + if (ret < 0) + return false; + psz += ret; + } + return true; +} + +bool RecvLineIRC(SOCKET hSocket, string& strLine) +{ + loop + { + bool fRet = RecvLine(hSocket, strLine); + if (fRet) + { + if (fShutdown) + return false; + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() >= 1 && vWords[0] == "PING") + { + strLine[1] = 'O'; + strLine += '\r'; + Send(hSocket, strLine.c_str()); + continue; + } + } + return fRet; + } +} + +int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL, const char* psz4=NULL) +{ + loop + { + string strLine; + strLine.reserve(10000); + if (!RecvLineIRC(hSocket, strLine)) + return 0; + printf("IRC %s\n", strLine.c_str()); + if (psz1 && strLine.find(psz1) != string::npos) + return 1; + if (psz2 && strLine.find(psz2) != string::npos) + return 2; + if (psz3 && strLine.find(psz3) != string::npos) + return 3; + if (psz4 && strLine.find(psz4) != string::npos) + return 4; + } +} + +bool Wait(int nSeconds) +{ + if (fShutdown) + return false; + printf("IRC waiting %d seconds to reconnect\n", nSeconds); + for (int i = 0; i < nSeconds; i++) + { + if (fShutdown) + return false; + Sleep(1000); + } + return true; +} + +bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet) +{ + strRet.clear(); + loop + { + string strLine; + if (!RecvLineIRC(hSocket, strLine)) + return false; + + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() < 2) + continue; + + if (vWords[1] == psz1) + { + printf("IRC %s\n", strLine.c_str()); + strRet = strLine; + return true; + } + } +} + +bool GetIPFromIRC(SOCKET hSocket, string strMyName, CNetAddr& ipRet) +{ + Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str()); + + string strLine; + if (!RecvCodeLine(hSocket, "302", strLine)) + return false; + + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() < 4) + return false; + + string str = vWords[3]; + if (str.rfind("@") == string::npos) + return false; + string strHost = str.substr(str.rfind("@")+1); + + // 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()); + CNetAddr addr(strHost, true); + if (!addr.IsValid()) + return false; + ipRet = addr; + + return true; +} + + + +void ThreadIRCSeed(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadIRCSeed(parg)); + + // Make this thread recognisable as the IRC seeding thread + RenameThread("bitcoin-ircseed"); + + try + { + ThreadIRCSeed2(parg); + } + catch (std::exception& e) { + PrintExceptionContinue(&e, "ThreadIRCSeed()"); + } catch (...) { + PrintExceptionContinue(NULL, "ThreadIRCSeed()"); + } + printf("ThreadIRCSeed exited\n"); +} + +void ThreadIRCSeed2(void* parg) +{ + /* Disable IRC Seeding Entirely */ + return; + + /* Dont advertise on IRC if we don't allow incoming connections */ + if (mapArgs.count("-connect") || fNoListen) + return; + + printf("ThreadIRCSeed started\n"); + int nErrorWait = 10; + int nRetryWait = 10; + + while (!fShutdown) + { + CService addrConnect("92.243.23.21", 6667); // irc.lfnet.org + + CService addrIRC("irc.lfnet.org", 6667, true); + if (addrIRC.IsValid()) + addrConnect = addrIRC; + + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + { + printf("IRC connect failed\n"); + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname")) + { + closesocket(hSocket); + hSocket = INVALID_SOCKET; + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses + CService addrLocal; + string strMyName; + if (GetLocal(addrLocal, &addrIPv4)) + strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); + if (strMyName == "") + strMyName = strprintf("x%u", GetRand(1000000000)); + + Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); + Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); + + int nRet = RecvUntil(hSocket, " 004 ", " 433 "); + if (nRet != 1) + { + closesocket(hSocket); + hSocket = INVALID_SOCKET; + if (nRet == 2) + { + printf("IRC name already in use\n"); + Wait(10); + continue; + } + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + Sleep(500); + + // Get our external IP from the IRC server and re-nick before joining the channel + CNetAddr addrFromIRC; + if (GetIPFromIRC(hSocket, strMyName, addrFromIRC)) + { + printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str()); + if (addrFromIRC.IsRoutable()) + { + // IRC lets you to re-nick + AddLocal(addrFromIRC, LOCAL_IRC); + strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); + Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); + } + } + + if (fTestNet) { + Send(hSocket, "JOIN #casinocoinTEST3\r"); + Send(hSocket, "WHO #casinocoinTEST3\r"); + } else { + // randomly join #casinocoin00-#casinocoin99 + int channel_number = GetRandInt(100); + channel_number = 0; // CasinoCoin: for now, just use one channel + Send(hSocket, strprintf("JOIN #casinocoin%02d\r", channel_number).c_str()); + Send(hSocket, strprintf("WHO #casinocoin%02d\r", channel_number).c_str()); + } + + int64 nStart = GetTime(); + string strLine; + strLine.reserve(10000); + while (!fShutdown && RecvLineIRC(hSocket, strLine)) + { + if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') + continue; + + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() < 2) + continue; + + char pszName[10000]; + pszName[0] = '\0'; + + if (vWords[1] == "352" && vWords.size() >= 8) + { + // index 7 is limited to 16 characters + // could get full length name at index 10, but would be different from join messages + strlcpy(pszName, vWords[7].c_str(), sizeof(pszName)); + printf("IRC got who\n"); + } + + if (vWords[1] == "JOIN" && vWords[0].size() > 1) + { + // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname + strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName)); + if (strchr(pszName, '!')) + *strchr(pszName, '!') = '\0'; + printf("IRC got join\n"); + } + + if (pszName[0] == 'u') + { + CAddress addr; + if (DecodeAddress(pszName, addr)) + { + addr.nTime = GetAdjustedTime(); + if (addrman.Add(addr, addrConnect, 51 * 60)) + printf("IRC got new address: %s\n", addr.ToString().c_str()); + nGotIRCAddresses++; + } + else + { + printf("IRC decode failed\n"); + } + } + } + closesocket(hSocket); + hSocket = INVALID_SOCKET; + + if (GetTime() - nStart > 20 * 60) + { + nErrorWait /= 3; + nRetryWait /= 3; + } + + nRetryWait = nRetryWait * 11 / 10; + if (!Wait(nRetryWait += 60)) + return; + } +} + + + + + + + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR) + { + printf("Error at WSAStartup()\n"); + return false; + } + + ThreadIRCSeed(NULL); + + WSACleanup(); + return 0; +} +#endif diff --git a/src/irc.h b/src/irc.h new file mode 100644 index 0000000..f0e36af --- /dev/null +++ b/src/irc.h @@ -0,0 +1,14 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_IRC_H +#define BITCOIN_IRC_H + +void ThreadIRCSeed(void* parg); + +extern int nGotIRCAddresses; + +#endif diff --git a/src/json/LICENSE.txt b/src/json/LICENSE.txt new file mode 100644 index 0000000..797d536 --- /dev/null +++ b/src/json/LICENSE.txt @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2007 - 2009 John W. Wilkinson + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/json/json_spirit.h b/src/json/json_spirit.h new file mode 100644 index 0000000..ac1879d --- /dev/null +++ b/src/json/json_spirit.h @@ -0,0 +1,18 @@ +#ifndef JSON_SPIRIT +#define JSON_SPIRIT + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_reader.h" +#include "json_spirit_writer.h" +#include "json_spirit_utils.h" + +#endif diff --git a/src/json/json_spirit_error_position.h b/src/json/json_spirit_error_position.h new file mode 100644 index 0000000..1720850 --- /dev/null +++ b/src/json/json_spirit_error_position.h @@ -0,0 +1,54 @@ +#ifndef JSON_SPIRIT_ERROR_POSITION +#define JSON_SPIRIT_ERROR_POSITION + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +namespace json_spirit +{ + // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. + // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" + // functions that return a bool. + // + struct Error_position + { + Error_position(); + Error_position( unsigned int line, unsigned int column, const std::string& reason ); + bool operator==( const Error_position& lhs ) const; + unsigned int line_; + unsigned int column_; + std::string reason_; + }; + + inline Error_position::Error_position() + : line_( 0 ) + , column_( 0 ) + { + } + + inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) + : line_( line ) + , column_( column ) + , reason_( reason ) + { + } + + inline bool Error_position::operator==( const Error_position& lhs ) const + { + if( this == &lhs ) return true; + + return ( reason_ == lhs.reason_ ) && + ( line_ == lhs.line_ ) && + ( column_ == lhs.column_ ); +} +} + +#endif diff --git a/src/json/json_spirit_reader.cpp b/src/json/json_spirit_reader.cpp new file mode 100644 index 0000000..aa4f637 --- /dev/null +++ b/src/json/json_spirit_reader.cpp @@ -0,0 +1,137 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_reader.h" +#include "json_spirit_reader_template.h" + +using namespace json_spirit; + +bool json_spirit::read( const std::string& s, Value& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, Value& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, Value& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, Value& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif + +bool json_spirit::read( const std::string& s, mValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, mValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, mValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, mValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wmValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wmValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif diff --git a/src/json/json_spirit_reader.h b/src/json/json_spirit_reader.h new file mode 100644 index 0000000..96494a9 --- /dev/null +++ b/src/json/json_spirit_reader.h @@ -0,0 +1,62 @@ +#ifndef JSON_SPIRIT_READER +#define JSON_SPIRIT_READER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" +#include + +namespace json_spirit +{ + // functions to reads a JSON values + + bool read( const std::string& s, Value& value ); + bool read( std::istream& is, Value& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + + void read_or_throw( const std::string& s, Value& value ); + void read_or_throw( std::istream& is, Value& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wValue& value ); + bool read( std::wistream& is, wValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + + void read_or_throw( const std::wstring& s, wValue& value ); + void read_or_throw( std::wistream& is, wValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + +#endif + + bool read( const std::string& s, mValue& value ); + bool read( std::istream& is, mValue& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + + void read_or_throw( const std::string& s, mValue& value ); + void read_or_throw( std::istream& is, mValue& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wmValue& value ); + bool read( std::wistream& is, wmValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + + void read_or_throw( const std::wstring& s, wmValue& value ); + void read_or_throw( std::wistream& is, wmValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + +#endif +} + +#endif diff --git a/src/json/json_spirit_reader_template.h b/src/json/json_spirit_reader_template.h new file mode 100644 index 0000000..4dec00e --- /dev/null +++ b/src/json/json_spirit_reader_template.h @@ -0,0 +1,612 @@ +#ifndef JSON_SPIRIT_READER_TEMPLATE +#define JSON_SPIRIT_READER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" + +//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread + +#include +#include +#include + +#if BOOST_VERSION >= 103800 + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit::classic +#else + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit +#endif + +namespace json_spirit +{ + const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); + const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >(); + + template< class Iter_type > + bool is_eq( Iter_type first, Iter_type last, const char* c_str ) + { + for( Iter_type i = first; i != last; ++i, ++c_str ) + { + if( *c_str == 0 ) return false; + + if( *i != *c_str ) return false; + } + + return true; + } + + template< class Char_type > + Char_type hex_to_num( const Char_type c ) + { + if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; + if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; + if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; + return 0; + } + + template< class Char_type, class Iter_type > + Char_type hex_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); + } + + template< class Char_type, class Iter_type > + Char_type unicode_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + const Char_type c3( *( ++begin ) ); + const Char_type c4( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 12 ) + + ( hex_to_num( c2 ) << 8 ) + + ( hex_to_num( c3 ) << 4 ) + + hex_to_num( c4 ); + } + + template< class String_type > + void append_esc_char_and_incr_iter( String_type& s, + typename String_type::const_iterator& begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::value_type Char_type; + + const Char_type c2( *begin ); + + switch( c2 ) + { + case 't': s += '\t'; break; + case 'b': s += '\b'; break; + case 'f': s += '\f'; break; + case 'n': s += '\n'; break; + case 'r': s += '\r'; break; + case '\\': s += '\\'; break; + case '/': s += '/'; break; + case '"': s += '"'; break; + case 'x': + { + if( end - begin >= 3 ) // expecting "xHH..." + { + s += hex_str_to_char< Char_type >( begin ); + } + break; + } + case 'u': + { + if( end - begin >= 5 ) // expecting "uHHHH..." + { + s += unicode_str_to_char< Char_type >( begin ); + } + break; + } + } + } + + template< class String_type > + String_type substitute_esc_chars( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::const_iterator Iter_type; + + if( end - begin < 2 ) return String_type( begin, end ); + + String_type result; + + result.reserve( end - begin ); + + const Iter_type end_minus_1( end - 1 ); + + Iter_type substr_start = begin; + Iter_type i = begin; + + for( ; i < end_minus_1; ++i ) + { + if( *i == '\\' ) + { + result.append( substr_start, i ); + + ++i; // skip the '\' + + append_esc_char_and_incr_iter( result, i, end ); + + substr_start = i + 1; + } + } + + result.append( substr_start, end ); + + return result; + } + + template< class String_type > + String_type get_str_( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + assert( end - begin >= 2 ); + + typedef typename String_type::const_iterator Iter_type; + + Iter_type str_without_quotes( ++begin ); + Iter_type end_without_quotes( --end ); + + return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); + } + + inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) + { + return get_str_< std::string >( begin, end ); + } + + inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) + { + return get_str_< std::wstring >( begin, end ); + } + + template< class String_type, class Iter_type > + String_type get_str( Iter_type begin, Iter_type end ) + { + const String_type tmp( begin, end ); // convert multipass iterators to string iterators + + return get_str( tmp.begin(), tmp.end() ); + } + + // this class's methods get called by the spirit parse resulting + // in the creation of a JSON object or array + // + // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator + // + template< class Value_type, class Iter_type > + class Semantic_actions + { + public: + + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + + Semantic_actions( Value_type& value ) + : value_( value ) + , current_p_( 0 ) + { + } + + void begin_obj( Char_type c ) + { + assert( c == '{' ); + + begin_compound< Object_type >(); + } + + void end_obj( Char_type c ) + { + assert( c == '}' ); + + end_compound(); + } + + void begin_array( Char_type c ) + { + assert( c == '[' ); + + begin_compound< Array_type >(); + } + + void end_array( Char_type c ) + { + assert( c == ']' ); + + end_compound(); + } + + void new_name( Iter_type begin, Iter_type end ) + { + assert( current_p_->type() == obj_type ); + + name_ = get_str< String_type >( begin, end ); + } + + void new_str( Iter_type begin, Iter_type end ) + { + add_to_current( get_str< String_type >( begin, end ) ); + } + + void new_true( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "true" ) ); + + add_to_current( true ); + } + + void new_false( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "false" ) ); + + add_to_current( false ); + } + + void new_null( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "null" ) ); + + add_to_current( Value_type() ); + } + + void new_int( boost::int64_t i ) + { + add_to_current( i ); + } + + void new_uint64( boost::uint64_t ui ) + { + add_to_current( ui ); + } + + void new_real( double d ) + { + add_to_current( d ); + } + + private: + + Semantic_actions& operator=( const Semantic_actions& ); + // to prevent "assignment operator could not be generated" warning + + Value_type* add_first( const Value_type& value ) + { + assert( current_p_ == 0 ); + + value_ = value; + current_p_ = &value_; + return current_p_; + } + + template< class Array_or_obj > + void begin_compound() + { + if( current_p_ == 0 ) + { + add_first( Array_or_obj() ); + } + else + { + stack_.push_back( current_p_ ); + + Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place + + current_p_ = add_to_current( new_array_or_obj ); + } + } + + void end_compound() + { + if( current_p_ != &value_ ) + { + current_p_ = stack_.back(); + + stack_.pop_back(); + } + } + + Value_type* add_to_current( const Value_type& value ) + { + if( current_p_ == 0 ) + { + return add_first( value ); + } + else if( current_p_->type() == array_type ) + { + current_p_->get_array().push_back( value ); + + return ¤t_p_->get_array().back(); + } + + assert( current_p_->type() == obj_type ); + + return &Config_type::add( current_p_->get_obj(), name_, value ); + } + + Value_type& value_; // this is the object or array that is being created + Value_type* current_p_; // the child object or array that is currently being constructed + + std::vector< Value_type* > stack_; // previous child objects and arrays + + String_type name_; // of current name/value pair + }; + + template< typename Iter_type > + void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) + { + throw Error_position( i.get_position().line, i.get_position().column, reason ); + } + + template< typename Iter_type > + void throw_error( Iter_type i, const std::string& reason ) + { + throw reason; + } + + // the spirit grammer + // + template< class Value_type, class Iter_type > + class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > + { + public: + + typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; + + Json_grammer( Semantic_actions_t& semantic_actions ) + : actions_( semantic_actions ) + { + } + + static void throw_not_value( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a value" ); + } + + static void throw_not_array( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an array" ); + } + + static void throw_not_object( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an object" ); + } + + static void throw_not_pair( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a pair" ); + } + + static void throw_not_colon( Iter_type begin, Iter_type end ) + { + throw_error( begin, "no colon in pair" ); + } + + static void throw_not_string( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a string" ); + } + + template< typename ScannerT > + class definition + { + public: + + definition( const Json_grammer& self ) + { + using namespace spirit_namespace; + + typedef typename Value_type::String_type::value_type Char_type; + + // first we convert the semantic action class methods to functors with the + // parameter signature expected by spirit + + typedef boost::function< void( Char_type ) > Char_action; + typedef boost::function< void( Iter_type, Iter_type ) > Str_action; + typedef boost::function< void( double ) > Real_action; + typedef boost::function< void( boost::int64_t ) > Int_action; + typedef boost::function< void( boost::uint64_t ) > Uint64_action; + + Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); + Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); + Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); + Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); + Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); + Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); + Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); + Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); + Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); + Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); + Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); + Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); + + // actual grammer + + json_ + = value_ | eps_p[ &throw_not_value ] + ; + + value_ + = string_[ new_str ] + | number_ + | object_ + | array_ + | str_p( "true" ) [ new_true ] + | str_p( "false" )[ new_false ] + | str_p( "null" ) [ new_null ] + ; + + object_ + = ch_p('{')[ begin_obj ] + >> !members_ + >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) + ; + + members_ + = pair_ >> *( ',' >> pair_ ) + ; + + pair_ + = string_[ new_name ] + >> ( ':' | eps_p[ &throw_not_colon ] ) + >> ( value_ | eps_p[ &throw_not_value ] ) + ; + + array_ + = ch_p('[')[ begin_array ] + >> !elements_ + >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) + ; + + elements_ + = value_ >> *( ',' >> value_ ) + ; + + string_ + = lexeme_d // this causes white space inside a string to be retained + [ + confix_p + ( + '"', + *lex_escape_ch_p, + '"' + ) + ] + ; + + number_ + = strict_real_p[ new_real ] + | int64_p [ new_int ] + | uint64_p [ new_uint64 ] + ; + } + + spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; + + const spirit_namespace::rule< ScannerT >& start() const { return json_; } + }; + + private: + + Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning + + Semantic_actions_t& actions_; + }; + + template< class Iter_type, class Value_type > + Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + Semantic_actions< Value_type, Iter_type > semantic_actions( value ); + + const spirit_namespace::parse_info< Iter_type > info = + spirit_namespace::parse( begin, end, + Json_grammer< Value_type, Iter_type >( semantic_actions ), + spirit_namespace::space_p ); + + if( !info.hit ) + { + assert( false ); // in theory exception should already have been thrown + throw_error( info.stop, "error" ); + } + + return info.stop; + } + + template< class Iter_type, class Value_type > + void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; + + const Posn_iter_t posn_begin( begin, end ); + const Posn_iter_t posn_end( end, end ); + + read_range_or_throw( posn_begin, posn_end, value ); + } + + template< class Iter_type, class Value_type > + bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) + { + try + { + begin = read_range_or_throw( begin, end, value ); + + return true; + } + catch( ... ) + { + return false; + } + } + + template< class String_type, class Value_type > + void read_string_or_throw( const String_type& s, Value_type& value ) + { + add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); + } + + template< class String_type, class Value_type > + bool read_string( const String_type& s, Value_type& value ) + { + typename String_type::const_iterator begin = s.begin(); + + return read_range( begin, s.end(), value ); + } + + template< class Istream_type > + struct Multi_pass_iters + { + typedef typename Istream_type::char_type Char_type; + typedef std::istream_iterator< Char_type, Char_type > istream_iter; + typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; + + Multi_pass_iters( Istream_type& is ) + { + is.unsetf( std::ios::skipws ); + + begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); + end_ = spirit_namespace::make_multi_pass( istream_iter() ); + } + + Mp_iter begin_; + Mp_iter end_; + }; + + template< class Istream_type, class Value_type > + bool read_stream( Istream_type& is, Value_type& value ) + { + Multi_pass_iters< Istream_type > mp_iters( is ); + + return read_range( mp_iters.begin_, mp_iters.end_, value ); + } + + template< class Istream_type, class Value_type > + void read_stream_or_throw( Istream_type& is, Value_type& value ) + { + const Multi_pass_iters< Istream_type > mp_iters( is ); + + add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); + } +} + +#endif diff --git a/src/json/json_spirit_stream_reader.h b/src/json/json_spirit_stream_reader.h new file mode 100644 index 0000000..7e59c9a --- /dev/null +++ b/src/json/json_spirit_stream_reader.h @@ -0,0 +1,70 @@ +#ifndef JSON_SPIRIT_READ_STREAM +#define JSON_SPIRIT_READ_STREAM + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_reader_template.h" + +namespace json_spirit +{ + // these classes allows you to read multiple top level contiguous values from a stream, + // the normal stream read functions have a bug that prevent multiple top level values + // from being read unless they are separated by spaces + + template< class Istream_type, class Value_type > + class Stream_reader + { + public: + + Stream_reader( Istream_type& is ) + : iters_( is ) + { + } + + bool read_next( Value_type& value ) + { + return read_range( iters_.begin_, iters_.end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + + Mp_iters iters_; + }; + + template< class Istream_type, class Value_type > + class Stream_reader_thrower + { + public: + + Stream_reader_thrower( Istream_type& is ) + : iters_( is ) + , posn_begin_( iters_.begin_, iters_.end_ ) + , posn_end_( iters_.end_, iters_.end_ ) + { + } + + void read_next( Value_type& value ) + { + posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; + + Mp_iters iters_; + Posn_iter_t posn_begin_, posn_end_; + }; +} + +#endif diff --git a/src/json/json_spirit_utils.h b/src/json/json_spirit_utils.h new file mode 100644 index 0000000..553e3b9 --- /dev/null +++ b/src/json/json_spirit_utils.h @@ -0,0 +1,61 @@ +#ifndef JSON_SPIRIT_UTILS +#define JSON_SPIRIT_UTILS + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + template< class Obj_t, class Map_t > + void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) + { + mp_obj.clear(); + + for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + mp_obj[ i->name_ ] = i->value_; + } + } + + template< class Obj_t, class Map_t > + void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) + { + obj.clear(); + + for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) + { + obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); + } + } + + typedef std::map< std::string, Value > Mapped_obj; + +#ifndef BOOST_NO_STD_WSTRING + typedef std::map< std::wstring, wValue > wMapped_obj; +#endif + + template< class Object_type, class String_type > + const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) + { + for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + if( i->name_ == name ) + { + return i->value_; + } + } + + return Object_type::value_type::Value_type::null; + } +} + +#endif diff --git a/src/json/json_spirit_value.cpp b/src/json/json_spirit_value.cpp new file mode 100644 index 0000000..44d2f06 --- /dev/null +++ b/src/json/json_spirit_value.cpp @@ -0,0 +1,8 @@ +/* Copyright (c) 2007 John W Wilkinson + + This source code can be used for any purpose as long as + this comment is retained. */ + +// json spirit version 2.00 + +#include "json_spirit_value.h" diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h new file mode 100644 index 0000000..7e83a2a --- /dev/null +++ b/src/json/json_spirit_value.h @@ -0,0 +1,534 @@ +#ifndef JSON_SPIRIT_VALUE +#define JSON_SPIRIT_VALUE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace json_spirit +{ + enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; + static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"}; + + template< class Config > // Config determines whether the value uses std::string or std::wstring and + // whether JSON Objects are represented as vectors or maps + class Value_impl + { + public: + + typedef Config Config_type; + typedef typename Config::String_type String_type; + typedef typename Config::Object_type Object; + typedef typename Config::Array_type Array; + typedef typename String_type::const_pointer Const_str_ptr; // eg const char* + + Value_impl(); // creates null value + Value_impl( Const_str_ptr value ); + Value_impl( const String_type& value ); + Value_impl( const Object& value ); + Value_impl( const Array& value ); + Value_impl( bool value ); + Value_impl( int value ); + Value_impl( boost::int64_t value ); + Value_impl( boost::uint64_t value ); + Value_impl( double value ); + + Value_impl( const Value_impl& other ); + + bool operator==( const Value_impl& lhs ) const; + + Value_impl& operator=( const Value_impl& lhs ); + + Value_type type() const; + + bool is_uint64() const; + bool is_null() const; + + const String_type& get_str() const; + const Object& get_obj() const; + const Array& get_array() const; + bool get_bool() const; + int get_int() const; + boost::int64_t get_int64() const; + boost::uint64_t get_uint64() const; + double get_real() const; + + Object& get_obj(); + Array& get_array(); + + template< typename T > T get_value() const; // example usage: int i = value.get_value< int >(); + // or double d = value.get_value< double >(); + + static const Value_impl null; + + private: + + void check_type( const Value_type vtype ) const; + + typedef boost::variant< String_type, + boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, + bool, boost::int64_t, double > Variant; + + Value_type type_; + Variant v_; + bool is_uint64_; + }; + + // vector objects + + template< class Config > + struct Pair_impl + { + typedef typename Config::String_type String_type; + typedef typename Config::Value_type Value_type; + + Pair_impl( const String_type& name, const Value_type& value ); + + bool operator==( const Pair_impl& lhs ) const; + + String_type name_; + Value_type value_; + }; + + template< class String > + struct Config_vector + { + typedef String String_type; + typedef Value_impl< Config_vector > Value_type; + typedef Pair_impl < Config_vector > Pair_type; + typedef std::vector< Value_type > Array_type; + typedef std::vector< Pair_type > Object_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + obj.push_back( Pair_type( name , value ) ); + + return obj.back().value_; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.name_; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.value_; + } + }; + + // typedefs for ASCII + + typedef Config_vector< std::string > Config; + + typedef Config::Value_type Value; + typedef Config::Pair_type Pair; + typedef Config::Object_type Object; + typedef Config::Array_type Array; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_vector< std::wstring > wConfig; + + typedef wConfig::Value_type wValue; + typedef wConfig::Pair_type wPair; + typedef wConfig::Object_type wObject; + typedef wConfig::Array_type wArray; +#endif + + // map objects + + template< class String > + struct Config_map + { + typedef String String_type; + typedef Value_impl< Config_map > Value_type; + typedef std::vector< Value_type > Array_type; + typedef std::map< String_type, Value_type > Object_type; + typedef typename Object_type::value_type Pair_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + return obj[ name ] = value; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.first; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.second; + } + }; + + // typedefs for ASCII + + typedef Config_map< std::string > mConfig; + + typedef mConfig::Value_type mValue; + typedef mConfig::Object_type mObject; + typedef mConfig::Array_type mArray; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_map< std::wstring > wmConfig; + + typedef wmConfig::Value_type wmValue; + typedef wmConfig::Object_type wmObject; + typedef wmConfig::Array_type wmArray; + +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////// + // + // implementation + + template< class Config > + const Value_impl< Config > Value_impl< Config >::null; + + template< class Config > + Value_impl< Config >::Value_impl() + : type_( null_type ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Const_str_ptr value ) + : type_( str_type ) + , v_( String_type( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const String_type& value ) + : type_( str_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Object& value ) + : type_( obj_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Array& value ) + : type_( array_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( bool value ) + : type_( bool_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( int value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::int64_t value ) + : type_( int_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::uint64_t value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( true ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( double value ) + : type_( real_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) + : type_( other.type() ) + , v_( other.v_ ) + , is_uint64_( other.is_uint64_ ) + { + } + + template< class Config > + Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) + { + Value_impl tmp( lhs ); + + std::swap( type_, tmp.type_ ); + std::swap( v_, tmp.v_ ); + std::swap( is_uint64_, tmp.is_uint64_ ); + + return *this; + } + + template< class Config > + bool Value_impl< Config >::operator==( const Value_impl& lhs ) const + { + if( this == &lhs ) return true; + + if( type() != lhs.type() ) return false; + + return v_ == lhs.v_; + } + + template< class Config > + Value_type Value_impl< Config >::type() const + { + return type_; + } + + template< class Config > + bool Value_impl< Config >::is_uint64() const + { + return is_uint64_; + } + + template< class Config > + bool Value_impl< Config >::is_null() const + { + return type() == null_type; + } + + template< class Config > + void Value_impl< Config >::check_type( const Value_type vtype ) const + { + if( type() != vtype ) + { + std::ostringstream os; + + ///// Bitcoin: Tell the types by name instead of by number + os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype]; + + throw std::runtime_error( os.str() ); + } + } + + template< class Config > + const typename Config::String_type& Value_impl< Config >::get_str() const + { + check_type( str_type ); + + return *boost::get< String_type >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + bool Value_impl< Config >::get_bool() const + { + check_type( bool_type ); + + return boost::get< bool >( v_ ); + } + + template< class Config > + int Value_impl< Config >::get_int() const + { + check_type( int_type ); + + return static_cast< int >( get_int64() ); + } + + template< class Config > + boost::int64_t Value_impl< Config >::get_int64() const + { + check_type( int_type ); + + return boost::get< boost::int64_t >( v_ ); + } + + template< class Config > + boost::uint64_t Value_impl< Config >::get_uint64() const + { + check_type( int_type ); + + return static_cast< boost::uint64_t >( get_int64() ); + } + + template< class Config > + double Value_impl< Config >::get_real() const + { + if( type() == int_type ) + { + return is_uint64() ? static_cast< double >( get_uint64() ) + : static_cast< double >( get_int64() ); + } + + check_type( real_type ); + + return boost::get< double >( v_ ); + } + + template< class Config > + typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + typename Value_impl< Config >::Array& Value_impl< Config >::get_array() + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) + : name_( name ) + , value_( value ) + { + } + + template< class Config > + bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const + { + if( this == &lhs ) return true; + + return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); + } + + // converts a C string, ie. 8 bit char array, to a string object + // + template < class String_type > + String_type to_str( const char* c_str ) + { + String_type result; + + for( const char* p = c_str; *p != 0; ++p ) + { + result += *p; + } + + return result; + } + + // + + namespace internal_ + { + template< typename T > + struct Type_to_type + { + }; + + template< class Value > + int get_value( const Value& value, Type_to_type< int > ) + { + return value.get_int(); + } + + template< class Value > + boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > ) + { + return value.get_int64(); + } + + template< class Value > + boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > ) + { + return value.get_uint64(); + } + + template< class Value > + double get_value( const Value& value, Type_to_type< double > ) + { + return value.get_real(); + } + + template< class Value > + typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) + { + return value.get_str(); + } + + template< class Value > + typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) + { + return value.get_array(); + } + + template< class Value > + typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) + { + return value.get_obj(); + } + + template< class Value > + bool get_value( const Value& value, Type_to_type< bool > ) + { + return value.get_bool(); + } + } + + template< class Config > + template< typename T > + T Value_impl< Config >::get_value() const + { + return internal_::get_value( *this, internal_::Type_to_type< T >() ); + } +} + +#endif diff --git a/src/json/json_spirit_writer.cpp b/src/json/json_spirit_writer.cpp new file mode 100644 index 0000000..d24a632 --- /dev/null +++ b/src/json/json_spirit_writer.cpp @@ -0,0 +1,95 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_writer.h" +#include "json_spirit_writer_template.h" + +void json_spirit::write( const Value& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const Value& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const Value& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const Value& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wValue& value ) +{ + return write_string( value, true ); +} + +#endif + +void json_spirit::write( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const mValue& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const mValue& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wmValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wmValue& value ) +{ + return write_string( value, true ); +} + +#endif diff --git a/src/json/json_spirit_writer.h b/src/json/json_spirit_writer.h new file mode 100644 index 0000000..52e1406 --- /dev/null +++ b/src/json/json_spirit_writer.h @@ -0,0 +1,50 @@ +#ifndef JSON_SPIRIT_WRITER +#define JSON_SPIRIT_WRITER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + // functions to convert JSON Values to text, + // the "formatted" versions add whitespace to format the output nicely + + void write ( const Value& value, std::ostream& os ); + void write_formatted( const Value& value, std::ostream& os ); + std::string write ( const Value& value ); + std::string write_formatted( const Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wValue& value, std::wostream& os ); + void write_formatted( const wValue& value, std::wostream& os ); + std::wstring write ( const wValue& value ); + std::wstring write_formatted( const wValue& value ); + +#endif + + void write ( const mValue& value, std::ostream& os ); + void write_formatted( const mValue& value, std::ostream& os ); + std::string write ( const mValue& value ); + std::string write_formatted( const mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wmValue& value, std::wostream& os ); + void write_formatted( const wmValue& value, std::wostream& os ); + std::wstring write ( const wmValue& value ); + std::wstring write_formatted( const wmValue& value ); + +#endif +} + +#endif diff --git a/src/json/json_spirit_writer_template.h b/src/json/json_spirit_writer_template.h new file mode 100644 index 0000000..28c49dd --- /dev/null +++ b/src/json/json_spirit_writer_template.h @@ -0,0 +1,248 @@ +#ifndef JSON_SPIRIT_WRITER_TEMPLATE +#define JSON_SPIRIT_WRITER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" + +#include +#include +#include + +namespace json_spirit +{ + inline char to_hex_char( unsigned int c ) + { + assert( c <= 0xF ); + + const char ch = static_cast< char >( c ); + + if( ch < 10 ) return '0' + ch; + + return 'A' - 10 + ch; + } + + template< class String_type > + String_type non_printable_to_string( unsigned int c ) + { + typedef typename String_type::value_type Char_type; + + String_type result( 6, '\\' ); + + result[1] = 'u'; + + result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 2 ] = to_hex_char( c & 0x000F ); + + return result; + } + + template< typename Char_type, class String_type > + bool add_esc_char( Char_type c, String_type& s ) + { + switch( c ) + { + case '"': s += to_str< String_type >( "\\\"" ); return true; + case '\\': s += to_str< String_type >( "\\\\" ); return true; + case '\b': s += to_str< String_type >( "\\b" ); return true; + case '\f': s += to_str< String_type >( "\\f" ); return true; + case '\n': s += to_str< String_type >( "\\n" ); return true; + case '\r': s += to_str< String_type >( "\\r" ); return true; + case '\t': s += to_str< String_type >( "\\t" ); return true; + } + + return false; + } + + template< class String_type > + String_type add_esc_chars( const String_type& s ) + { + typedef typename String_type::const_iterator Iter_type; + typedef typename String_type::value_type Char_type; + + String_type result; + + const Iter_type end( s.end() ); + + for( Iter_type i = s.begin(); i != end; ++i ) + { + const Char_type c( *i ); + + if( add_esc_char( c, result ) ) continue; + + const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); + + if( iswprint( unsigned_c ) ) + { + result += c; + } + else + { + result += non_printable_to_string< String_type >( unsigned_c ); + } + } + + return result; + } + + // this class generates the JSON text, + // it keeps track of the indentation level etc. + // + template< class Value_type, class Ostream_type > + class Generator + { + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + typedef typename Object_type::value_type Obj_member_type; + + public: + + Generator( const Value_type& value, Ostream_type& os, bool pretty ) + : os_( os ) + , indentation_level_( 0 ) + , pretty_( pretty ) + { + output( value ); + } + + private: + + void output( const Value_type& value ) + { + switch( value.type() ) + { + case obj_type: output( value.get_obj() ); break; + case array_type: output( value.get_array() ); break; + case str_type: output( value.get_str() ); break; + case bool_type: output( value.get_bool() ); break; + case int_type: output_int( value ); break; + + /// Bitcoin: Added std::fixed and changed precision from 16 to 8 + case real_type: os_ << std::showpoint << std::fixed << std::setprecision(8) + << value.get_real(); break; + + case null_type: os_ << "null"; break; + default: assert( false ); + } + } + + void output( const Object_type& obj ) + { + output_array_or_obj( obj, '{', '}' ); + } + + void output( const Array_type& arr ) + { + output_array_or_obj( arr, '[', ']' ); + } + + void output( const Obj_member_type& member ) + { + output( Config_type::get_name( member ) ); space(); + os_ << ':'; space(); + output( Config_type::get_value( member ) ); + } + + void output_int( const Value_type& value ) + { + if( value.is_uint64() ) + { + os_ << value.get_uint64(); + } + else + { + os_ << value.get_int64(); + } + } + + void output( const String_type& s ) + { + os_ << '"' << add_esc_chars( s ) << '"'; + } + + void output( bool b ) + { + os_ << to_str< String_type >( b ? "true" : "false" ); + } + + template< class T > + void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) + { + os_ << start_char; new_line(); + + ++indentation_level_; + + for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) + { + indent(); output( *i ); + + typename T::const_iterator next = i; + + if( ++next != t.end()) + { + os_ << ','; + } + + new_line(); + } + + --indentation_level_; + + indent(); os_ << end_char; + } + + void indent() + { + if( !pretty_ ) return; + + for( int i = 0; i < indentation_level_; ++i ) + { + os_ << " "; + } + } + + void space() + { + if( pretty_ ) os_ << ' '; + } + + void new_line() + { + if( pretty_ ) os_ << '\n'; + } + + Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning + + Ostream_type& os_; + int indentation_level_; + bool pretty_; + }; + + template< class Value_type, class Ostream_type > + void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) + { + Generator< Value_type, Ostream_type >( value, os, pretty ); + } + + template< class Value_type > + typename Value_type::String_type write_string( const Value_type& value, bool pretty ) + { + typedef typename Value_type::String_type::value_type Char_type; + + std::basic_ostringstream< Char_type > os; + + write_stream( value, os, pretty ); + + return os.str(); + } +} + +#endif diff --git a/src/key.cpp b/src/key.cpp new file mode 100644 index 0000000..6a5dcf0 --- /dev/null +++ b/src/key.cpp @@ -0,0 +1,387 @@ +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include + +#include "key.h" + +// Generate a private key from just the secret parameter +int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) +{ + int ok = 0; + BN_CTX *ctx = NULL; + EC_POINT *pub_key = NULL; + + if (!eckey) return 0; + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + pub_key = EC_POINT_new(group); + + if (pub_key == NULL) + goto err; + + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) + goto err; + + EC_KEY_set_private_key(eckey,priv_key); + EC_KEY_set_public_key(eckey,pub_key); + + ok = 1; + +err: + + if (pub_key) + EC_POINT_free(pub_key); + if (ctx != NULL) + BN_CTX_free(ctx); + + return(ok); +} + +// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields +// recid selects which key is recovered +// if check is nonzero, additional checks are performed +int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) +{ + if (!eckey) return 0; + + int ret = 0; + BN_CTX *ctx = NULL; + + BIGNUM *x = NULL; + BIGNUM *e = NULL; + BIGNUM *order = NULL; + BIGNUM *sor = NULL; + BIGNUM *eor = NULL; + BIGNUM *field = NULL; + EC_POINT *R = NULL; + EC_POINT *O = NULL; + EC_POINT *Q = NULL; + BIGNUM *rr = NULL; + BIGNUM *zero = NULL; + int n = 0; + int i = recid / 2; + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; } + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; } + x = BN_CTX_get(ctx); + if (!BN_copy(x, order)) { ret=-1; goto err; } + if (!BN_mul_word(x, i)) { ret=-1; goto err; } + if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; } + field = BN_CTX_get(ctx); + if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } + if (BN_cmp(x, field) >= 0) { ret=0; goto err; } + if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; } + if (check) + { + if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; } + if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; } + } + if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + n = EC_GROUP_get_degree(group); + e = BN_CTX_get(ctx); + if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } + if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); + zero = BN_CTX_get(ctx); + if (!BN_zero(zero)) { ret=-1; goto err; } + if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } + rr = BN_CTX_get(ctx); + if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; } + sor = BN_CTX_get(ctx); + if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; } + eor = BN_CTX_get(ctx); + if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } + if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } + if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; } + + ret = 1; + +err: + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (R != NULL) EC_POINT_free(R); + if (O != NULL) EC_POINT_free(O); + if (Q != NULL) EC_POINT_free(Q); + return ret; +} + +void CKey::SetCompressedPubKey() +{ + EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED); + fCompressedPubKey = true; +} + +void CKey::Reset() +{ + fCompressedPubKey = false; + if (pkey != NULL) + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); + fSet = false; +} + +CKey::CKey() +{ + pkey = NULL; + Reset(); +} + +CKey::CKey(const CKey& b) +{ + pkey = EC_KEY_dup(b.pkey); + if (pkey == NULL) + throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); + fSet = b.fSet; +} + +CKey& CKey::operator=(const CKey& b) +{ + if (!EC_KEY_copy(pkey, b.pkey)) + throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); + fSet = b.fSet; + return (*this); +} + +CKey::~CKey() +{ + EC_KEY_free(pkey); +} + +bool CKey::IsNull() const +{ + return !fSet; +} + +bool CKey::IsCompressed() const +{ + return fCompressedPubKey; +} + +void CKey::MakeNewKey(bool fCompressed) +{ + if (!EC_KEY_generate_key(pkey)) + throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); + if (fCompressed) + SetCompressedPubKey(); + fSet = true; +} + +bool CKey::SetPrivKey(const CPrivKey& vchPrivKey) +{ + const unsigned char* pbegin = &vchPrivKey[0]; + if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) + return false; + fSet = true; + return true; +} + +bool CKey::SetSecret(const CSecret& vchSecret, bool fCompressed) +{ + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed"); + if (vchSecret.size() != 32) + throw key_error("CKey::SetSecret() : secret must be 32 bytes"); + BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new()); + if (bn == NULL) + throw key_error("CKey::SetSecret() : BN_bin2bn failed"); + if (!EC_KEY_regenerate_key(pkey,bn)) + { + BN_clear_free(bn); + throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed"); + } + BN_clear_free(bn); + fSet = true; + if (fCompressed || fCompressedPubKey) + SetCompressedPubKey(); + return true; +} + +CSecret CKey::GetSecret(bool &fCompressed) const +{ + CSecret vchRet; + vchRet.resize(32); + const BIGNUM *bn = EC_KEY_get0_private_key(pkey); + int nBytes = BN_num_bytes(bn); + if (bn == NULL) + throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed"); + int n=BN_bn2bin(bn,&vchRet[32 - nBytes]); + if (n != nBytes) + throw key_error("CKey::GetSecret(): BN_bn2bin failed"); + fCompressed = fCompressedPubKey; + return vchRet; +} + +CPrivKey CKey::GetPrivKey() const +{ + int nSize = i2d_ECPrivateKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed"); + CPrivKey vchPrivKey(nSize, 0); + unsigned char* pbegin = &vchPrivKey[0]; + if (i2d_ECPrivateKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size"); + return vchPrivKey; +} + +bool CKey::SetPubKey(const CPubKey& vchPubKey) +{ + const unsigned char* pbegin = &vchPubKey.vchPubKey[0]; + if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.vchPubKey.size())) + return false; + fSet = true; + if (vchPubKey.vchPubKey.size() == 33) + SetCompressedPubKey(); + return true; +} + +CPubKey CKey::GetPubKey() const +{ + int nSize = i2o_ECPublicKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed"); + std::vector vchPubKey(nSize, 0); + unsigned char* pbegin = &vchPubKey[0]; + if (i2o_ECPublicKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); + return CPubKey(vchPubKey); +} + +bool CKey::Sign(uint256 hash, std::vector& vchSig) +{ + unsigned int nSize = ECDSA_size(pkey); + vchSig.resize(nSize); // Make sure it is big enough + if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey)) + { + vchSig.clear(); + return false; + } + vchSig.resize(nSize); // Shrink to fit actual size + return true; +} + +// create a compact signature (65 bytes), which allows reconstructing the used public key +// The format is one header byte, followed by two times 32 bytes for the serialized r and s values. +// The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, +// 0x1D = second key with even y, 0x1E = second key with odd y +bool CKey::SignCompact(uint256 hash, std::vector& vchSig) +{ + bool fOk = false; + ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); + if (sig==NULL) + return false; + vchSig.clear(); + vchSig.resize(65,0); + int nBitsR = BN_num_bits(sig->r); + int nBitsS = BN_num_bits(sig->s); + if (nBitsR <= 256 && nBitsS <= 256) + { + int nRecId = -1; + for (int i=0; i<4; i++) + { + CKey keyRec; + keyRec.fSet = true; + if (fCompressedPubKey) + keyRec.SetCompressedPubKey(); + if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1) + if (keyRec.GetPubKey() == this->GetPubKey()) + { + nRecId = i; + break; + } + } + + if (nRecId == -1) + throw key_error("CKey::SignCompact() : unable to construct recoverable key"); + + vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0); + BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]); + BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]); + fOk = true; + } + ECDSA_SIG_free(sig); + return fOk; +} + +// reconstruct public key from a compact signature +// This is only slightly more CPU intensive than just verifying it. +// If this function succeeds, the recovered public key is guaranteed to be valid +// (the signature is a valid signature of the given data for that key) +bool CKey::SetCompactSignature(uint256 hash, const std::vector& vchSig) +{ + if (vchSig.size() != 65) + return false; + int nV = vchSig[0]; + if (nV<27 || nV>=35) + return false; + ECDSA_SIG *sig = ECDSA_SIG_new(); + BN_bin2bn(&vchSig[1],32,sig->r); + BN_bin2bn(&vchSig[33],32,sig->s); + + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (nV >= 31) + { + SetCompressedPubKey(); + nV -= 4; + } + if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1) + { + fSet = true; + ECDSA_SIG_free(sig); + return true; + } + return false; +} + +bool CKey::Verify(uint256 hash, const std::vector& vchSig) +{ + // -1 = error, 0 = bad sig, 1 = good + if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) + return false; + + return true; +} + +bool CKey::VerifyCompact(uint256 hash, const std::vector& vchSig) +{ + CKey key; + if (!key.SetCompactSignature(hash, vchSig)) + return false; + if (GetPubKey() != key.GetPubKey()) + return false; + + return true; +} + +bool CKey::IsValid() +{ + if (!fSet) + return false; + + bool fCompr; + CSecret secret = GetSecret(fCompr); + CKey key2; + key2.SetSecret(secret, fCompr); + return GetPubKey() == key2.GetPubKey(); +} diff --git a/src/key.h b/src/key.h new file mode 100644 index 0000000..9d02707 --- /dev/null +++ b/src/key.h @@ -0,0 +1,164 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_KEY_H +#define BITCOIN_KEY_H + +#include +#include + +#include "allocators.h" +#include "serialize.h" +#include "uint256.h" +#include "util.h" + +#include // for EC_KEY definition + +// secp160k1 +// const unsigned int PRIVATE_KEY_SIZE = 192; +// const unsigned int PUBLIC_KEY_SIZE = 41; +// const unsigned int SIGNATURE_SIZE = 48; +// +// secp192k1 +// const unsigned int PRIVATE_KEY_SIZE = 222; +// const unsigned int PUBLIC_KEY_SIZE = 49; +// const unsigned int SIGNATURE_SIZE = 57; +// +// secp224k1 +// const unsigned int PRIVATE_KEY_SIZE = 250; +// const unsigned int PUBLIC_KEY_SIZE = 57; +// const unsigned int SIGNATURE_SIZE = 66; +// +// secp256k1: +// const unsigned int PRIVATE_KEY_SIZE = 279; +// const unsigned int PUBLIC_KEY_SIZE = 65; +// const unsigned int SIGNATURE_SIZE = 72; +// +// see www.keylength.com +// script supports up to 75 for single byte push + +class key_error : public std::runtime_error +{ +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 vchPubKey; + friend class CKey; + +public: + CPubKey() { } + CPubKey(const std::vector &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 Raw() const { + return vchPubKey; + } +}; + + +// secure_allocator is defined in serialize.h +// CPrivKey is a serialized private key, with all parameters included (279 bytes) +typedef std::vector > CPrivKey; +// CSecret is a serialization of just the secret parameter (32 bytes) +typedef std::vector > CSecret; + +/** An encapsulated OpenSSL Elliptic Curve key (public and/or private) */ +class CKey +{ +protected: + EC_KEY* pkey; + bool fSet; + bool fCompressedPubKey; + + void SetCompressedPubKey(); + +public: + + void Reset(); + + CKey(); + CKey(const CKey& b); + + CKey& operator=(const CKey& b); + + ~CKey(); + + bool IsNull() const; + bool IsCompressed() const; + + void MakeNewKey(bool fCompressed); + bool SetPrivKey(const CPrivKey& vchPrivKey); + bool SetSecret(const CSecret& vchSecret, bool fCompressed = false); + CSecret GetSecret(bool &fCompressed) const; + CPrivKey GetPrivKey() const; + bool SetPubKey(const CPubKey& vchPubKey); + CPubKey GetPubKey() const; + + bool Sign(uint256 hash, std::vector& vchSig); + + // create a compact signature (65 bytes), which allows reconstructing the used public key + // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. + // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, + // 0x1D = second key with even y, 0x1E = second key with odd y + bool SignCompact(uint256 hash, std::vector& vchSig); + + // reconstruct public key from a compact signature + // This is only slightly more CPU intensive than just verifying it. + // If this function succeeds, the recovered public key is guaranteed to be valid + // (the signature is a valid signature of the given data for that key) + bool SetCompactSignature(uint256 hash, const std::vector& vchSig); + + bool Verify(uint256 hash, const std::vector& vchSig); + + // Verify a compact signature + bool VerifyCompact(uint256 hash, const std::vector& vchSig); + + bool IsValid(); +}; + +#endif diff --git a/src/keystore.cpp b/src/keystore.cpp new file mode 100644 index 0000000..5251703 --- /dev/null +++ b/src/keystore.cpp @@ -0,0 +1,223 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "keystore.h" +#include "script.h" + +bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const +{ + CKey key; + if (!GetKey(address, key)) + return false; + vchPubKeyOut = key.GetPubKey(); + return true; +} + +bool CBasicKeyStore::AddKey(const CKey& key) +{ + bool fCompressed = false; + CSecret secret = key.GetSecret(fCompressed); + { + LOCK(cs_KeyStore); + mapKeys[key.GetPubKey().GetID()] = make_pair(secret, fCompressed); + } + return true; +} + +bool CBasicKeyStore::AddCScript(const CScript& redeemScript) +{ + { + LOCK(cs_KeyStore); + mapScripts[redeemScript.GetID()] = redeemScript; + } + return true; +} + +bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const +{ + bool result; + { + LOCK(cs_KeyStore); + result = (mapScripts.count(hash) > 0); + } + return result; +} + + +bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const +{ + { + LOCK(cs_KeyStore); + ScriptMap::const_iterator mi = mapScripts.find(hash); + if (mi != mapScripts.end()) + { + redeemScriptOut = (*mi).second; + return true; + } + } + return false; +} + +bool CCryptoKeyStore::SetCrypted() +{ + { + LOCK(cs_KeyStore); + if (fUseCrypto) + return true; + if (!mapKeys.empty()) + return false; + fUseCrypto = true; + } + return true; +} + +bool CCryptoKeyStore::Lock() +{ + if (!SetCrypted()) + return false; + + { + LOCK(cs_KeyStore); + vMasterKey.clear(); + } + + NotifyStatusChanged(this); + return true; +} + +bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) +{ + { + LOCK(cs_KeyStore); + if (!SetCrypted()) + return false; + + CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); + for (; mi != mapCryptedKeys.end(); ++mi) + { + const CPubKey &vchPubKey = (*mi).second.first; + const std::vector &vchCryptedSecret = (*mi).second.second; + CSecret vchSecret; + if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) + return false; + if (vchSecret.size() != 32) + return false; + CKey key; + key.SetPubKey(vchPubKey); + key.SetSecret(vchSecret); + if (key.GetPubKey() == vchPubKey) + break; + return false; + } + vMasterKey = vMasterKeyIn; + } + NotifyStatusChanged(this); + return true; +} + +bool CCryptoKeyStore::AddKey(const CKey& key) +{ + { + LOCK(cs_KeyStore); + if (!IsCrypted()) + return CBasicKeyStore::AddKey(key); + + if (IsLocked()) + return false; + + std::vector vchCryptedSecret; + CPubKey vchPubKey = key.GetPubKey(); + bool fCompressed; + if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret)) + return false; + + if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) + return false; + } + return true; +} + + +bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) +{ + { + LOCK(cs_KeyStore); + if (!SetCrypted()) + return false; + + mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret); + } + return true; +} + +bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const +{ + { + LOCK(cs_KeyStore); + if (!IsCrypted()) + return CBasicKeyStore::GetKey(address, keyOut); + + CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); + if (mi != mapCryptedKeys.end()) + { + const CPubKey &vchPubKey = (*mi).second.first; + const std::vector &vchCryptedSecret = (*mi).second.second; + CSecret vchSecret; + if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) + return false; + if (vchSecret.size() != 32) + return false; + keyOut.SetPubKey(vchPubKey); + keyOut.SetSecret(vchSecret); + return true; + } + } + return false; +} + +bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const +{ + { + LOCK(cs_KeyStore); + if (!IsCrypted()) + return CKeyStore::GetPubKey(address, vchPubKeyOut); + + CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); + if (mi != mapCryptedKeys.end()) + { + vchPubKeyOut = (*mi).second.first; + return true; + } + } + return false; +} + +bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) +{ + { + LOCK(cs_KeyStore); + if (!mapCryptedKeys.empty() || IsCrypted()) + return false; + + fUseCrypto = true; + BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys) + { + CKey key; + if (!key.SetSecret(mKey.second.first, mKey.second.second)) + return false; + const CPubKey vchPubKey = key.GetPubKey(); + std::vector vchCryptedSecret; + bool fCompressed; + if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret)) + return false; + if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) + return false; + } + mapKeys.clear(); + } + return true; +} diff --git a/src/keystore.h b/src/keystore.h new file mode 100644 index 0000000..3cd6db4 --- /dev/null +++ b/src/keystore.h @@ -0,0 +1,186 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_KEYSTORE_H +#define BITCOIN_KEYSTORE_H + +#include "crypter.h" +#include "sync.h" +#include + +class CScript; + +/** A virtual base class for key stores */ +class CKeyStore +{ +protected: + mutable CCriticalSection cs_KeyStore; + +public: + virtual ~CKeyStore() {} + + // Add a key to the store. + 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 CKeyID &address) const =0; + virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0; + virtual void GetKeys(std::set &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 CScriptID &hash) const =0; + virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0; + + virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const + { + CKey key; + if (!GetKey(address, key)) + return false; + vchSecret = key.GetSecret(fCompressed); + return true; + } +}; + +typedef std::map > KeyMap; +typedef std::map ScriptMap; + +/** Basic key store, that keeps keys in an address->secret map */ +class CBasicKeyStore : public CKeyStore +{ +protected: + KeyMap mapKeys; + ScriptMap mapScripts; + +public: + bool AddKey(const CKey& key); + bool HaveKey(const CKeyID &address) const + { + bool result; + { + LOCK(cs_KeyStore); + result = (mapKeys.count(address) > 0); + } + return result; + } + void GetKeys(std::set &setAddress) const + { + setAddress.clear(); + { + LOCK(cs_KeyStore); + KeyMap::const_iterator mi = mapKeys.begin(); + while (mi != mapKeys.end()) + { + setAddress.insert((*mi).first); + mi++; + } + } + } + bool GetKey(const CKeyID &address, CKey &keyOut) const + { + { + LOCK(cs_KeyStore); + KeyMap::const_iterator mi = mapKeys.find(address); + if (mi != mapKeys.end()) + { + keyOut.Reset(); + keyOut.SetSecret((*mi).second.first, (*mi).second.second); + return true; + } + } + return false; + } + virtual bool AddCScript(const CScript& redeemScript); + virtual bool HaveCScript(const CScriptID &hash) const; + virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const; +}; + +typedef std::map > > CryptedKeyMap; + +/** Keystore which keeps the private keys encrypted. + * It derives from the basic key store, which is used if no encryption is active. + */ +class CCryptoKeyStore : public CBasicKeyStore +{ +private: + CryptedKeyMap mapCryptedKeys; + + CKeyingMaterial vMasterKey; + + // if fUseCrypto is true, mapKeys must be empty + // if fUseCrypto is false, vMasterKey must be empty + bool fUseCrypto; + +protected: + bool SetCrypted(); + + // will encrypt previously unencrypted keys + bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); + + bool Unlock(const CKeyingMaterial& vMasterKeyIn); + +public: + CCryptoKeyStore() : fUseCrypto(false) + { + } + + bool IsCrypted() const + { + return fUseCrypto; + } + + bool IsLocked() const + { + if (!IsCrypted()) + return false; + bool result; + { + LOCK(cs_KeyStore); + result = vMasterKey.empty(); + } + return result; + } + + bool Lock(); + + virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret); + bool AddKey(const CKey& key); + bool HaveKey(const CKeyID &address) const + { + { + LOCK(cs_KeyStore); + if (!IsCrypted()) + return CBasicKeyStore::HaveKey(address); + return mapCryptedKeys.count(address) > 0; + } + return false; + } + bool GetKey(const CKeyID &address, CKey& keyOut) const; + bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + void GetKeys(std::set &setAddress) const + { + if (!IsCrypted()) + { + CBasicKeyStore::GetKeys(setAddress); + return; + } + setAddress.clear(); + CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); + while (mi != mapCryptedKeys.end()) + { + setAddress.insert((*mi).first); + mi++; + } + } + + /* Wallet status (encrypted, locked) changed. + * Note: Called without locks held. + */ + boost::signals2::signal NotifyStatusChanged; +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..83976ef --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,3883 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "checkpoints.h" +#include "db.h" +#include "net.h" +#include "init.h" +#include "ui_interface.h" +#include +#include +#include + +using namespace std; +using namespace boost; + +// +// Global state +// + +CCriticalSection cs_setpwalletRegistered; +set setpwalletRegistered; + +CCriticalSection cs_main; + +CTxMemPool mempool; +unsigned int nTransactionsUpdated = 0; + +map mapBlockIndex; +uint256 hashGenesisBlock("0x4f46c9af6d88a14114b7dc53a37d81ba4064cda5ae2ede1213ca28fea9b86e9c"); +static CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); // CasinoCoin: starting difficulty is 1 / 2^12 +CBlockIndex* pindexGenesisBlock = NULL; +int nBestHeight = -1; +CBigNum bnBestChainWork = 0; +CBigNum bnBestInvalidWork = 0; +uint256 hashBestChain = 0; +CBlockIndex* pindexBest = NULL; +int64 nTimeBestReceived = 0; + +CMedianFilter cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have + +map mapOrphanBlocks; +multimap mapOrphanBlocksByPrev; + +map mapOrphanTransactions; +map > mapOrphanTransactionsByPrev; + +// Constant stuff for coinbase transactions we create: +CScript COINBASE_FLAGS; + +const string strMessageMagic = "CasinoCoin Signed Message:\n"; + +double dHashesPerSec; +int64 nHPSTimerStart; + +// Settings +int64 nTransactionFee = 0; +int64 nMinimumInputValue = CENT / 100; + + + +////////////////////////////////////////////////////////////////////////////// +// +// dispatching functions +// + +// These functions dispatch to one or all registered wallets + + +void RegisterWallet(CWallet* pwalletIn) +{ + { + LOCK(cs_setpwalletRegistered); + setpwalletRegistered.insert(pwalletIn); + } +} + +void UnregisterWallet(CWallet* pwalletIn) +{ + { + LOCK(cs_setpwalletRegistered); + setpwalletRegistered.erase(pwalletIn); + } +} + +// check whether the passed transaction is from us +bool static IsFromMe(CTransaction& tx) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + if (pwallet->IsFromMe(tx)) + return true; + return false; +} + +// get the wallet transaction with the given hash (if it exists) +bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + if (pwallet->GetTransaction(hashTx,wtx)) + return true; + return false; +} + +// erases transaction with the given hash from all wallets +void static EraseFromWallets(uint256 hash) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->EraseFromWallet(hash); +} + +// make sure all wallets know about the given transaction, in the given block +void SyncWithWallets(const CTransaction& tx, const CBlock* pblock, bool fUpdate) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate); +} + +// notify wallets about a new best chain +void static SetBestChain(const CBlockLocator& loc) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->SetBestChain(loc); +} + +// notify wallets about an updated transaction +void static UpdatedTransaction(const uint256& hashTx) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->UpdatedTransaction(hashTx); +} + +// dump all wallets +void static PrintWallets(const CBlock& block) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->PrintWallet(block); +} + +// notify wallets about an incoming inventory (for request counts) +void static Inventory(const uint256& hash) +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->Inventory(hash); +} + +// ask wallets to resend their transactions +void static ResendWalletTransactions() +{ + BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + pwallet->ResendWalletTransactions(); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapOrphanTransactions +// + +bool AddOrphanTx(const CDataStream& vMsg) +{ + CTransaction tx; + CDataStream(vMsg) >> tx; + uint256 hash = tx.GetHash(); + if (mapOrphanTransactions.count(hash)) + return false; + + CDataStream* pvMsg = new CDataStream(vMsg); + + // Ignore big transactions, to avoid a + // send-big-orphans memory exhaustion attack. If a peer has a legitimate + // large transaction with a missing parent then we assume + // it will rebroadcast it later, after the parent transaction(s) + // have been mined or received. + // 10,000 orphans, each of which is at most 5,000 bytes big is + // at most 500 megabytes of orphans: + if (pvMsg->size() > 5000) + { + printf("ignoring large orphan tx (size: %u, hash: %s)\n", pvMsg->size(), hash.ToString().substr(0,10).c_str()); + delete pvMsg; + return false; + } + + mapOrphanTransactions[hash] = pvMsg; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + mapOrphanTransactionsByPrev[txin.prevout.hash].insert(make_pair(hash, pvMsg)); + + printf("stored orphan tx %s (mapsz %u)\n", hash.ToString().substr(0,10).c_str(), + mapOrphanTransactions.size()); + return true; +} + +void static EraseOrphanTx(uint256 hash) +{ + if (!mapOrphanTransactions.count(hash)) + return; + const CDataStream* pvMsg = mapOrphanTransactions[hash]; + CTransaction tx; + CDataStream(*pvMsg) >> tx; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash); + if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty()) + mapOrphanTransactionsByPrev.erase(txin.prevout.hash); + } + delete pvMsg; + mapOrphanTransactions.erase(hash); +} + +unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) +{ + unsigned int nEvicted = 0; + while (mapOrphanTransactions.size() > nMaxOrphans) + { + // Evict a random orphan: + uint256 randomhash = GetRandHash(); + map::iterator it = mapOrphanTransactions.lower_bound(randomhash); + if (it == mapOrphanTransactions.end()) + it = mapOrphanTransactions.begin(); + EraseOrphanTx(it->first); + ++nEvicted; + } + return nEvicted; +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CTransaction and CTxIndex +// + +bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet) +{ + SetNull(); + if (!txdb.ReadTxIndex(prevout.hash, txindexRet)) + return false; + if (!ReadFromDisk(txindexRet.pos)) + return false; + if (prevout.n >= vout.size()) + { + SetNull(); + return false; + } + return true; +} + +bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout) +{ + CTxIndex txindex; + return ReadFromDisk(txdb, prevout, txindex); +} + +bool CTransaction::ReadFromDisk(COutPoint prevout) +{ + CTxDB txdb("r"); + CTxIndex txindex; + return ReadFromDisk(txdb, prevout, txindex); +} + +bool CTransaction::IsStandard() const +{ + if (nVersion > CTransaction::CURRENT_VERSION) + return false; + + BOOST_FOREACH(const CTxIn& txin, vin) + { + // Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG + // pay-to-script-hash, which is 3 ~80-byte signatures, 3 + // ~65-byte public keys, plus a few script ops. + if (txin.scriptSig.size() > 500) + return false; + if (!txin.scriptSig.IsPushOnly()) + return false; + } + BOOST_FOREACH(const CTxOut& txout, vout) + if (!::IsStandard(txout.scriptPubKey)) + return false; + return true; +} + +// +// Check transaction inputs, and make sure any +// pay-to-script-hash transactions are evaluating IsStandard scripts +// +// Why bother? To avoid denial-of-service attacks; an attacker +// can submit a standard HASH... OP_EQUAL transaction, +// which will get accepted into blocks. The redemption +// script can be anything; an attacker could use a very +// expensive-to-check-upon-redemption script like: +// DUP CHECKSIG DROP ... repeated 100 times... OP_1 +// +bool CTransaction::AreInputsStandard(const MapPrevTx& mapInputs) const +{ + if (IsCoinBase()) + return true; // Coinbases don't use vin normally + + for (unsigned int i = 0; i < vin.size(); i++) + { + const CTxOut& prev = GetOutputFor(vin[i], mapInputs); + + vector > vSolutions; + txnouttype whichType; + // get the scriptPubKey corresponding to this input: + const CScript& prevScript = prev.scriptPubKey; + if (!Solver(prevScript, whichType, vSolutions)) + return false; + int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions); + if (nArgsExpected < 0) + return false; + + // Transactions with extra stuff in their scriptSigs are + // non-standard. Note that this EvalScript() call will + // be quick, because if there are any operations + // beside "push data" in the scriptSig the + // IsStandard() call returns false + vector > stack; + if (!EvalScript(stack, vin[i].scriptSig, *this, i, 0)) + return false; + + if (whichType == TX_SCRIPTHASH) + { + if (stack.empty()) + return false; + CScript subscript(stack.back().begin(), stack.back().end()); + vector > vSolutions2; + txnouttype whichType2; + if (!Solver(subscript, whichType2, vSolutions2)) + return false; + if (whichType2 == TX_SCRIPTHASH) + return false; + + int tmpExpected; + tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); + if (tmpExpected < 0) + return false; + nArgsExpected += tmpExpected; + } + + if (stack.size() != (unsigned int)nArgsExpected) + return false; + } + + return true; +} + +unsigned int +CTransaction::GetLegacySigOpCount() const +{ + unsigned int nSigOps = 0; + BOOST_FOREACH(const CTxIn& txin, vin) + { + nSigOps += txin.scriptSig.GetSigOpCount(false); + } + BOOST_FOREACH(const CTxOut& txout, vout) + { + nSigOps += txout.scriptPubKey.GetSigOpCount(false); + } + return nSigOps; +} + + +int CMerkleTx::SetMerkleBranch(const CBlock* pblock) +{ + if (fClient) + { + if (hashBlock == 0) + return 0; + } + else + { + CBlock blockTmp; + if (pblock == NULL) + { + // Load the block this tx is in + CTxIndex txindex; + if (!CTxDB("r").ReadTxIndex(GetHash(), txindex)) + return 0; + if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos)) + return 0; + pblock = &blockTmp; + } + + // Update the tx's hashBlock + hashBlock = pblock->GetHash(); + + // Locate the transaction + for (nIndex = 0; nIndex < (int)pblock->vtx.size(); nIndex++) + if (pblock->vtx[nIndex] == *(CTransaction*)this) + break; + if (nIndex == (int)pblock->vtx.size()) + { + vMerkleBranch.clear(); + nIndex = -1; + printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); + return 0; + } + + // Fill in merkle branch + vMerkleBranch = pblock->GetMerkleBranch(nIndex); + } + + // Is the tx in a block that's in the main chain + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + return pindexBest->nHeight - pindex->nHeight + 1; +} + + + + + + + +bool CTransaction::CheckTransaction() const +{ + // Basic checks that don't depend on any context + if (vin.empty()) + return DoS(10, error("CTransaction::CheckTransaction() : vin empty")); + if (vout.empty()) + return DoS(10, error("CTransaction::CheckTransaction() : vout empty")); + // Size limits + if (::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) + return DoS(100, error("CTransaction::CheckTransaction() : size limits failed")); + + // Check for negative or overflow output values + int64 nValueOut = 0; + BOOST_FOREACH(const CTxOut& txout, vout) + { + if (txout.nValue < 0) + return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative")); + if (txout.nValue > MAX_MONEY) + return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high")); + nValueOut += txout.nValue; + if (!MoneyRange(nValueOut)) + return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range")); + } + + // Check for duplicate inputs + set vInOutPoints; + BOOST_FOREACH(const CTxIn& txin, vin) + { + if (vInOutPoints.count(txin.prevout)) + return false; + vInOutPoints.insert(txin.prevout); + } + + if (IsCoinBase()) + { + if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) + return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size")); + } + else + { + BOOST_FOREACH(const CTxIn& txin, vin) + if (txin.prevout.IsNull()) + return DoS(10, error("CTransaction::CheckTransaction() : prevout is null")); + } + + return true; +} + +bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, + bool* pfMissingInputs) +{ + if (pfMissingInputs) + *pfMissingInputs = false; + + if (!tx.CheckTransaction()) + return error("CTxMemPool::accept() : CheckTransaction failed"); + + // Coinbase is only valid in a block, not as a loose transaction + if (tx.IsCoinBase()) + return tx.DoS(100, error("CTxMemPool::accept() : coinbase as individual tx")); + + // To help v0.1.5 clients who would see it as a negative number + if ((int64)tx.nLockTime > std::numeric_limits::max()) + return error("CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet"); + + // Rather not work on nonstandard transactions (unless -testnet) + if (!fTestNet && !tx.IsStandard()) + return error("CTxMemPool::accept() : nonstandard transaction type"); + + // Do we already have it? + uint256 hash = tx.GetHash(); + { + LOCK(cs); + if (mapTx.count(hash)) + return false; + } + if (fCheckInputs) + if (txdb.ContainsTx(hash)) + return false; + + // Check for conflicts with in-memory transactions + CTransaction* ptxOld = NULL; + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + COutPoint outpoint = tx.vin[i].prevout; + if (mapNextTx.count(outpoint)) + { + // Disable replacement feature for now + return false; + + // Allow replacing with a newer version of the same transaction + if (i != 0) + return false; + ptxOld = mapNextTx[outpoint].ptx; + if (ptxOld->IsFinal()) + return false; + if (!tx.IsNewerThan(*ptxOld)) + return false; + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + COutPoint outpoint = tx.vin[i].prevout; + if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld) + return false; + } + break; + } + } + + if (fCheckInputs) + { + MapPrevTx mapInputs; + map mapUnused; + bool fInvalid = false; + if (!tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) + { + if (fInvalid) + return error("CTxMemPool::accept() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str()); + if (pfMissingInputs) + *pfMissingInputs = true; + return false; + } + + // Check for non-standard pay-to-script-hash in inputs + if (!tx.AreInputsStandard(mapInputs) && !fTestNet) + return error("CTxMemPool::accept() : nonstandard transaction input"); + + // Note: if you modify this code to accept non-standard transactions, then + // you should add code here to check that the transaction does a + // reasonable number of ECDSA signature verifications. + + int64 nFees = tx.GetValueIn(mapInputs)-tx.GetValueOut(); + unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + + // Don't accept it if it can't get into a block + int64 txMinFee = tx.GetMinFee(1000, true, GMF_RELAY); + if (nFees < txMinFee) + return error("CTxMemPool::accept() : not enough fees %s, %"PRI64d" < %"PRI64d, + hash.ToString().c_str(), + nFees, txMinFee); + + // Continuously rate-limit free transactions + // This mitigates 'penny-flooding' -- sending thousands of free transactions just to + // be annoying or make other's transactions take longer to confirm. + if (nFees < MIN_RELAY_TX_FEE) + { + static CCriticalSection cs; + static double dFreeCount; + static int64 nLastTime; + int64 nNow = GetTime(); + + { + LOCK(cs); + // Use an exponentially decaying ~10-minute window: + dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime)); + nLastTime = nNow; + // -limitfreerelay unit is thousand-bytes-per-minute + // At default rate it would take over a month to fill 1GB + if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(tx)) + return error("CTxMemPool::accept() : free transaction rejected by rate limiter"); + if (fDebug) + printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); + dFreeCount += nSize; + } + } + + // Check against previous transactions + // This is done last to help prevent CPU exhaustion denial-of-service attacks. + if (!tx.ConnectInputs(mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false)) + { + return error("CTxMemPool::accept() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str()); + } + } + + // Store transaction in memory + { + LOCK(cs); + if (ptxOld) + { + printf("CTxMemPool::accept() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str()); + remove(*ptxOld); + } + addUnchecked(hash, tx); + } + + ///// are we sure this is ok when loading transactions or restoring block txes + // If updated, erase old tx from wallet + if (ptxOld) + EraseFromWallets(ptxOld->GetHash()); + + printf("CTxMemPool::accept() : accepted %s (poolsz %u)\n", + hash.ToString().c_str(), + mapTx.size()); + return true; +} + +bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs) +{ + return mempool.accept(txdb, *this, fCheckInputs, pfMissingInputs); +} + +bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx) +{ + // Add to memory pool without checking anything. Don't call this directly, + // call CTxMemPool::accept to properly check the transaction first. + { + mapTx[hash] = tx; + for (unsigned int i = 0; i < tx.vin.size(); i++) + mapNextTx[tx.vin[i].prevout] = CInPoint(&mapTx[hash], i); + nTransactionsUpdated++; + } + return true; +} + + +bool CTxMemPool::remove(CTransaction &tx) +{ + // Remove transaction from memory pool + { + LOCK(cs); + uint256 hash = tx.GetHash(); + if (mapTx.count(hash)) + { + BOOST_FOREACH(const CTxIn& txin, tx.vin) + mapNextTx.erase(txin.prevout); + mapTx.erase(hash); + nTransactionsUpdated++; + } + } + return true; +} + +void CTxMemPool::queryHashes(std::vector& vtxid) +{ + vtxid.clear(); + + LOCK(cs); + vtxid.reserve(mapTx.size()); + for (map::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) + vtxid.push_back((*mi).first); +} + + + + +int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const +{ + if (hashBlock == 0 || nIndex == -1) + return 0; + + // Find the block it claims to be in + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + // Make sure the merkle branch connects to this block + if (!fMerkleVerified) + { + if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) + return 0; + fMerkleVerified = true; + } + + pindexRet = pindex; + return pindexBest->nHeight - pindex->nHeight + 1; +} + + +int CMerkleTx::GetBlocksToMaturity() const +{ + if (!IsCoinBase()) + return 0; + return max(0, (COINBASE_MATURITY) - GetDepthInMainChain()); +} + + +bool CMerkleTx::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs) +{ + if (fClient) + { + if (!IsInMainChain() && !ClientConnectInputs()) + return false; + return CTransaction::AcceptToMemoryPool(txdb, false); + } + else + { + return CTransaction::AcceptToMemoryPool(txdb, fCheckInputs); + } +} + +bool CMerkleTx::AcceptToMemoryPool() +{ + CTxDB txdb("r"); + return AcceptToMemoryPool(txdb); +} + + + +bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) +{ + + { + LOCK(mempool.cs); + // Add previous supporting transactions first + BOOST_FOREACH(CMerkleTx& tx, vtxPrev) + { + if (!tx.IsCoinBase()) + { + uint256 hash = tx.GetHash(); + if (!mempool.exists(hash) && !txdb.ContainsTx(hash)) + tx.AcceptToMemoryPool(txdb, fCheckInputs); + } + } + return AcceptToMemoryPool(txdb, fCheckInputs); + } + return false; +} + +bool CWalletTx::AcceptWalletTransaction() +{ + CTxDB txdb("r"); + return AcceptWalletTransaction(txdb); +} + +int CTxIndex::GetDepthInMainChain() const +{ + // Read block header + CBlock block; + if (!block.ReadFromDisk(pos.nFile, pos.nBlockPos, false)) + return 0; + // Find the block in the index + map::iterator mi = mapBlockIndex.find(block.GetHash()); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + return 1 + nBestHeight - pindex->nHeight; +} + +// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock +bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock) +{ + { + LOCK(cs_main); + { + LOCK(mempool.cs); + if (mempool.exists(hash)) + { + tx = mempool.lookup(hash); + return true; + } + } + CTxDB txdb("r"); + CTxIndex txindex; + if (tx.ReadFromDisk(txdb, COutPoint(hash, 0), txindex)) + { + CBlock block; + if (block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + hashBlock = block.GetHash(); + return true; + } + } + return false; +} + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CBlock and CBlockIndex +// + +bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions) +{ + if (!fReadTransactions) + { + *this = pindex->GetBlockHeader(); + return true; + } + if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions)) + return false; + if (GetHash() != pindex->GetBlockHash()) + return error("CBlock::ReadFromDisk() : GetHash() doesn't match index"); + return true; +} + +uint256 static GetOrphanRoot(const CBlock* pblock) +{ + // Work back to the first block in the orphan chain + while (mapOrphanBlocks.count(pblock->hashPrevBlock)) + pblock = mapOrphanBlocks[pblock->hashPrevBlock]; + return pblock->GetHash(); +} + +int64 static GetBlockValue(int nHeight, int64 nFees) +{ + int64 nSubsidy = 50 * COIN; + + if(nHeight < 720) + { + nSubsidy = 35 * COIN; + } + else if(nHeight < 1440) + { + nSubsidy = 5 * COIN; + } + else if(nHeight < 2160) + { + nSubsidy = 10 * COIN; + } + else if(nHeight < 2880) + { + nSubsidy = 15 * COIN; + } + else if(nHeight < 3600) + { + nSubsidy = 20 * COIN; + } + else if(nHeight < 4320) + { + nSubsidy = 25 * COIN; + } + else if(nHeight < 5040) + { + nSubsidy = 30 * COIN; + } + else if(nHeight < 5760) + { + nSubsidy = 35 * COIN; + } + else if(nHeight < 6480) + { + nSubsidy = 40 * COIN; + } + else if(nHeight < 7200) + { + nSubsidy = 45 * COIN; + } + + // Subsidy is cut in half every 3153600 blocks, which will occur approximately every 3 years + nSubsidy >>= (nHeight / 3153600); + + return nSubsidy + nFees; +} + +static const int64 nTargetTimespan = 0.25 * 24 * 60 * 60; // 0.25 day / 6 hours +static const int64 nTargetSpacing = 1 * 30; // 30 seconds +static const int64 nInterval = nTargetTimespan / nTargetSpacing; + +// +// minimum amount of work that could possibly be required nTime after +// minimum work required was nBase +// +unsigned int ComputeMinWork(unsigned int nBase, int64 nTime) +{ + // Testnet has min-difficulty blocks + // after nTargetSpacing*2 time between blocks: + if (fTestNet && nTime > nTargetSpacing*2) + return bnProofOfWorkLimit.GetCompact(); + + CBigNum bnResult; + bnResult.SetCompact(nBase); + while (nTime > 0 && bnResult < bnProofOfWorkLimit) + { + // Maximum 400% adjustment... + bnResult *= 4; + // ... in best-case exactly 4-times-normal target time + nTime -= nTargetTimespan*4; + } + if (bnResult > bnProofOfWorkLimit) + bnResult = bnProofOfWorkLimit; + return bnResult.GetCompact(); +} + +unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlock *pblock) +{ + unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact(); + + // Genesis block + if (pindexLast == NULL) + return nProofOfWorkLimit; + + // Only change once per interval + if ((pindexLast->nHeight+1) % nInterval != 0) + { + // 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) + return nProofOfWorkLimit; + else + { + // Return the last non-special-min-difficulty-rules-block + const CBlockIndex* pindex = pindexLast; + while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit) + pindex = pindex->pprev; + return pindex->nBits; + } + } + + return pindexLast->nBits; + } + + // CasinoCoin: This fixes an issue where a 51% attack can change difficulty at will. + // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz + int blockstogoback = nInterval-1; + if ((pindexLast->nHeight+1) != nInterval) + blockstogoback = nInterval; + + // Go back by what we want to be 14 days worth of blocks + const CBlockIndex* pindexFirst = pindexLast; + for (int i = 0; pindexFirst && i < blockstogoback; i++) + pindexFirst = pindexFirst->pprev; + assert(pindexFirst); + + // Limit adjustment step + int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime(); + printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan); + if (nActualTimespan < nTargetTimespan/4) + nActualTimespan = nTargetTimespan/4; + if (nActualTimespan > nTargetTimespan*4) + nActualTimespan = nTargetTimespan*4; + + // Retarget + CBigNum bnNew; + bnNew.SetCompact(pindexLast->nBits); + bnNew *= nActualTimespan; + bnNew /= nTargetTimespan; + + if (bnNew > bnProofOfWorkLimit) + bnNew = bnProofOfWorkLimit; + + /// debug print + printf("GetNextWorkRequired RETARGET\n"); + printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan); + printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str()); + printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str()); + + return bnNew.GetCompact(); +} + +bool CheckProofOfWork(uint256 hash, unsigned int nBits) +{ + CBigNum bnTarget; + bnTarget.SetCompact(nBits); + + // Check range + if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit) + return error("CheckProofOfWork() : nBits below minimum work"); + + // Check proof of work matches claimed amount + if (hash > bnTarget.getuint256()) + return error("CheckProofOfWork() : hash doesn't match nBits"); + + return true; +} + +// Return maximum amount of blocks that other nodes claim to have +int GetNumBlocksOfPeers() +{ + return std::max(cPeerBlockCounts.median(), Checkpoints::GetTotalBlocksEstimate()); +} + +bool IsInitialBlockDownload() +{ + if (pindexBest == NULL || nBestHeight < Checkpoints::GetTotalBlocksEstimate()) + return true; + static int64 nLastUpdate; + static CBlockIndex* pindexLastBest; + if (pindexBest != pindexLastBest) + { + pindexLastBest = pindexBest; + nLastUpdate = GetTime(); + } + return (GetTime() - nLastUpdate < 10 && + pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60); +} + +void static InvalidChainFound(CBlockIndex* pindexNew) +{ + if (pindexNew->bnChainWork > bnBestInvalidWork) + { + bnBestInvalidWork = pindexNew->bnChainWork; + CTxDB().WriteBestInvalidWork(bnBestInvalidWork); + uiInterface.NotifyBlocksChanged(); + } + printf("InvalidChainFound: invalid block=%s height=%d work=%s date=%s\n", + pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, + pindexNew->bnChainWork.ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S", + pindexNew->GetBlockTime()).c_str()); + printf("InvalidChainFound: current best=%s height=%d work=%s date=%s\n", + hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str(), + DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); + if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6) + printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n"); +} + +void CBlock::UpdateTime(const CBlockIndex* pindexPrev) +{ + nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + + // Updating time can change work required on testnet: + if (fTestNet) + nBits = GetNextWorkRequired(pindexPrev, this); +} + + + + + + + + + + + +bool CTransaction::DisconnectInputs(CTxDB& txdb) +{ + // Relinquish previous transactions' spent pointers + if (!IsCoinBase()) + { + BOOST_FOREACH(const CTxIn& txin, vin) + { + COutPoint prevout = txin.prevout; + + // Get prev txindex from disk + CTxIndex txindex; + if (!txdb.ReadTxIndex(prevout.hash, txindex)) + return error("DisconnectInputs() : ReadTxIndex failed"); + + if (prevout.n >= txindex.vSpent.size()) + return error("DisconnectInputs() : prevout.n out of range"); + + // Mark outpoint as not spent + txindex.vSpent[prevout.n].SetNull(); + + // Write back + if (!txdb.UpdateTxIndex(prevout.hash, txindex)) + return error("DisconnectInputs() : UpdateTxIndex failed"); + } + } + + // Remove transaction from index + // This can fail if a duplicate of this transaction was in a chain that got + // reorganized away. This is only possible if this transaction was completely + // spent, so erasing it would be a no-op anway. + txdb.EraseTxIndex(*this); + + return true; +} + + +bool CTransaction::FetchInputs(CTxDB& txdb, const map& mapTestPool, + bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid) +{ + // FetchInputs can return false either because we just haven't seen some inputs + // (in which case the transaction should be stored as an orphan) + // or because the transaction is malformed (in which case the transaction should + // be dropped). If tx is definitely invalid, fInvalid will be set to true. + fInvalid = false; + + if (IsCoinBase()) + return true; // Coinbase transactions have no inputs to fetch. + + for (unsigned int i = 0; i < vin.size(); i++) + { + COutPoint prevout = vin[i].prevout; + if (inputsRet.count(prevout.hash)) + continue; // Got it already + + // Read txindex + CTxIndex& txindex = inputsRet[prevout.hash].first; + bool fFound = true; + if ((fBlock || fMiner) && mapTestPool.count(prevout.hash)) + { + // Get txindex from current proposed changes + txindex = mapTestPool.find(prevout.hash)->second; + } + else + { + // Read txindex from txdb + fFound = txdb.ReadTxIndex(prevout.hash, txindex); + } + if (!fFound && (fBlock || fMiner)) + return fMiner ? false : error("FetchInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str()); + + // Read txPrev + CTransaction& txPrev = inputsRet[prevout.hash].second; + if (!fFound || txindex.pos == CDiskTxPos(1,1,1)) + { + // Get prev tx from single transactions in memory + { + LOCK(mempool.cs); + if (!mempool.exists(prevout.hash)) + return error("FetchInputs() : %s mempool Tx prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str()); + txPrev = mempool.lookup(prevout.hash); + } + if (!fFound) + txindex.vSpent.resize(txPrev.vout.size()); + } + else + { + // Get prev tx from disk + if (!txPrev.ReadFromDisk(txindex.pos)) + return error("FetchInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str()); + } + } + + // Make sure all prevout.n's are valid: + for (unsigned int i = 0; i < vin.size(); i++) + { + const COutPoint prevout = vin[i].prevout; + assert(inputsRet.count(prevout.hash) != 0); + const CTxIndex& txindex = inputsRet[prevout.hash].first; + const CTransaction& txPrev = inputsRet[prevout.hash].second; + if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) + { + // Revisit this if/when transaction replacement is implemented and allows + // adding inputs: + fInvalid = true; + return DoS(100, error("FetchInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str())); + } + } + + return true; +} + +const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const +{ + MapPrevTx::const_iterator mi = inputs.find(input.prevout.hash); + if (mi == inputs.end()) + throw std::runtime_error("CTransaction::GetOutputFor() : prevout.hash not found"); + + const CTransaction& txPrev = (mi->second).second; + if (input.prevout.n >= txPrev.vout.size()) + throw std::runtime_error("CTransaction::GetOutputFor() : prevout.n out of range"); + + return txPrev.vout[input.prevout.n]; +} + +int64 CTransaction::GetValueIn(const MapPrevTx& inputs) const +{ + if (IsCoinBase()) + return 0; + + int64 nResult = 0; + for (unsigned int i = 0; i < vin.size(); i++) + { + nResult += GetOutputFor(vin[i], inputs).nValue; + } + return nResult; + +} + +unsigned int CTransaction::GetP2SHSigOpCount(const MapPrevTx& inputs) const +{ + if (IsCoinBase()) + return 0; + + unsigned int nSigOps = 0; + for (unsigned int i = 0; i < vin.size(); i++) + { + const CTxOut& prevout = GetOutputFor(vin[i], inputs); + if (prevout.scriptPubKey.IsPayToScriptHash()) + nSigOps += prevout.scriptPubKey.GetSigOpCount(vin[i].scriptSig); + } + return nSigOps; +} + +bool CTransaction::ConnectInputs(MapPrevTx inputs, + map& mapTestPool, const CDiskTxPos& posThisTx, + const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash) +{ + // Take over previous transactions' spent pointers + // fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain + // fMiner is true when called from the internal casinocoin miner + // ... both are false when called from CTransaction::AcceptToMemoryPool + if (!IsCoinBase()) + { + int64 nValueIn = 0; + int64 nFees = 0; + for (unsigned int i = 0; i < vin.size(); i++) + { + COutPoint prevout = vin[i].prevout; + assert(inputs.count(prevout.hash) > 0); + CTxIndex& txindex = inputs[prevout.hash].first; + CTransaction& txPrev = inputs[prevout.hash].second; + + if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) + return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str())); + + // If prev is coinbase, check that it's matured + if (txPrev.IsCoinBase()) + for (const CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev) + if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile) + return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight); + + // Check for negative or overflow input values + nValueIn += txPrev.vout[prevout.n].nValue; + if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) + return DoS(100, error("ConnectInputs() : txin values out of range")); + + } + // The first loop above does all the inexpensive checks. + // Only if ALL inputs pass do we perform expensive ECDSA signature checks. + // Helps prevent CPU exhaustion attacks. + for (unsigned int i = 0; i < vin.size(); i++) + { + COutPoint prevout = vin[i].prevout; + assert(inputs.count(prevout.hash) > 0); + CTxIndex& txindex = inputs[prevout.hash].first; + CTransaction& txPrev = inputs[prevout.hash].second; + + // Check for conflicts (double-spend) + // This doesn't trigger the DoS code on purpose; if it did, it would make it easier + // for an attacker to attempt to split the network. + if (!txindex.vSpent[prevout.n].IsNull()) + return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str()); + + // Skip ECDSA signature verification when connecting blocks (fBlock=true) + // before the last blockchain checkpoint. This is safe because block merkle hashes are + // still computed and checked, and any change will be caught at the next checkpoint. + if (!(fBlock && (nBestHeight < Checkpoints::GetTotalBlocksEstimate()))) + { + // Verify signature + if (!VerifySignature(txPrev, *this, i, fStrictPayToScriptHash, 0)) + { + // only during transition phase for P2SH: do not invoke anti-DoS code for + // potentially old clients relaying bad P2SH transactions + if (fStrictPayToScriptHash && VerifySignature(txPrev, *this, i, false, 0)) + return error("ConnectInputs() : %s P2SH VerifySignature failed", GetHash().ToString().substr(0,10).c_str()); + + return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str())); + } + } + + // Mark outpoints as spent + txindex.vSpent[prevout.n] = posThisTx; + + // Write back + if (fBlock || fMiner) + { + mapTestPool[prevout.hash] = txindex; + } + } + + if (nValueIn < GetValueOut()) + return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str())); + + // Tally transaction fees + int64 nTxFee = nValueIn - GetValueOut(); + if (nTxFee < 0) + return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str())); + nFees += nTxFee; + if (!MoneyRange(nFees)) + return DoS(100, error("ConnectInputs() : nFees out of range")); + } + + return true; +} + + +bool CTransaction::ClientConnectInputs() +{ + if (IsCoinBase()) + return false; + + // Take over previous transactions' spent pointers + { + LOCK(mempool.cs); + int64 nValueIn = 0; + for (unsigned int i = 0; i < vin.size(); i++) + { + // Get prev tx from single transactions in memory + COutPoint prevout = vin[i].prevout; + if (!mempool.exists(prevout.hash)) + return false; + CTransaction& txPrev = mempool.lookup(prevout.hash); + + if (prevout.n >= txPrev.vout.size()) + return false; + + // Verify signature + if (!VerifySignature(txPrev, *this, i, true, 0)) + return error("ConnectInputs() : VerifySignature failed"); + + ///// this is redundant with the mempool.mapNextTx stuff, + ///// not sure which I want to get rid of + ///// this has to go away now that posNext is gone + // // Check for conflicts + // if (!txPrev.vout[prevout.n].posNext.IsNull()) + // return error("ConnectInputs() : prev tx already used"); + // + // // Flag outpoints as used + // txPrev.vout[prevout.n].posNext = posThisTx; + + nValueIn += txPrev.vout[prevout.n].nValue; + + if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) + return error("ClientConnectInputs() : txin values out of range"); + } + if (GetValueOut() > nValueIn) + return false; + } + + return true; +} + + + + +bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) +{ + // Disconnect in reverse order + for (int i = vtx.size()-1; i >= 0; i--) + if (!vtx[i].DisconnectInputs(txdb)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = 0; + if (!txdb.WriteBlockIndex(blockindexPrev)) + return error("DisconnectBlock() : WriteBlockIndex failed"); + } + + return true; +} + +bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) +{ + // Check it again in case a previous version let a bad block in + if (!CheckBlock()) + return false; + + // Do not allow blocks that contain transactions which 'overwrite' older transactions, + // unless those are already completely spent. + // If such overwrites are allowed, coinbases and transactions depending upon those + // can be duplicated to remove the ability to spend the first instance -- even after + // being sent to another address. + // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information. + // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool + // already refuses previously-known transaction id's entirely. + // This rule applies to all blocks whose timestamp is after October 1, 2012, 0:00 UTC. + int64 nBIP30SwitchTime = 1349049600; + bool fEnforceBIP30 = (pindex->nTime > nBIP30SwitchTime); + + // BIP16 didn't become active until October 1 2012 + int64 nBIP16SwitchTime = 1349049600; + bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime); + + //// issue here: it doesn't know the version + unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - 1 + GetSizeOfCompactSize(vtx.size()); + + map mapQueuedChanges; + int64 nFees = 0; + unsigned int nSigOps = 0; + BOOST_FOREACH(CTransaction& tx, vtx) + { + uint256 hashTx = tx.GetHash(); + + if (fEnforceBIP30) { + CTxIndex txindexOld; + if (txdb.ReadTxIndex(hashTx, txindexOld)) { + BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent) + if (pos.IsNull()) + return false; + } + } + + nSigOps += tx.GetLegacySigOpCount(); + if (nSigOps > MAX_BLOCK_SIGOPS) + return DoS(100, error("ConnectBlock() : too many sigops")); + + CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); + nTxPos += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); + + MapPrevTx mapInputs; + if (!tx.IsCoinBase()) + { + bool fInvalid; + if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid)) + return false; + + if (fStrictPayToScriptHash) + { + // Add in sigops done by pay-to-script-hash inputs; + // this is to prevent a "rogue miner" from creating + // an incredibly-expensive-to-validate block. + nSigOps += tx.GetP2SHSigOpCount(mapInputs); + if (nSigOps > MAX_BLOCK_SIGOPS) + return DoS(100, error("ConnectBlock() : too many sigops")); + } + + nFees += tx.GetValueIn(mapInputs)-tx.GetValueOut(); + + if (!tx.ConnectInputs(mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fStrictPayToScriptHash)) + return false; + } + + mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size()); + } + + // Write queued txindex changes + for (map::iterator mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi) + { + if (!txdb.UpdateTxIndex((*mi).first, (*mi).second)) + return error("ConnectBlock() : UpdateTxIndex failed"); + } + + if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = pindex->GetBlockHash(); + if (!txdb.WriteBlockIndex(blockindexPrev)) + return error("ConnectBlock() : WriteBlockIndex failed"); + } + + // Watch for transactions paying to me + BOOST_FOREACH(CTransaction& tx, vtx) + SyncWithWallets(tx, this, true); + + return true; +} + +bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) +{ + printf("REORGANIZE\n"); + + // Find the fork + CBlockIndex* pfork = pindexBest; + CBlockIndex* plonger = pindexNew; + while (pfork != plonger) + { + while (plonger->nHeight > pfork->nHeight) + if (!(plonger = plonger->pprev)) + return error("Reorganize() : plonger->pprev is null"); + if (pfork == plonger) + break; + if (!(pfork = pfork->pprev)) + return error("Reorganize() : pfork->pprev is null"); + } + + // List of what to disconnect + vector vDisconnect; + for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev) + vDisconnect.push_back(pindex); + + // List of what to connect + vector vConnect; + for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev) + vConnect.push_back(pindex); + reverse(vConnect.begin(), vConnect.end()); + + printf("REORGANIZE: Disconnect %i blocks; %s..%s\n", vDisconnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexBest->GetBlockHash().ToString().substr(0,20).c_str()); + printf("REORGANIZE: Connect %i blocks; %s..%s\n", vConnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->GetBlockHash().ToString().substr(0,20).c_str()); + + // Disconnect shorter branch + vector vResurrect; + BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) + { + CBlock block; + if (!block.ReadFromDisk(pindex)) + return error("Reorganize() : ReadFromDisk for disconnect failed"); + if (!block.DisconnectBlock(txdb, pindex)) + return error("Reorganize() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str()); + + // Queue memory transactions to resurrect + BOOST_FOREACH(const CTransaction& tx, block.vtx) + if (!tx.IsCoinBase()) + vResurrect.push_back(tx); + } + + // Connect longer branch + vector vDelete; + for (unsigned int i = 0; i < vConnect.size(); i++) + { + CBlockIndex* pindex = vConnect[i]; + CBlock block; + if (!block.ReadFromDisk(pindex)) + return error("Reorganize() : ReadFromDisk for connect failed"); + if (!block.ConnectBlock(txdb, pindex)) + { + // Invalid block + return error("Reorganize() : ConnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str()); + } + + // Queue memory transactions to delete + BOOST_FOREACH(const CTransaction& tx, block.vtx) + vDelete.push_back(tx); + } + if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) + return error("Reorganize() : WriteHashBestChain failed"); + + // Make sure it's successfully written to disk before changing memory structure + if (!txdb.TxnCommit()) + return error("Reorganize() : TxnCommit failed"); + + // Disconnect shorter branch + BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) + if (pindex->pprev) + pindex->pprev->pnext = NULL; + + // Connect longer branch + BOOST_FOREACH(CBlockIndex* pindex, vConnect) + if (pindex->pprev) + pindex->pprev->pnext = pindex; + + // Resurrect memory transactions that were in the disconnected branch + BOOST_FOREACH(CTransaction& tx, vResurrect) + tx.AcceptToMemoryPool(txdb, false); + + // Delete redundant memory transactions that are in the connected branch + BOOST_FOREACH(CTransaction& tx, vDelete) + mempool.remove(tx); + + printf("REORGANIZE: done\n"); + + return true; +} + + +// Called from inside SetBestChain: attaches a block to the new best chain being built +bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew) +{ + uint256 hash = GetHash(); + + // Adding to current best branch + if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash)) + { + txdb.TxnAbort(); + InvalidChainFound(pindexNew); + return false; + } + if (!txdb.TxnCommit()) + return error("SetBestChain() : TxnCommit failed"); + + // Add to current best branch + pindexNew->pprev->pnext = pindexNew; + + // Delete redundant memory transactions + BOOST_FOREACH(CTransaction& tx, vtx) + mempool.remove(tx); + + return true; +} + +bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) +{ + uint256 hash = GetHash(); + + if (!txdb.TxnBegin()) + return error("SetBestChain() : TxnBegin failed"); + + if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) + { + txdb.WriteHashBestChain(hash); + if (!txdb.TxnCommit()) + return error("SetBestChain() : TxnCommit failed"); + pindexGenesisBlock = pindexNew; + } + else if (hashPrevBlock == hashBestChain) + { + if (!SetBestChainInner(txdb, pindexNew)) + return error("SetBestChain() : SetBestChainInner failed"); + } + else + { + // the first block in the new chain that will cause it to become the new best chain + CBlockIndex *pindexIntermediate = pindexNew; + + // list of blocks that need to be connected afterwards + std::vector vpindexSecondary; + + // Reorganize is costly in terms of db load, as it works in a single db transaction. + // Try to limit how much needs to be done inside + while (pindexIntermediate->pprev && pindexIntermediate->pprev->bnChainWork > pindexBest->bnChainWork) + { + vpindexSecondary.push_back(pindexIntermediate); + pindexIntermediate = pindexIntermediate->pprev; + } + + if (!vpindexSecondary.empty()) + printf("Postponing %i reconnects\n", vpindexSecondary.size()); + + // Switch to new best branch + if (!Reorganize(txdb, pindexIntermediate)) + { + txdb.TxnAbort(); + InvalidChainFound(pindexNew); + return error("SetBestChain() : Reorganize failed"); + } + + // Connect futher blocks + BOOST_REVERSE_FOREACH(CBlockIndex *pindex, vpindexSecondary) + { + CBlock block; + if (!block.ReadFromDisk(pindex)) + { + printf("SetBestChain() : ReadFromDisk failed\n"); + break; + } + if (!txdb.TxnBegin()) { + printf("SetBestChain() : TxnBegin 2 failed\n"); + break; + } + // errors now are not fatal, we still did a reorganisation to a new chain in a valid way + if (!block.SetBestChainInner(txdb, pindex)) + break; + } + } + + // Update best block in wallet (so we can detect restored wallets) + bool fIsInitialDownload = IsInitialBlockDownload(); + if (!fIsInitialDownload) + { + const CBlockLocator locator(pindexNew); + ::SetBestChain(locator); + } + + // New best block + hashBestChain = hash; + pindexBest = pindexNew; + nBestHeight = pindexBest->nHeight; + bnBestChainWork = pindexNew->bnChainWork; + nTimeBestReceived = GetTime(); + nTransactionsUpdated++; + printf("SetBestChain: new best=%s height=%d work=%s date=%s\n", + hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str(), + DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); + + // Check the version of the last 100 blocks to see if we need to upgrade: + if (!fIsInitialDownload) + { + int nUpgraded = 0; + const CBlockIndex* pindex = pindexBest; + for (int i = 0; i < 100 && pindex != NULL; i++) + { + if (pindex->nVersion > CBlock::CURRENT_VERSION) + ++nUpgraded; + pindex = pindex->pprev; + } + if (nUpgraded > 0) + printf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, CBlock::CURRENT_VERSION); + // if (nUpgraded > 100/2) + // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: + // strMiscWarning = _("Warning: this version is obsolete, upgrade required"); + } + + std::string strCmd = GetArg("-blocknotify", ""); + + if (!fIsInitialDownload && !strCmd.empty()) + { + boost::replace_all(strCmd, "%s", hashBestChain.GetHex()); + boost::thread t(runCommand, strCmd); // thread runs free + } + + return true; +} + + +bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str()); + + // Construct new block index object + CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this); + if (!pindexNew) + return error("AddToBlockIndex() : new CBlockIndex failed"); + map::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + map::iterator miPrev = mapBlockIndex.find(hashPrevBlock); + if (miPrev != mapBlockIndex.end()) + { + pindexNew->pprev = (*miPrev).second; + pindexNew->nHeight = pindexNew->pprev->nHeight + 1; + } + pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork(); + + CTxDB txdb; + if (!txdb.TxnBegin()) + return false; + txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); + if (!txdb.TxnCommit()) + return false; + + // New best + if (pindexNew->bnChainWork > bnBestChainWork) + if (!SetBestChain(txdb, pindexNew)) + return false; + + txdb.Close(); + + if (pindexNew == pindexBest) + { + // Notify UI to display prev block's coinbase if it was ours + static uint256 hashPrevBestCoinBase; + UpdatedTransaction(hashPrevBestCoinBase); + hashPrevBestCoinBase = vtx[0].GetHash(); + } + + uiInterface.NotifyBlocksChanged(); + return true; +} + + + + +bool CBlock::CheckBlock() const +{ + // These are checks that are independent of context + // that can be verified before saving an orphan block. + + // Size limits + if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) + return DoS(100, error("CheckBlock() : size limits failed")); + + // Check proof of work matches claimed amount + if (!CheckProofOfWork(GetPoWHash(), nBits)) + return DoS(50, error("CheckBlock() : proof of work failed")); + + // Check timestamp + if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) + return error("CheckBlock() : block timestamp too far in the future"); + + // First transaction must be coinbase, the rest must not be + if (vtx.empty() || !vtx[0].IsCoinBase()) + return DoS(100, error("CheckBlock() : first tx is not coinbase")); + for (unsigned int i = 1; i < vtx.size(); i++) + if (vtx[i].IsCoinBase()) + return DoS(100, error("CheckBlock() : more than one coinbase")); + + // Check transactions + BOOST_FOREACH(const CTransaction& tx, vtx) + if (!tx.CheckTransaction()) + return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed")); + + // Check for duplicate txids. This is caught by ConnectInputs(), + // but catching it earlier avoids a potential DoS attack: + set uniqueTx; + BOOST_FOREACH(const CTransaction& tx, vtx) + { + uniqueTx.insert(tx.GetHash()); + } + if (uniqueTx.size() != vtx.size()) + return DoS(100, error("CheckBlock() : duplicate transaction")); + + unsigned int nSigOps = 0; + BOOST_FOREACH(const CTransaction& tx, vtx) + { + nSigOps += tx.GetLegacySigOpCount(); + } + if (nSigOps > MAX_BLOCK_SIGOPS) + return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount")); + + // Check merkleroot + if (hashMerkleRoot != BuildMerkleTree()) + return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch")); + + return true; +} + +bool CBlock::AcceptBlock() +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AcceptBlock() : block already in mapBlockIndex"); + + // Get prev block index + map::iterator mi = mapBlockIndex.find(hashPrevBlock); + if (mi == mapBlockIndex.end()) + return DoS(10, error("AcceptBlock() : prev block not found")); + CBlockIndex* pindexPrev = (*mi).second; + int nHeight = pindexPrev->nHeight+1; + + // Check proof of work + if (nBits != GetNextWorkRequired(pindexPrev, this)) + return DoS(100, error("AcceptBlock() : incorrect proof of work")); + + // Check timestamp against prev + if (GetBlockTime() <= pindexPrev->GetMedianTimePast()) + return error("AcceptBlock() : block's timestamp is too early"); + + // Check that all transactions are finalized + BOOST_FOREACH(const CTransaction& tx, vtx) + if (!tx.IsFinal(nHeight, GetBlockTime())) + return DoS(10, error("AcceptBlock() : contains a non-final transaction")); + + // Check that the block chain matches the known block chain up to a checkpoint + if (!Checkpoints::CheckBlock(nHeight, hash)) + return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight)); + + // Write block to history file + if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION))) + return error("AcceptBlock() : out of disk space"); + unsigned int nFile = -1; + unsigned int nBlockPos = 0; + if (!WriteToDisk(nFile, nBlockPos)) + return error("AcceptBlock() : WriteToDisk failed"); + if (!AddToBlockIndex(nFile, nBlockPos)) + return error("AcceptBlock() : AddToBlockIndex failed"); + + // Relay inventory, but don't relay old inventory during initial block download + int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(); + if (hashBestChain == hash) + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) + pnode->PushInventory(CInv(MSG_BLOCK, hash)); + } + + return true; +} + +bool ProcessBlock(CNode* pfrom, CBlock* pblock) +{ + // Check for duplicate + uint256 hash = pblock->GetHash(); + if (mapBlockIndex.count(hash)) + return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str()); + if (mapOrphanBlocks.count(hash)) + return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str()); + + // Preliminary checks + if (!pblock->CheckBlock()) + return error("ProcessBlock() : CheckBlock FAILED"); + + CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); + if (pcheckpoint && pblock->hashPrevBlock != hashBestChain) + { + // Extra checks to prevent "fill up memory by spamming with bogus blocks" + int64 deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime; + if (deltaTime < 0) + { + if (pfrom) + pfrom->Misbehaving(100); + return error("ProcessBlock() : block with timestamp before last checkpoint"); + } + CBigNum bnNewBlock; + bnNewBlock.SetCompact(pblock->nBits); + CBigNum bnRequired; + bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime)); + if (bnNewBlock > bnRequired) + { + if (pfrom) + pfrom->Misbehaving(100); + return error("ProcessBlock() : block with too little proof-of-work"); + } + } + + + // If don't already have its previous block, shunt it off to holding area until we get it + if (!mapBlockIndex.count(pblock->hashPrevBlock)) + { + printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str()); + CBlock* pblock2 = new CBlock(*pblock); + mapOrphanBlocks.insert(make_pair(hash, pblock2)); + mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2)); + + // Ask this guy to fill in what we're missing + if (pfrom) + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2)); + return true; + } + + // Store to disk + if (!pblock->AcceptBlock()) + return error("ProcessBlock() : AcceptBlock FAILED"); + + // Recursively process any orphan blocks that depended on this one + vector vWorkQueue; + vWorkQueue.push_back(hash); + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (multimap::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev); + mi != mapOrphanBlocksByPrev.upper_bound(hashPrev); + ++mi) + { + CBlock* pblockOrphan = (*mi).second; + if (pblockOrphan->AcceptBlock()) + vWorkQueue.push_back(pblockOrphan->GetHash()); + mapOrphanBlocks.erase(pblockOrphan->GetHash()); + delete pblockOrphan; + } + mapOrphanBlocksByPrev.erase(hashPrev); + } + + printf("ProcessBlock: ACCEPTED\n"); + return true; +} + + + + + + + + +bool CheckDiskSpace(uint64 nAdditionalBytes) +{ + uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; + + // Check for nMinDiskSpace bytes (currently 50MB) + if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) + { + fShutdown = true; + string strMessage = _("Warning: Disk space is low"); + strMiscWarning = strMessage; + printf("*** %s\n", strMessage.c_str()); + uiInterface.ThreadSafeMessageBox(strMessage, "CasinoCoin", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + StartShutdown(); + return false; + } + return true; +} + +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode) +{ + if ((nFile < 1) || (nFile == (unsigned int) -1)) + return NULL; + FILE* file = fopen((GetDataDir() / strprintf("blk%04d.dat", nFile)).string().c_str(), pszMode); + if (!file) + return NULL; + if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) + { + if (fseek(file, nBlockPos, SEEK_SET) != 0) + { + fclose(file); + return NULL; + } + } + return file; +} + +static unsigned int nCurrentBlockFile = 1; + +FILE* AppendBlockFile(unsigned int& nFileRet) +{ + nFileRet = 0; + loop + { + FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab"); + if (!file) + return NULL; + if (fseek(file, 0, SEEK_END) != 0) + return NULL; + // FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB + if (ftell(file) < 0x7F000000 - MAX_SIZE) + { + nFileRet = nCurrentBlockFile; + return file; + } + fclose(file); + nCurrentBlockFile++; + } +} + +bool LoadBlockIndex(bool fAllowNew) +{ + if (fTestNet) + { + pchMessageStart[0] = 0xfc; + pchMessageStart[1] = 0xc1; + pchMessageStart[2] = 0xb7; + pchMessageStart[3] = 0xdc; + hashGenesisBlock = uint256("0xe5d98005cd7744147b4c472fffc04a81bdc04756ddbcb49e6675f01b1585c1d3"); + } + + // + // Load block index + // + CTxDB txdb("cr"); + if (!txdb.LoadBlockIndex()) + return false; + txdb.Close(); + + // + // Init with genesis block + // + if (mapBlockIndex.empty()) + { + if (!fAllowNew) + return false; + + // Genesis Block: + // block.nTime = 1372621620 + // block.nNonce = 1022795 + // block.GetHash = e5d98005cd7744147b4c472fffc04a81bdc04756ddbcb49e6675f01b1585c1d3 + // CBlock(hash=e5d98005cd7744147b4c, PoW=00000ef9c997ddd28652, ver=1, hashPrevBlock=00000000000000000000, hashMerkleRoot=2ae9af367b, nTime=1372621620, nBits=1e0ffff0, nNonce=1022795, vtx=1) + // CTransaction(hash=2ae9af367b, ver=1, vin.size=1, vout.size=1, nLockTime=0) + // CTxIn(COutPoint(0000000000, -1), coinbase 04ffff001d0104474e592054696d65732032392f4a756e2f323031332045637561646f72204c6561646572205361797320426964656e2043616c6c65642048696d2041626f757420536e6f7764656e) + // CTxOut(error) + // vMerkleTree: 2ae9af367b + + // Genesis block + const char* pszTimestamp = "NY Times 2/July/2013 What the N.S.A. Knows About You"; + CTransaction txNew; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = 0; + txNew.vout[0].scriptPubKey = CScript() << 0x0 << OP_CHECKSIG; + CBlock block; + block.vtx.push_back(txNew); + block.hashPrevBlock = 0; + block.hashMerkleRoot = block.BuildMerkleTree(); + block.nVersion = 1; + block.nTime = 1372838150; + block.nBits = 0x1e0ffff0; + block.nNonce = 16762; + + if (fTestNet) + { + block.nTime = 1372621620; + block.nNonce = 1022795; + } + + //// debug print + printf("%s\n", block.GetHash().ToString().c_str()); + printf("%s\n", hashGenesisBlock.ToString().c_str()); + printf("%s\n", block.hashMerkleRoot.ToString().c_str()); + assert(block.hashMerkleRoot == uint256("0x73d304deca65f150913c0f87305dec7aa3913919889e483aa04bda87133023e6")); + + // If genesis block hash does not match, then generate new genesis hash. + if (false && block.GetHash() != hashGenesisBlock) + { + printf("Searching for genesis block...\n"); + // This will figure out a valid hash and Nonce if you're + // creating a different genesis block: + uint256 hashTarget = CBigNum().SetCompact(block.nBits).getuint256(); + uint256 thash; + char scratchpad[SCRYPT_SCRATCHPAD_SIZE]; + + loop + { + scrypt_1024_1_1_256_sp(BEGIN(block.nVersion), BEGIN(thash), scratchpad); + if (thash <= hashTarget) + break; + if ((block.nNonce & 0xFFF) == 0) + { + printf("nonce %08X: hash = %s (target = %s)\n", block.nNonce, thash.ToString().c_str(), hashTarget.ToString().c_str()); + } + ++block.nNonce; + if (block.nNonce == 0) + { + printf("NONCE WRAPPED, incrementing time\n"); + ++block.nTime; + } + } + printf("block.nTime = %u \n", block.nTime); + printf("block.nNonce = %u \n", block.nNonce); + printf("block.GetHash = %s\n", block.GetHash().ToString().c_str()); + } + + block.print(); + assert(block.GetHash() == hashGenesisBlock); + + // Start new block file + unsigned int nFile; + unsigned int nBlockPos; + if (!block.WriteToDisk(nFile, nBlockPos)) + return error("LoadBlockIndex() : writing genesis block to disk failed"); + if (!block.AddToBlockIndex(nFile, nBlockPos)) + return error("LoadBlockIndex() : genesis block not accepted"); + } + + return true; +} + + + +void PrintBlockTree() +{ + // precompute tree structure + map > mapNext; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + CBlockIndex* pindex = (*mi).second; + mapNext[pindex->pprev].push_back(pindex); + // test + //while (rand() % 3 == 0) + // mapNext[pindex->pprev].push_back(pindex); + } + + vector > vStack; + vStack.push_back(make_pair(0, pindexGenesisBlock)); + + int nPrevCol = 0; + while (!vStack.empty()) + { + int nCol = vStack.back().first; + CBlockIndex* pindex = vStack.back().second; + vStack.pop_back(); + + // print split or gap + if (nCol > nPrevCol) + { + for (int i = 0; i < nCol-1; i++) + printf("| "); + printf("|\\\n"); + } + else if (nCol < nPrevCol) + { + for (int i = 0; i < nCol; i++) + printf("| "); + printf("|\n"); + } + nPrevCol = nCol; + + // print columns + for (int i = 0; i < nCol; i++) + printf("| "); + + // print item + CBlock block; + block.ReadFromDisk(pindex); + printf("%d (%u,%u) %s %s tx %d", + pindex->nHeight, + pindex->nFile, + pindex->nBlockPos, + block.GetHash().ToString().substr(0,20).c_str(), + DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(), + block.vtx.size()); + + PrintWallets(block); + + // put the main timechain first + vector& vNext = mapNext[pindex]; + for (unsigned int i = 0; i < vNext.size(); i++) + { + if (vNext[i]->pnext) + { + swap(vNext[0], vNext[i]); + break; + } + } + + // iterate children + for (unsigned int i = 0; i < vNext.size(); i++) + vStack.push_back(make_pair(nCol+i, vNext[i])); + } +} + +bool LoadExternalBlockFile(FILE* fileIn) +{ + int nLoaded = 0; + { + LOCK(cs_main); + try { + CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION); + unsigned int nPos = 0; + while (nPos != (unsigned int)-1 && blkdat.good() && !fRequestShutdown) + { + unsigned char pchData[65536]; + do { + fseek(blkdat, nPos, SEEK_SET); + int nRead = fread(pchData, 1, sizeof(pchData), blkdat); + if (nRead <= 8) + { + nPos = (unsigned int)-1; + break; + } + void* nFind = memchr(pchData, pchMessageStart[0], nRead+1-sizeof(pchMessageStart)); + if (nFind) + { + if (memcmp(nFind, pchMessageStart, sizeof(pchMessageStart))==0) + { + nPos += ((unsigned char*)nFind - pchData) + sizeof(pchMessageStart); + break; + } + nPos += ((unsigned char*)nFind - pchData) + 1; + } + else + nPos += sizeof(pchData) - sizeof(pchMessageStart) + 1; + } while(!fRequestShutdown); + if (nPos == (unsigned int)-1) + break; + fseek(blkdat, nPos, SEEK_SET); + unsigned int nSize; + blkdat >> nSize; + if (nSize > 0 && nSize <= MAX_BLOCK_SIZE) + { + CBlock block; + blkdat >> block; + if (ProcessBlock(NULL,&block)) + { + nLoaded++; + nPos += 4 + nSize; + } + } + } + } + catch (std::exception &e) { + printf("%s() : Deserialize or I/O error caught during load\n", + __PRETTY_FUNCTION__); + } + } + printf("Loaded %i blocks from external file\n", nLoaded); + return nLoaded > 0; +} + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CAlert +// + +map mapAlerts; +CCriticalSection cs_mapAlerts; + +string GetWarnings(string strFor) +{ + int nPriority = 0; + string strStatusBar; + string strRPC; + if (GetBoolArg("-testsafemode")) + strRPC = "test"; + + // Misc warnings like out of disk space and clock is wrong + if (strMiscWarning != "") + { + nPriority = 1000; + strStatusBar = strMiscWarning; + } + + // Longer invalid proof-of-work chain + if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6) + { + nPriority = 2000; + strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade."; + } + + // Alerts + { + LOCK(cs_mapAlerts); + BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + { + const CAlert& alert = item.second; + if (alert.AppliesToMe() && alert.nPriority > nPriority) + { + nPriority = alert.nPriority; + strStatusBar = alert.strStatusBar; + } + } + } + + if (strFor == "statusbar") + return strStatusBar; + else if (strFor == "rpc") + return strRPC; + assert(!"GetWarnings() : invalid parameter"); + return "error"; +} + +CAlert CAlert::getAlertByHash(const uint256 &hash) +{ + CAlert retval; + { + LOCK(cs_mapAlerts); + map::iterator mi = mapAlerts.find(hash); + if(mi != mapAlerts.end()) + retval = mi->second; + } + return retval; +} + +bool CAlert::ProcessAlert() +{ + if (!CheckSignature()) + return false; + if (!IsInEffect()) + return false; + + { + LOCK(cs_mapAlerts); + // Cancel previous alerts + for (map::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();) + { + const CAlert& alert = (*mi).second; + if (Cancels(alert)) + { + printf("cancelling alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mapAlerts.erase(mi++); + } + else if (!alert.IsInEffect()) + { + printf("expiring alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mapAlerts.erase(mi++); + } + else + mi++; + } + + // Check if this alert has been cancelled + BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + { + const CAlert& alert = item.second; + if (alert.Cancels(*this)) + { + printf("alert already cancelled by %d\n", alert.nID); + return false; + } + } + + // Add to mapAlerts + mapAlerts.insert(make_pair(GetHash(), *this)); + // Notify UI if it applies to me + if(AppliesToMe()) + uiInterface.NotifyAlertChanged(GetHash(), CT_NEW); + } + + printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe()); + return true; +} + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Messages +// + + +bool static AlreadyHave(CTxDB& txdb, const CInv& inv) +{ + switch (inv.type) + { + case MSG_TX: + { + bool txInMap = false; + { + LOCK(mempool.cs); + txInMap = (mempool.exists(inv.hash)); + } + return txInMap || + mapOrphanTransactions.count(inv.hash) || + txdb.ContainsTx(inv.hash); + } + + case MSG_BLOCK: + return mapBlockIndex.count(inv.hash) || + mapOrphanBlocks.count(inv.hash); + } + // Don't know what it is, just say we already got one + return true; +} + + + + +// The message start string is designed to be unlikely to occur in normal data. +// The characters are rarely used upper ascii, not valid as UTF-8, and produce +// a large 4-byte int at any alignment. +unsigned char pchMessageStart[4] = { 0xfa, 0xc3, 0xb6, 0xda }; + + +bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) +{ + static map mapReuseKey; + RandAddSeedPerfmon(); + if (fDebug) + printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) + { + printf("dropmessagestest DROPPING RECV MESSAGE\n"); + return true; + } + + + + + + if (strCommand == "version") + { + // Each connection can only send one version message + if (pfrom->nVersion != 0) + { + pfrom->Misbehaving(1); + return false; + } + + int64 nTime; + CAddress addrMe; + CAddress addrFrom; + uint64 nNonce = 1; + vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + if (pfrom->nVersion < MIN_PROTO_VERSION) + { + // Since February 20, 2012, the protocol is initiated at version 209, + // and earlier versions are no longer supported + printf("partner %s using obsolete version %i; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); + pfrom->fDisconnect = true; + return false; + } + + if (pfrom->nVersion == 10300) + pfrom->nVersion = 300; + if (!vRecv.empty()) + vRecv >> addrFrom >> nNonce; + if (!vRecv.empty()) + vRecv >> pfrom->strSubVer; + if (!vRecv.empty()) + vRecv >> pfrom->nStartingHeight; + + if (pfrom->fInbound && addrMe.IsRoutable()) + { + pfrom->addrLocal = addrMe; + SeenLocal(addrMe); + } + + // Disconnect if we connected to ourself + if (nNonce == nLocalHostNonce && nNonce > 1) + { + printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str()); + pfrom->fDisconnect = true; + return true; + } + + // Be shy and don't send version until we hear + if (pfrom->fInbound) + pfrom->PushVersion(); + + pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); + + AddTimeData(pfrom->addr, nTime); + + // Change version + pfrom->PushMessage("verack"); + pfrom->vSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); + + if (!pfrom->fInbound) + { + // Advertise our address + if (!fNoListen && !IsInitialBlockDownload()) + { + CAddress addr = GetLocalAddress(&pfrom->addr); + if (addr.IsRoutable()) + pfrom->PushAddress(addr); + } + + // Get recent addresses + if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) + { + pfrom->PushMessage("getaddr"); + pfrom->fGetAddr = true; + } + addrman.Good(pfrom->addr); + } else { + if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom) + { + addrman.Add(addrFrom, addrFrom); + addrman.Good(addrFrom); + } + } + + // Ask the first connected node for block updates + static int nAskedForBlocks = 0; + if (!pfrom->fClient && !pfrom->fOneShot && + (pfrom->nVersion < NOBLKS_VERSION_START || + pfrom->nVersion >= NOBLKS_VERSION_END) && + (nAskedForBlocks < 1 || vNodes.size() <= 1)) + { + nAskedForBlocks++; + pfrom->PushGetBlocks(pindexBest, uint256(0)); + } + + // Relay alerts + { + LOCK(cs_mapAlerts); + BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + item.second.RelayTo(pfrom); + } + + pfrom->fSuccessfullyConnected = true; + + printf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str()); + + cPeerBlockCounts.input(pfrom->nStartingHeight); + } + + + else if (pfrom->nVersion == 0) + { + // Must have a version message before anything else + pfrom->Misbehaving(1); + return false; + } + + + else if (strCommand == "verack") + { + pfrom->vRecv.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); + } + + + else if (strCommand == "addr") + { + vector vAddr; + vRecv >> vAddr; + + // Don't want addr from older versions unless seeding + if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000) + return true; + if (vAddr.size() > 1000) + { + pfrom->Misbehaving(20); + return error("message addr size() = %d", vAddr.size()); + } + + // Store the new addresses + vector vAddrOk; + int64 nNow = GetAdjustedTime(); + int64 nSince = nNow - 10 * 60; + BOOST_FOREACH(CAddress& addr, vAddr) + { + if (fShutdown) + return true; + if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) + addr.nTime = nNow - 5 * 24 * 60 * 60; + pfrom->AddAddressKnown(addr); + bool fReachable = IsReachable(addr); + if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) + { + // Relay to a limited number of other nodes + { + LOCK(cs_vNodes); + // Use deterministic randomness to send to the same nodes for 24 hours + // at a time so the setAddrKnowns of the chosen nodes prevent repeats + static uint256 hashSalt; + if (hashSalt == 0) + hashSalt = GetRandHash(); + uint64 hashAddr = addr.GetHash(); + uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)); + hashRand = Hash(BEGIN(hashRand), END(hashRand)); + multimap mapMix; + BOOST_FOREACH(CNode* pnode, vNodes) + { + if (pnode->nVersion < CADDR_TIME_VERSION) + continue; + unsigned int nPointer; + memcpy(&nPointer, &pnode, sizeof(nPointer)); + uint256 hashKey = hashRand ^ nPointer; + hashKey = Hash(BEGIN(hashKey), END(hashKey)); + mapMix.insert(make_pair(hashKey, pnode)); + } + int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s) + for (multimap::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) + ((*mi).second)->PushAddress(addr); + } + } + // Do not store addresses outside our network + if (fReachable) + vAddrOk.push_back(addr); + } + addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60); + if (vAddr.size() < 1000) + pfrom->fGetAddr = false; + if (pfrom->fOneShot) + pfrom->fDisconnect = true; + } + + + else if (strCommand == "inv") + { + vector vInv; + vRecv >> vInv; + if (vInv.size() > 50000) + { + pfrom->Misbehaving(20); + return error("message inv size() = %d", vInv.size()); + } + + // find last block in inv vector + unsigned int nLastBlock = (unsigned int)(-1); + for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { + if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) { + nLastBlock = vInv.size() - 1 - nInv; + break; + } + } + CTxDB txdb("r"); + for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) + { + const CInv &inv = vInv[nInv]; + + if (fShutdown) + return true; + pfrom->AddInventoryKnown(inv); + + bool fAlreadyHave = AlreadyHave(txdb, inv); + if (fDebug) + printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); + + if (!fAlreadyHave) + pfrom->AskFor(inv); + else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) { + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); + } else if (nInv == nLastBlock) { + // In case we are on a very long side-chain, it is possible that we already have + // the last block in an inv bundle sent in response to getblocks. Try to detect + // this situation and push another getblocks to continue. + std::vector vGetData(1,inv); + pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0)); + if (fDebug) + printf("force request: %s\n", inv.ToString().c_str()); + } + + // Track requests for our stuff + Inventory(inv.hash); + } + } + + + else if (strCommand == "getdata") + { + vector vInv; + vRecv >> vInv; + if (vInv.size() > 50000) + { + pfrom->Misbehaving(20); + return error("message getdata size() = %d", vInv.size()); + } + + if (fDebugNet || (vInv.size() != 1)) + printf("received getdata (%d invsz)\n", vInv.size()); + + BOOST_FOREACH(const CInv& inv, vInv) + { + if (fShutdown) + return true; + if (fDebugNet || (vInv.size() == 1)) + printf("received getdata for: %s\n", inv.ToString().c_str()); + + if (inv.type == MSG_BLOCK) + { + // Send block from disk + map::iterator mi = mapBlockIndex.find(inv.hash); + if (mi != mapBlockIndex.end()) + { + CBlock block; + block.ReadFromDisk((*mi).second); + pfrom->PushMessage("block", block); + + // Trigger them to send a getblocks request for the next batch of inventory + if (inv.hash == pfrom->hashContinue) + { + // Bypass PushInventory, this must send even if redundant, + // and we want it right after the last block so they don't + // wait for other stuff first. + vector vInv; + vInv.push_back(CInv(MSG_BLOCK, hashBestChain)); + pfrom->PushMessage("inv", vInv); + pfrom->hashContinue = 0; + } + } + } + else if (inv.IsKnownType()) + { + // Send stream from relay memory + { + LOCK(cs_mapRelay); + map::iterator mi = mapRelay.find(inv); + if (mi != mapRelay.end()) + pfrom->PushMessage(inv.GetCommand(), (*mi).second); + } + } + + // Track requests for our stuff + Inventory(inv.hash); + } + } + + + else if (strCommand == "getblocks") + { + CBlockLocator locator; + uint256 hashStop; + vRecv >> locator >> hashStop; + + // Find the last block the caller has in the main chain + CBlockIndex* pindex = locator.GetBlockIndex(); + + // Send the rest of the chain + if (pindex) + pindex = pindex->pnext; + int nLimit = 500; + printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit); + for (; pindex; pindex = pindex->pnext) + { + if (pindex->GetBlockHash() == hashStop) + { + printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str()); + break; + } + pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); + if (--nLimit <= 0) + { + // When this block is requested, we'll send an inv that'll make them + // getblocks the next batch of inventory. + printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str()); + pfrom->hashContinue = pindex->GetBlockHash(); + break; + } + } + } + + + else if (strCommand == "getheaders") + { + CBlockLocator locator; + uint256 hashStop; + vRecv >> locator >> hashStop; + + CBlockIndex* pindex = NULL; + if (locator.IsNull()) + { + // If locator is null, return the hashStop block + map::iterator mi = mapBlockIndex.find(hashStop); + if (mi == mapBlockIndex.end()) + return true; + pindex = (*mi).second; + } + else + { + // Find the last block the caller has in the main chain + pindex = locator.GetBlockIndex(); + if (pindex) + pindex = pindex->pnext; + } + + vector vHeaders; + int nLimit = 2000; + printf("getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str()); + for (; pindex; pindex = pindex->pnext) + { + vHeaders.push_back(pindex->GetBlockHeader()); + if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) + break; + } + pfrom->PushMessage("headers", vHeaders); + } + + + else if (strCommand == "tx") + { + vector vWorkQueue; + vector vEraseQueue; + CDataStream vMsg(vRecv); + CTxDB txdb("r"); + CTransaction tx; + vRecv >> tx; + + CInv inv(MSG_TX, tx.GetHash()); + pfrom->AddInventoryKnown(inv); + + // Truncate messages to the size of the tx in them + unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + unsigned int oldSize = vMsg.size(); + if (nSize < oldSize) { + vMsg.resize(nSize); + printf("truncating oversized TX %s (%u -> %u)\n", + tx.GetHash().ToString().c_str(), + oldSize, nSize); + } + + bool fMissingInputs = false; + if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs)) + { + SyncWithWallets(tx, NULL, true); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + vEraseQueue.push_back(inv.hash); + + // Recursively process any orphan transactions that depended on this one + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (map::iterator mi = mapOrphanTransactionsByPrev[hashPrev].begin(); + mi != mapOrphanTransactionsByPrev[hashPrev].end(); + ++mi) + { + const CDataStream& vMsg = *((*mi).second); + CTransaction tx; + CDataStream(vMsg) >> tx; + CInv inv(MSG_TX, tx.GetHash()); + bool fMissingInputs2 = false; + + if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs2)) + { + printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); + SyncWithWallets(tx, NULL, true); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + vEraseQueue.push_back(inv.hash); + } + else if (!fMissingInputs2) + { + // invalid orphan + vEraseQueue.push_back(inv.hash); + printf(" removed invalid orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); + } + } + } + + BOOST_FOREACH(uint256 hash, vEraseQueue) + EraseOrphanTx(hash); + } + else if (fMissingInputs) + { + AddOrphanTx(vMsg); + + // DoS prevention: do not allow mapOrphanTransactions to grow unbounded + unsigned int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS); + if (nEvicted > 0) + printf("mapOrphan overflow, removed %u tx\n", nEvicted); + } + if (tx.nDoS) pfrom->Misbehaving(tx.nDoS); + } + + + else if (strCommand == "block") + { + CBlock block; + vRecv >> block; + + printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str()); + // block.print(); + + CInv inv(MSG_BLOCK, block.GetHash()); + pfrom->AddInventoryKnown(inv); + + if (ProcessBlock(pfrom, &block)) + mapAlreadyAskedFor.erase(inv); + if (block.nDoS) pfrom->Misbehaving(block.nDoS); + } + + + else if (strCommand == "getaddr") + { + pfrom->vAddrToSend.clear(); + vector vAddr = addrman.GetAddr(); + BOOST_FOREACH(const CAddress &addr, vAddr) + pfrom->PushAddress(addr); + } + + + else if (strCommand == "checkorder") + { + uint256 hashReply; + vRecv >> hashReply; + + if (!GetBoolArg("-allowreceivebyip")) + { + pfrom->PushMessage("reply", hashReply, (int)2, string("")); + return true; + } + + CWalletTx order; + vRecv >> order; + + /// we have a chance to check the order here + + // Keep giving the same key to the same ip until they use it + if (!mapReuseKey.count(pfrom->addr)) + pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr], true); + + // Send back approval of order and pubkey to use + CScript scriptPubKey; + scriptPubKey << mapReuseKey[pfrom->addr] << OP_CHECKSIG; + pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey); + } + + + else if (strCommand == "reply") + { + uint256 hashReply; + vRecv >> hashReply; + + CRequestTracker tracker; + { + LOCK(pfrom->cs_mapRequests); + map::iterator mi = pfrom->mapRequests.find(hashReply); + if (mi != pfrom->mapRequests.end()) + { + tracker = (*mi).second; + pfrom->mapRequests.erase(mi); + } + } + if (!tracker.IsNull()) + tracker.fn(tracker.param1, vRecv); + } + + + else if (strCommand == "ping") + { + if (pfrom->nVersion > BIP0031_VERSION) + { + uint64 nonce = 0; + vRecv >> nonce; + // Echo the message back with the nonce. This allows for two useful features: + // + // 1) A remote node can quickly check if the connection is operational + // 2) Remote nodes can measure the latency of the network thread. If this node + // is overloaded it won't respond to pings quickly and the remote node can + // avoid sending us more work, like chain download requests. + // + // The nonce stops the remote getting confused between different pings: without + // it, if the remote node sends a ping once per second and this node takes 5 + // seconds to respond to each, the 5th ping the remote sends would appear to + // return very quickly. + pfrom->PushMessage("pong", nonce); + } + } + + + else if (strCommand == "alert") + { + CAlert alert; + vRecv >> alert; + + if (alert.ProcessAlert()) + { + // Relay + pfrom->setKnown.insert(alert.GetHash()); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + alert.RelayTo(pnode); + } + } + } + + + else + { + // Ignore unknown commands for extensibility + } + + + // Update the last seen time for this node's address + if (pfrom->fNetworkNode) + if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping") + AddressCurrentlyConnected(pfrom->addr); + + + return true; +} + +bool ProcessMessages(CNode* pfrom) +{ + CDataStream& vRecv = pfrom->vRecv; + if (vRecv.empty()) + return true; + //if (fDebug) + // printf("ProcessMessages(%u bytes)\n", vRecv.size()); + + // + // Message format + // (4) message start + // (12) command + // (4) size + // (4) checksum + // (x) data + // + + loop + { + // Don't bother if send buffer is too full to respond anyway + if (pfrom->vSend.size() >= SendBufferSize()) + break; + + // Scan for message start + CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart)); + int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader()); + if (vRecv.end() - pstart < nHeaderSize) + { + if ((int)vRecv.size() > nHeaderSize) + { + printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n"); + vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize); + } + break; + } + if (pstart - vRecv.begin() > 0) + printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin()); + vRecv.erase(vRecv.begin(), pstart); + + // Read header + vector vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize); + CMessageHeader hdr; + vRecv >> hdr; + if (!hdr.IsValid()) + { + printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); + continue; + } + string strCommand = hdr.GetCommand(); + + // Message size + unsigned int nMessageSize = hdr.nMessageSize; + if (nMessageSize > MAX_SIZE) + { + printf("ProcessMessages(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize); + continue; + } + if (nMessageSize > vRecv.size()) + { + // Rewind and wait for rest of message + vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end()); + break; + } + + // Checksum + uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + if (nChecksum != hdr.nChecksum) + { + printf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", + strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum); + continue; + } + + // Copy message to its own buffer + CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); + vRecv.ignore(nMessageSize); + + // Process message + bool fRet = false; + try + { + { + LOCK(cs_main); + fRet = ProcessMessage(pfrom, strCommand, vMsg); + } + if (fShutdown) + return true; + } + catch (std::ios_base::failure& e) + { + if (strstr(e.what(), "end of data")) + { + // Allow exceptions from underlength message on vRecv + printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); + } + else if (strstr(e.what(), "size too large")) + { + // Allow exceptions from overlong size + printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what()); + } + else + { + PrintExceptionContinue(&e, "ProcessMessages()"); + } + } + catch (std::exception& e) { + PrintExceptionContinue(&e, "ProcessMessages()"); + } catch (...) { + PrintExceptionContinue(NULL, "ProcessMessages()"); + } + + if (!fRet) + printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize); + } + + vRecv.Compact(); + return true; +} + + +bool SendMessages(CNode* pto, bool fSendTrickle) +{ + TRY_LOCK(cs_main, lockMain); + if (lockMain) { + // Don't send anything until we get their version message + if (pto->nVersion == 0) + return true; + + // 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", nonce); + else + pto->PushMessage("ping"); + } + + // Resend wallet transactions that haven't gotten in a block yet + ResendWalletTransactions(); + + // Address refresh broadcast + static int64 nLastRebroadcast; + if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) + { + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + // Periodically clear setAddrKnown to allow refresh broadcasts + if (nLastRebroadcast) + pnode->setAddrKnown.clear(); + + // Rebroadcast our address + if (!fNoListen) + { + CAddress addr = GetLocalAddress(&pnode->addr); + if (addr.IsRoutable()) + pnode->PushAddress(addr); + } + } + } + nLastRebroadcast = GetTime(); + } + + // + // Message: addr + // + if (fSendTrickle) + { + vector vAddr; + vAddr.reserve(pto->vAddrToSend.size()); + BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) + { + // returns true if wasn't already contained in the set + if (pto->setAddrKnown.insert(addr).second) + { + vAddr.push_back(addr); + // receiver rejects addr messages larger than 1000 + if (vAddr.size() >= 1000) + { + pto->PushMessage("addr", vAddr); + vAddr.clear(); + } + } + } + pto->vAddrToSend.clear(); + if (!vAddr.empty()) + pto->PushMessage("addr", vAddr); + } + + + // + // Message: inventory + // + vector vInv; + vector vInvWait; + { + LOCK(pto->cs_inventory); + vInv.reserve(pto->vInventoryToSend.size()); + vInvWait.reserve(pto->vInventoryToSend.size()); + BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) + { + if (pto->setInventoryKnown.count(inv)) + continue; + + // trickle out tx inv to protect privacy + if (inv.type == MSG_TX && !fSendTrickle) + { + // 1/4 of tx invs blast to all immediately + static uint256 hashSalt; + if (hashSalt == 0) + hashSalt = GetRandHash(); + uint256 hashRand = inv.hash ^ hashSalt; + hashRand = Hash(BEGIN(hashRand), END(hashRand)); + bool fTrickleWait = ((hashRand & 3) != 0); + + // always trickle our own transactions + if (!fTrickleWait) + { + CWalletTx wtx; + if (GetTransaction(inv.hash, wtx)) + if (wtx.fFromMe) + fTrickleWait = true; + } + + if (fTrickleWait) + { + vInvWait.push_back(inv); + continue; + } + } + + // returns true if wasn't already contained in the set + if (pto->setInventoryKnown.insert(inv).second) + { + vInv.push_back(inv); + if (vInv.size() >= 1000) + { + pto->PushMessage("inv", vInv); + vInv.clear(); + } + } + } + pto->vInventoryToSend = vInvWait; + } + if (!vInv.empty()) + pto->PushMessage("inv", vInv); + + + // + // Message: getdata + // + vector vGetData; + int64 nNow = GetTime() * 1000000; + CTxDB txdb("r"); + while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) + { + const CInv& inv = (*pto->mapAskFor.begin()).second; + if (!AlreadyHave(txdb, inv)) + { + if (fDebugNet) + printf("sending getdata: %s\n", inv.ToString().c_str()); + vGetData.push_back(inv); + if (vGetData.size() >= 1000) + { + pto->PushMessage("getdata", vGetData); + vGetData.clear(); + } + mapAlreadyAskedFor[inv] = nNow; + } + pto->mapAskFor.erase(pto->mapAskFor.begin()); + } + if (!vGetData.empty()) + pto->PushMessage("getdata", vGetData); + + } + return true; +} + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// BitcoinMiner +// + +int static FormatHashBlocks(void* pbuffer, unsigned int len) +{ + unsigned char* pdata = (unsigned char*)pbuffer; + unsigned int blocks = 1 + ((len + 8) / 64); + unsigned char* pend = pdata + 64 * blocks; + memset(pdata + len, 0, 64 * blocks - len); + pdata[len] = 0x80; + unsigned int bits = len * 8; + pend[-1] = (bits >> 0) & 0xff; + pend[-2] = (bits >> 8) & 0xff; + pend[-3] = (bits >> 16) & 0xff; + pend[-4] = (bits >> 24) & 0xff; + return blocks; +} + +static const unsigned int pSHA256InitState[8] = +{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + +void SHA256Transform(void* pstate, void* pinput, const void* pinit) +{ + SHA256_CTX ctx; + unsigned char data[64]; + + SHA256_Init(&ctx); + + for (int i = 0; i < 16; i++) + ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]); + + for (int i = 0; i < 8; i++) + ctx.h[i] = ((uint32_t*)pinit)[i]; + + SHA256_Update(&ctx, data, sizeof(data)); + for (int i = 0; i < 8; i++) + ((uint32_t*)pstate)[i] = ctx.h[i]; +} + +// +// ScanHash scans nonces looking for a hash with at least some zero bits. +// It operates on big endian data. Caller does the byte reversing. +// All input buffers are 16-byte aligned. nNonce is usually preserved +// between calls, but periodically or if nNonce is 0xffff0000 or above, +// the block is rebuilt and nNonce starts over at zero. +// +unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone) +{ + unsigned int& nNonce = *(unsigned int*)(pdata + 12); + for (;;) + { + // Crypto++ SHA-256 + // Hash pdata using pmidstate as the starting state into + // preformatted buffer phash1, then hash phash1 into phash + nNonce++; + SHA256Transform(phash1, pdata, pmidstate); + SHA256Transform(phash, phash1, pSHA256InitState); + + // Return the nonce if the hash has at least some zero bits, + // caller will check if it has enough to reach the target + if (((unsigned short*)phash)[14] == 0) + return nNonce; + + // If nothing found after trying for a while, return -1 + if ((nNonce & 0xffff) == 0) + { + nHashesDone = 0xffff+1; + return (unsigned int) -1; + } + } +} + +// Some explaining would be appreciated +class COrphan +{ +public: + CTransaction* ptx; + set setDependsOn; + double dPriority; + + COrphan(CTransaction* ptxIn) + { + ptx = ptxIn; + dPriority = 0; + } + + void print() const + { + printf("COrphan(hash=%s, dPriority=%.1f)\n", ptx->GetHash().ToString().substr(0,10).c_str(), dPriority); + BOOST_FOREACH(uint256 hash, setDependsOn) + printf(" setDependsOn %s\n", hash.ToString().substr(0,10).c_str()); + } +}; + + +uint64 nLastBlockTx = 0; +uint64 nLastBlockSize = 0; + +CBlock* CreateNewBlock(CReserveKey& reservekey) +{ + CBlockIndex* pindexPrev = pindexBest; + + // Create new block + auto_ptr pblock(new CBlock()); + if (!pblock.get()) + return NULL; + + // Create coinbase tx + CTransaction txNew; + txNew.vin.resize(1); + txNew.vin[0].prevout.SetNull(); + txNew.vout.resize(1); + txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; + + // Add our coinbase tx as first transaction + pblock->vtx.push_back(txNew); + + // Collect memory pool transactions into the block + int64 nFees = 0; + { + LOCK2(cs_main, mempool.cs); + CTxDB txdb("r"); + + // Priority order to process transactions + list vOrphan; // list memory doesn't move + map > mapDependers; + multimap mapPriority; + for (map::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) + { + CTransaction& tx = (*mi).second; + if (tx.IsCoinBase() || !tx.IsFinal()) + continue; + + COrphan* porphan = NULL; + double dPriority = 0; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + // Read prev transaction + CTransaction txPrev; + CTxIndex txindex; + if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) + { + // Has to wait for dependencies + if (!porphan) + { + // Use list for automatic deletion + vOrphan.push_back(COrphan(&tx)); + porphan = &vOrphan.back(); + } + mapDependers[txin.prevout.hash].push_back(porphan); + porphan->setDependsOn.insert(txin.prevout.hash); + continue; + } + int64 nValueIn = txPrev.vout[txin.prevout.n].nValue; + + // Read block header + int nConf = txindex.GetDepthInMainChain(); + + dPriority += (double)nValueIn * nConf; + + if (fDebug && GetBoolArg("-printpriority")) + printf("priority nValueIn=%-12"PRI64d" nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority); + } + + // Priority is sum(valuein * age) / txsize + dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + + if (porphan) + porphan->dPriority = dPriority; + else + mapPriority.insert(make_pair(-dPriority, &(*mi).second)); + + if (fDebug && GetBoolArg("-printpriority")) + { + printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str()); + if (porphan) + porphan->print(); + printf("\n"); + } + } + + // Collect transactions into block + map mapTestPool; + uint64 nBlockSize = 1000; + uint64 nBlockTx = 0; + int nBlockSigOps = 100; + while (!mapPriority.empty()) + { + // Take highest priority transaction off priority queue + double dPriority = -(*mapPriority.begin()).first; + CTransaction& tx = *(*mapPriority.begin()).second; + mapPriority.erase(mapPriority.begin()); + + // Size limits + unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN) + continue; + + // Legacy limits on sigOps: + unsigned int nTxSigOps = tx.GetLegacySigOpCount(); + if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) + continue; + + // Transaction fee required depends on block size + // CasinoCoind: Reduce the exempted free transactions to 500 bytes (from Bitcoin's 3000 bytes) + bool fAllowFree = (nBlockSize + nTxSize < 1500 || CTransaction::AllowFree(dPriority)); + int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree, GMF_BLOCK); + + // Connecting shouldn't fail due to dependency on other memory pool transactions + // because we're already processing them in order of dependency + map mapTestPoolTmp(mapTestPool); + MapPrevTx mapInputs; + bool fInvalid; + if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid)) + continue; + + int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut(); + if (nTxFees < nMinFee) + continue; + + nTxSigOps += tx.GetP2SHSigOpCount(mapInputs); + if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) + continue; + + if (!tx.ConnectInputs(mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true)) + continue; + mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size()); + swap(mapTestPool, mapTestPoolTmp); + + // Added + pblock->vtx.push_back(tx); + nBlockSize += nTxSize; + ++nBlockTx; + nBlockSigOps += nTxSigOps; + nFees += nTxFees; + + // Add transactions that depend on this one to the priority queue + uint256 hash = tx.GetHash(); + if (mapDependers.count(hash)) + { + BOOST_FOREACH(COrphan* porphan, mapDependers[hash]) + { + if (!porphan->setDependsOn.empty()) + { + porphan->setDependsOn.erase(hash); + if (porphan->setDependsOn.empty()) + mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx)); + } + } + } + } + + nLastBlockTx = nBlockTx; + nLastBlockSize = nBlockSize; + printf("CreateNewBlock(): total size %lu\n", nBlockSize); + + } + pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees); + + // Fill in header + pblock->hashPrevBlock = pindexPrev->GetBlockHash(); + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + pblock->UpdateTime(pindexPrev); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get()); + pblock->nNonce = 0; + + return pblock.release(); +} + + +void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) +{ + // Update nExtraNonce + static uint256 hashPrevBlock; + if (hashPrevBlock != pblock->hashPrevBlock) + { + nExtraNonce = 0; + hashPrevBlock = pblock->hashPrevBlock; + } + ++nExtraNonce; + pblock->vtx[0].vin[0].scriptSig = (CScript() << pblock->nTime << CBigNum(nExtraNonce)) + COINBASE_FLAGS; + assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100); + + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); +} + + +void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1) +{ + // + // Prebuild hash buffers + // + struct + { + struct unnamed2 + { + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + } + block; + unsigned char pchPadding0[64]; + uint256 hash1; + unsigned char pchPadding1[64]; + } + tmp; + memset(&tmp, 0, sizeof(tmp)); + + tmp.block.nVersion = pblock->nVersion; + tmp.block.hashPrevBlock = pblock->hashPrevBlock; + tmp.block.hashMerkleRoot = pblock->hashMerkleRoot; + tmp.block.nTime = pblock->nTime; + tmp.block.nBits = pblock->nBits; + tmp.block.nNonce = pblock->nNonce; + + FormatHashBlocks(&tmp.block, sizeof(tmp.block)); + FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); + + // Byte swap all the input buffer + for (unsigned int i = 0; i < sizeof(tmp)/4; i++) + ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]); + + // Precalc the first half of the first hash, which stays constant + SHA256Transform(pmidstate, &tmp.block, pSHA256InitState); + + memcpy(pdata, &tmp.block, 128); + memcpy(phash1, &tmp.hash1, 64); +} + + +bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) +{ + uint256 hash = pblock->GetPoWHash(); + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + if (hash > hashTarget) + return false; + + //// debug print + printf("BitcoinMiner:\n"); + printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + pblock->print(); + printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); + + // Found a solution + { + LOCK(cs_main); + if (pblock->hashPrevBlock != hashBestChain) + return error("BitcoinMiner : generated block is stale"); + + // Remove key from key pool + reservekey.KeepKey(); + + // Track how many getdata requests this block gets + { + LOCK(wallet.cs_wallet); + wallet.mapRequestCount[pblock->GetHash()] = 0; + } + + // Process this block the same as if we had received it from another node + if (!ProcessBlock(NULL, pblock)) + return error("BitcoinMiner : ProcessBlock, block not accepted"); + } + + return true; +} + +void static ThreadBitcoinMiner(void* parg); + +static bool fGenerateBitcoins = false; +static bool fLimitProcessors = false; +static int nLimitProcessors = -1; + +void static BitcoinMiner(CWallet *pwallet) +{ + printf("BitcoinMiner started\n"); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + + // Make this thread recognisable as the mining thread + RenameThread("bitcoin-miner"); + + // Each thread has its own key and counter + CReserveKey reservekey(pwallet); + unsigned int nExtraNonce = 0; + + while (fGenerateBitcoins) + { + if (fShutdown) + return; + while (vNodes.empty() || IsInitialBlockDownload()) + { + Sleep(1000); + if (fShutdown) + return; + if (!fGenerateBitcoins) + return; + } + + + // + // Create new block + // + unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrev = pindexBest; + + auto_ptr pblock(CreateNewBlock(reservekey)); + if (!pblock.get()) + return; + IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce); + + printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); + + + // + // Prebuild hash buffers + // + char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf); + char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf); + char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf); + + FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1); + + unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4); + unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8); + //unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12); + + + // + // Search + // + int64 nStart = GetTime(); + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + loop + { + unsigned int nHashesDone = 0; + //unsigned int nNonceFound; + + uint256 thash; + char scratchpad[SCRYPT_SCRATCHPAD_SIZE]; + loop + { + scrypt_1024_1_1_256_sp(BEGIN(pblock->nVersion), BEGIN(thash), scratchpad); + + if (thash <= hashTarget) + { + // Found a solution + SetThreadPriority(THREAD_PRIORITY_NORMAL); + CheckWork(pblock.get(), *pwalletMain, reservekey); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + break; + } + pblock->nNonce += 1; + nHashesDone += 1; + if ((pblock->nNonce & 0xFF) == 0) + break; + } + + // Meter hashes/sec + static int64 nHashCounter; + if (nHPSTimerStart == 0) + { + nHPSTimerStart = GetTimeMillis(); + nHashCounter = 0; + } + else + nHashCounter += nHashesDone; + if (GetTimeMillis() - nHPSTimerStart > 4000) + { + static CCriticalSection cs; + { + LOCK(cs); + if (GetTimeMillis() - nHPSTimerStart > 4000) + { + dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart); + nHPSTimerStart = GetTimeMillis(); + nHashCounter = 0; + string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0); + static int64 nLogTime; + if (GetTime() - nLogTime > 30 * 60) + { + nLogTime = GetTime(); + printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str()); + printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[THREAD_MINER], dHashesPerSec/1000.0); + } + } + } + } + + // Check for stop or if block needs to be rebuilt + if (fShutdown) + return; + if (!fGenerateBitcoins) + return; + if (fLimitProcessors && vnThreadsRunning[THREAD_MINER] > nLimitProcessors) + return; + if (vNodes.empty()) + break; + if (pblock->nNonce >= 0xffff0000) + break; + if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) + break; + if (pindexPrev != pindexBest) + break; + + // Update nTime every few seconds + pblock->UpdateTime(pindexPrev); + nBlockTime = ByteReverse(pblock->nTime); + if (fTestNet) + { + // Changing pblock->nTime can change work required on testnet: + nBlockBits = ByteReverse(pblock->nBits); + hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + } + } + } +} + +void static ThreadBitcoinMiner(void* parg) +{ + CWallet* pwallet = (CWallet*)parg; + try + { + vnThreadsRunning[THREAD_MINER]++; + BitcoinMiner(pwallet); + vnThreadsRunning[THREAD_MINER]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_MINER]--; + PrintException(&e, "ThreadBitcoinMiner()"); + } catch (...) { + vnThreadsRunning[THREAD_MINER]--; + PrintException(NULL, "ThreadBitcoinMiner()"); + } + nHPSTimerStart = 0; + if (vnThreadsRunning[THREAD_MINER] == 0) + dHashesPerSec = 0; + printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[THREAD_MINER]); +} + + +void GenerateBitcoins(bool fGenerate, CWallet* pwallet) +{ + fGenerateBitcoins = fGenerate; + nLimitProcessors = GetArg("-genproclimit", -1); + if (nLimitProcessors == 0) + fGenerateBitcoins = false; + fLimitProcessors = (nLimitProcessors != -1); + + if (fGenerate) + { + int nProcessors = boost::thread::hardware_concurrency(); + printf("%d processors\n", nProcessors); + if (nProcessors < 1) + nProcessors = 1; + if (fLimitProcessors && nProcessors > nLimitProcessors) + nProcessors = nLimitProcessors; + int nAddThreads = nProcessors - vnThreadsRunning[THREAD_MINER]; + printf("Starting %d BitcoinMiner threads\n", nAddThreads); + for (int i = 0; i < nAddThreads; i++) + { + if (!CreateThread(ThreadBitcoinMiner, pwallet)) + printf("Error: CreateThread(ThreadBitcoinMiner) failed\n"); + Sleep(10); + } + } +} diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..e6001f6 --- /dev/null +++ b/src/main.h @@ -0,0 +1,1640 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_MAIN_H +#define BITCOIN_MAIN_H + +#include "bignum.h" +#include "net.h" +#include "key.h" +#include "script.h" +#include "db.h" +#include "scrypt.h" + +#include + +class CWallet; +class CBlock; +class CBlockIndex; +class CKeyItem; +class CReserveKey; + +class CAddress; +class CInv; +class CRequestTracker; +class CNode; + +static const unsigned int MAX_BLOCK_SIZE = 1000000; +static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2; +static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; +static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100; +static const int64 MIN_TX_FEE = 2000000; +static const int64 MIN_RELAY_TX_FEE = MIN_TX_FEE; +static const int64 MAX_MONEY = 336000000 * COIN; // CasinoCoin: maximum of 336 million coins +inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } +static const int COINBASE_MATURITY = 8; +// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. +static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC +#ifdef USE_UPNP +static const int fHaveUPnP = true; +#else +static const int fHaveUPnP = false; +#endif + + +extern CScript COINBASE_FLAGS; + + + + + + +extern CCriticalSection cs_main; +extern std::map mapBlockIndex; +extern uint256 hashGenesisBlock; +extern CBlockIndex* pindexGenesisBlock; +extern int nBestHeight; +extern CBigNum bnBestChainWork; +extern CBigNum bnBestInvalidWork; +extern uint256 hashBestChain; +extern CBlockIndex* pindexBest; +extern unsigned int nTransactionsUpdated; +extern uint64 nLastBlockTx; +extern uint64 nLastBlockSize; +extern const std::string strMessageMagic; +extern double dHashesPerSec; +extern int64 nHPSTimerStart; +extern int64 nTimeBestReceived; +extern CCriticalSection cs_setpwalletRegistered; +extern std::set setpwalletRegistered; +extern unsigned char pchMessageStart[4]; + +// Settings +extern int64 nTransactionFee; +extern int64 nMinimumInputValue; + +// Minimum disk space required - used in CheckDiskSpace() +static const uint64 nMinDiskSpace = 52428800; + + +class CReserveKey; +class CTxDB; +class CTxIndex; + +void RegisterWallet(CWallet* pwalletIn); +void UnregisterWallet(CWallet* pwalletIn); +void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false); +bool ProcessBlock(CNode* pfrom, CBlock* pblock); +bool CheckDiskSpace(uint64 nAdditionalBytes=0); +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); +FILE* AppendBlockFile(unsigned int& nFileRet); +bool LoadBlockIndex(bool fAllowNew=true); +void PrintBlockTree(); +bool ProcessMessages(CNode* pfrom); +bool SendMessages(CNode* pto, bool fSendTrickle); +bool LoadExternalBlockFile(FILE* fileIn); +void GenerateBitcoins(bool fGenerate, CWallet* pwallet); +CBlock* CreateNewBlock(CReserveKey& reservekey); +void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); +void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); +bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); +bool CheckProofOfWork(uint256 hash, unsigned int nBits); +unsigned int ComputeMinWork(unsigned int nBase, int64 nTime); +int GetNumBlocksOfPeers(); +bool IsInitialBlockDownload(); +std::string GetWarnings(std::string strFor); +bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock); + + + + + + + + + + + +bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); + +/** Position on disk for a particular transaction. */ +class CDiskTxPos +{ +public: + unsigned int nFile; + unsigned int nBlockPos; + unsigned int nTxPos; + + CDiskTxPos() + { + SetNull(); + } + + CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn) + { + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nTxPos = nTxPosIn; + } + + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { nFile = (unsigned int) -1; nBlockPos = 0; nTxPos = 0; } + bool IsNull() const { return (nFile == (unsigned int) -1); } + + friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b) + { + return (a.nFile == b.nFile && + a.nBlockPos == b.nBlockPos && + a.nTxPos == b.nTxPos); + } + + friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b) + { + return !(a == b); + } + + std::string ToString() const + { + if (IsNull()) + return "null"; + else + return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos); + } + + void print() const + { + printf("%s", ToString().c_str()); + } +}; + + + +/** An inpoint - a combination of a transaction and an index n into its vin */ +class CInPoint +{ +public: + CTransaction* ptx; + unsigned int n; + + CInPoint() { SetNull(); } + CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; } + void SetNull() { ptx = NULL; n = (unsigned int) -1; } + bool IsNull() const { return (ptx == NULL && n == (unsigned int) -1); } +}; + + + +/** An outpoint - a combination of a transaction hash and an index n into its vout */ +class COutPoint +{ +public: + uint256 hash; + unsigned int n; + + COutPoint() { SetNull(); } + COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; } + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { hash = 0; n = (unsigned int) -1; } + bool IsNull() const { return (hash == 0 && n == (unsigned int) -1); } + + friend bool operator<(const COutPoint& a, const COutPoint& b) + { + return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); + } + + friend bool operator==(const COutPoint& a, const COutPoint& b) + { + return (a.hash == b.hash && a.n == b.n); + } + + friend bool operator!=(const COutPoint& a, const COutPoint& b) + { + return !(a == b); + } + + std::string ToString() const + { + return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +/** An input of a transaction. It contains the location of the previous + * transaction's output that it claims and a signature that matches the + * output's public key. + */ +class CTxIn +{ +public: + COutPoint prevout; + CScript scriptSig; + unsigned int nSequence; + + CTxIn() + { + nSequence = std::numeric_limits::max(); + } + + explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits::max()) + { + prevout = prevoutIn; + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits::max()) + { + prevout = COutPoint(hashPrevTx, nOut); + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(prevout); + READWRITE(scriptSig); + READWRITE(nSequence); + ) + + bool IsFinal() const + { + return (nSequence == std::numeric_limits::max()); + } + + friend bool operator==(const CTxIn& a, const CTxIn& b) + { + return (a.prevout == b.prevout && + a.scriptSig == b.scriptSig && + a.nSequence == b.nSequence); + } + + friend bool operator!=(const CTxIn& a, const CTxIn& b) + { + return !(a == b); + } + + std::string ToString() const + { + std::string str; + str += "CTxIn("; + str += prevout.ToString(); + if (prevout.IsNull()) + str += strprintf(", coinbase %s", HexStr(scriptSig).c_str()); + else + str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str()); + if (nSequence != std::numeric_limits::max()) + str += strprintf(", nSequence=%u", nSequence); + str += ")"; + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +/** An output of a transaction. It contains the public key that the next input + * must be able to sign with to claim it. + */ +class CTxOut +{ +public: + int64 nValue; + CScript scriptPubKey; + + CTxOut() + { + SetNull(); + } + + CTxOut(int64 nValueIn, CScript scriptPubKeyIn) + { + nValue = nValueIn; + scriptPubKey = scriptPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(nValue); + READWRITE(scriptPubKey); + ) + + void SetNull() + { + nValue = -1; + scriptPubKey.clear(); + } + + bool IsNull() + { + return (nValue == -1); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + friend bool operator==(const CTxOut& a, const CTxOut& b) + { + return (a.nValue == b.nValue && + a.scriptPubKey == b.scriptPubKey); + } + + friend bool operator!=(const CTxOut& a, const CTxOut& b) + { + return !(a == b); + } + + std::string ToString() const + { + if (scriptPubKey.size() < 6) + return "CTxOut(error)"; + return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +enum GetMinFee_mode +{ + GMF_BLOCK, + GMF_RELAY, + GMF_SEND, +}; + +typedef std::map > MapPrevTx; + +/** The basic transaction that is broadcasted on the network and contained in + * blocks. A transaction can contain multiple inputs and outputs. + */ +class CTransaction +{ +public: + static const int CURRENT_VERSION=1; + int nVersion; + std::vector vin; + std::vector vout; + unsigned int nLockTime; + + // Denial-of-service detection: + mutable int nDoS; + bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } + + CTransaction() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(vin); + READWRITE(vout); + READWRITE(nLockTime); + ) + + void SetNull() + { + nVersion = CTransaction::CURRENT_VERSION; + vin.clear(); + vout.clear(); + nLockTime = 0; + nDoS = 0; // Denial-of-service prevention + } + + bool IsNull() const + { + return (vin.empty() && vout.empty()); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const + { + // Time based nLockTime implemented in 0.1.6 + if (nLockTime == 0) + return true; + if (nBlockHeight == 0) + nBlockHeight = nBestHeight; + if (nBlockTime == 0) + nBlockTime = GetAdjustedTime(); + if ((int64)nLockTime < ((int64)nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime)) + return true; + BOOST_FOREACH(const CTxIn& txin, vin) + if (!txin.IsFinal()) + return false; + return true; + } + + bool IsNewerThan(const CTransaction& old) const + { + if (vin.size() != old.vin.size()) + return false; + for (unsigned int i = 0; i < vin.size(); i++) + if (vin[i].prevout != old.vin[i].prevout) + return false; + + bool fNewer = false; + unsigned int nLowest = std::numeric_limits::max(); + for (unsigned int i = 0; i < vin.size(); i++) + { + if (vin[i].nSequence != old.vin[i].nSequence) + { + if (vin[i].nSequence <= nLowest) + { + fNewer = false; + nLowest = vin[i].nSequence; + } + if (old.vin[i].nSequence < nLowest) + { + fNewer = true; + nLowest = old.vin[i].nSequence; + } + } + } + return fNewer; + } + + bool IsCoinBase() const + { + return (vin.size() == 1 && vin[0].prevout.IsNull()); + } + + /** Check for standard transaction types + @return True if all outputs (scriptPubKeys) use only standard transaction forms + */ + bool IsStandard() const; + + /** Check for standard transaction types + @param[in] mapInputs Map of previous transactions that have outputs we're spending + @return True if all inputs (scriptSigs) use only standard transaction forms + @see CTransaction::FetchInputs + */ + bool AreInputsStandard(const MapPrevTx& mapInputs) const; + + /** Count ECDSA signature operations the old-fashioned (pre-0.6) way + @return number of sigops this transaction's outputs will produce when spent + @see CTransaction::FetchInputs + */ + unsigned int GetLegacySigOpCount() const; + + /** Count ECDSA signature operations in pay-to-script-hash inputs. + + @param[in] mapInputs Map of previous transactions that have outputs we're spending + @return maximum number of sigops required to validate this transaction's inputs + @see CTransaction::FetchInputs + */ + unsigned int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const; + + /** Amount of bitcoins spent by this transaction. + @return sum of all outputs (note: does not include fees) + */ + int64 GetValueOut() const + { + int64 nValueOut = 0; + BOOST_FOREACH(const CTxOut& txout, vout) + { + nValueOut += txout.nValue; + if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut)) + throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); + } + return nValueOut; + } + + /** Amount of bitcoins coming in to this transaction + Note that lightweight clients may not know anything besides the hash of previous transactions, + so may not be able to calculate this. + + @param[in] mapInputs Map of previous transactions that have outputs we're spending + @return Sum of value of all inputs (scriptSigs) + @see CTransaction::FetchInputs + */ + int64 GetValueIn(const MapPrevTx& mapInputs) const; + + static bool AllowFree(double dPriority) + { + // Large (in bytes) low-priority (new, small-coin) transactions + // need a fee. + return dPriority > COIN * 2880 / 250; // CasinoCoin: 2880 blocks found a day. Priority cutoff is 1 casinocoin day / 250 bytes. + } + + int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const + { + // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE + int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; + + unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); + unsigned int nNewBlockSize = nBlockSize + nBytes; + int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; + + if (fAllowFree) + { + if (nBlockSize == 1) + { + // Transactions under 10K are free + // (about 4500bc if made of 50bc inputs) + if (nBytes < 10000) + nMinFee = 0; + } + else + { + // Free transaction area + if (nNewBlockSize < 27000) + nMinFee = 0; + } + } + + // To limit dust spam, add MIN_TX_FEE/MIN_RELAY_TX_FEE for any output that is less than 0.01 + BOOST_FOREACH(const CTxOut& txout, vout) + if (txout.nValue < CENT) + nMinFee += nBaseFee; + + // Raise the price as the block approaches full + if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2) + { + if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN) + return MAX_MONEY; + nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize); + } + + if (!MoneyRange(nMinFee)) + nMinFee = MAX_MONEY; + return nMinFee; + } + + + bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) + { + CAutoFile filein = CAutoFile(OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"), SER_DISK, CLIENT_VERSION); + if (!filein) + return error("CTransaction::ReadFromDisk() : OpenBlockFile failed"); + + // Read transaction + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : fseek failed"); + + try { + filein >> *this; + } + catch (std::exception &e) { + return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); + } + + // Return file pointer + if (pfileRet) + { + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : second fseek failed"); + *pfileRet = filein.release(); + } + return true; + } + + friend bool operator==(const CTransaction& a, const CTransaction& b) + { + return (a.nVersion == b.nVersion && + a.vin == b.vin && + a.vout == b.vout && + a.nLockTime == b.nLockTime); + } + + friend bool operator!=(const CTransaction& a, const CTransaction& b) + { + return !(a == b); + } + + + std::string ToString() const + { + std::string str; + str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n", + GetHash().ToString().substr(0,10).c_str(), + nVersion, + vin.size(), + vout.size(), + nLockTime); + for (unsigned int i = 0; i < vin.size(); i++) + str += " " + vin[i].ToString() + "\n"; + for (unsigned int i = 0; i < vout.size(); i++) + str += " " + vout[i].ToString() + "\n"; + return str; + } + + void print() const + { + printf("%s", ToString().c_str()); + } + + + bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet); + bool ReadFromDisk(CTxDB& txdb, COutPoint prevout); + bool ReadFromDisk(COutPoint prevout); + bool DisconnectInputs(CTxDB& txdb); + + /** Fetch from memory and/or disk. inputsRet keys are transaction hashes. + + @param[in] txdb Transaction database + @param[in] mapTestPool List of pending changes to the transaction index database + @param[in] fBlock True if being called to add a new best-block to the chain + @param[in] fMiner True if being called by CreateNewBlock + @param[out] inputsRet Pointers to this transaction's inputs + @param[out] fInvalid returns true if transaction is invalid + @return Returns true if all inputs are in txdb or mapTestPool + */ + bool FetchInputs(CTxDB& txdb, const std::map& mapTestPool, + bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid); + + /** Sanity check previous transactions, then, if all checks succeed, + mark them as spent by this transaction. + + @param[in] inputs Previous transactions (from FetchInputs) + @param[out] mapTestPool Keeps track of inputs that need to be updated on disk + @param[in] posThisTx Position of this transaction on disk + @param[in] pindexBlock + @param[in] fBlock true if called from ConnectBlock + @param[in] fMiner true if called from CreateNewBlock + @param[in] fStrictPayToScriptHash true if fully validating p2sh transactions + @return Returns true if all checks succeed + */ + bool ConnectInputs(MapPrevTx inputs, + std::map& mapTestPool, const CDiskTxPos& posThisTx, + const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true); + bool ClientConnectInputs(); + bool CheckTransaction() const; + bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); + +protected: + const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const; +}; + + + + + +/** A transaction with a merkle branch linking it to the block chain. */ +class CMerkleTx : public CTransaction +{ +public: + uint256 hashBlock; + std::vector vMerkleBranch; + int nIndex; + + // memory only + mutable bool fMerkleVerified; + + + CMerkleTx() + { + Init(); + } + + CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) + { + Init(); + } + + void Init() + { + hashBlock = 0; + nIndex = -1; + fMerkleVerified = false; + } + + + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(hashBlock); + READWRITE(vMerkleBranch); + READWRITE(nIndex); + ) + + + int SetMerkleBranch(const CBlock* pblock=NULL); + int GetDepthInMainChain(CBlockIndex* &pindexRet) const; + int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } + bool IsInMainChain() const { return GetDepthInMainChain() > 0; } + int GetBlocksToMaturity() const; + bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptToMemoryPool(); +}; + + + + +/** A txdb record that contains the disk location of a transaction and the + * locations of transactions that spend its outputs. vSpent is really only + * used as a flag, but having the location is very helpful for debugging. + */ +class CTxIndex +{ +public: + CDiskTxPos pos; + std::vector vSpent; + + CTxIndex() + { + SetNull(); + } + + CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs) + { + pos = posIn; + vSpent.resize(nOutputs); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(pos); + READWRITE(vSpent); + ) + + void SetNull() + { + pos.SetNull(); + vSpent.clear(); + } + + bool IsNull() + { + return pos.IsNull(); + } + + friend bool operator==(const CTxIndex& a, const CTxIndex& b) + { + return (a.pos == b.pos && + a.vSpent == b.vSpent); + } + + friend bool operator!=(const CTxIndex& a, const CTxIndex& b) + { + return !(a == b); + } + int GetDepthInMainChain() const; + +}; + + + + + +/** Nodes collect new transactions into a block, hash them into a hash tree, + * and scan through nonce values to make the block's hash satisfy proof-of-work + * requirements. When they solve the proof-of-work, they broadcast the block + * to everyone and the block is added to the block chain. The first transaction + * in the block is a special one that creates a new coin owned by the creator + * of the block. + * + * Blocks are appended to blk0001.dat files on disk. Their location on disk + * is indexed by CBlockIndex objects in memory. + */ +class CBlock +{ +public: + // header + static const int CURRENT_VERSION=1; + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + // network and disk + std::vector vtx; + + // memory only + mutable std::vector vMerkleTree; + + // Denial-of-service detection: + mutable int nDoS; + bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } + + CBlock() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(hashPrevBlock); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + + // ConnectBlock depends on vtx being last so it can calculate offset + if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) + READWRITE(vtx); + else if (fRead) + const_cast(this)->vtx.clear(); + ) + + void SetNull() + { + nVersion = CBlock::CURRENT_VERSION; + hashPrevBlock = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + vtx.clear(); + vMerkleTree.clear(); + nDoS = 0; + } + + bool IsNull() const + { + return (nBits == 0); + } + + uint256 GetHash() const + { + return Hash(BEGIN(nVersion), END(nNonce)); + } + + uint256 GetPoWHash() const + { + uint256 thash; + scrypt_1024_1_1_256(BEGIN(nVersion), BEGIN(thash)); + return thash; + } + + int64 GetBlockTime() const + { + return (int64)nTime; + } + + void UpdateTime(const CBlockIndex* pindexPrev); + + + uint256 BuildMerkleTree() const + { + vMerkleTree.clear(); + BOOST_FOREACH(const CTransaction& tx, vtx) + vMerkleTree.push_back(tx.GetHash()); + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + for (int i = 0; i < nSize; i += 2) + { + int i2 = std::min(i+1, nSize-1); + vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), + BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); + } + j += nSize; + } + return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); + } + + std::vector GetMerkleBranch(int nIndex) const + { + if (vMerkleTree.empty()) + BuildMerkleTree(); + std::vector vMerkleBranch; + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + int i = std::min(nIndex^1, nSize-1); + vMerkleBranch.push_back(vMerkleTree[j+i]); + nIndex >>= 1; + j += nSize; + } + return vMerkleBranch; + } + + static uint256 CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, int nIndex) + { + if (nIndex == -1) + return 0; + BOOST_FOREACH(const uint256& otherside, vMerkleBranch) + { + if (nIndex & 1) + hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); + else + hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); + nIndex >>= 1; + } + return hash; + } + + + bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet) + { + // Open history file to append + CAutoFile fileout = CAutoFile(AppendBlockFile(nFileRet), SER_DISK, CLIENT_VERSION); + if (!fileout) + return error("CBlock::WriteToDisk() : AppendBlockFile failed"); + + // Write index header + unsigned int nSize = fileout.GetSerializeSize(*this); + fileout << FLATDATA(pchMessageStart) << nSize; + + // Write block + long fileOutPos = ftell(fileout); + if (fileOutPos < 0) + return error("CBlock::WriteToDisk() : ftell failed"); + nBlockPosRet = fileOutPos; + fileout << *this; + + // Flush stdio buffers and commit to disk before returning + fflush(fileout); + if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0) + FileCommit(fileout); + + return true; + } + + bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true) + { + SetNull(); + + // Open history file to read + CAutoFile filein = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb"), SER_DISK, CLIENT_VERSION); + if (!filein) + return error("CBlock::ReadFromDisk() : OpenBlockFile failed"); + if (!fReadTransactions) + filein.nType |= SER_BLOCKHEADERONLY; + + // Read block + try { + filein >> *this; + } + catch (std::exception &e) { + return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); + } + + // Check the header + if (!CheckProofOfWork(GetPoWHash(), nBits)) + return error("CBlock::ReadFromDisk() : errors in block header"); + + return true; + } + + + + void print() const + { + printf("CBlock(hash=%s, PoW=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", + GetHash().ToString().substr(0,20).c_str(), + GetPoWHash().ToString().substr(0,20).c_str(), + nVersion, + hashPrevBlock.ToString().substr(0,20).c_str(), + hashMerkleRoot.ToString().substr(0,10).c_str(), + nTime, nBits, nNonce, + vtx.size()); + for (unsigned int i = 0; i < vtx.size(); i++) + { + printf(" "); + vtx[i].print(); + } + printf(" vMerkleTree: "); + for (unsigned int i = 0; i < vMerkleTree.size(); i++) + printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str()); + printf("\n"); + } + + + bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); + bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); + bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true); + bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew); + bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); + bool CheckBlock() const; + bool AcceptBlock(); + +private: + bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew); +}; + + + + + + +/** The block chain is a tree shaped structure starting with the + * genesis block at the root, with each block potentially having multiple + * candidates to be the next block. pprev and pnext link a path through the + * main/longest chain. A blockindex may have multiple pprev pointing back + * to it, but pnext will only point forward to the longest branch, or will + * be null if the block is not part of the longest chain. + */ +class CBlockIndex +{ +public: + const uint256* phashBlock; + CBlockIndex* pprev; + CBlockIndex* pnext; + unsigned int nFile; + unsigned int nBlockPos; + int nHeight; + CBigNum bnChainWork; + + // block header + int nVersion; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + + CBlockIndex() + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = 0; + nBlockPos = 0; + nHeight = 0; + bnChainWork = 0; + + nVersion = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + } + + CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nHeight = 0; + bnChainWork = 0; + + nVersion = block.nVersion; + hashMerkleRoot = block.hashMerkleRoot; + nTime = block.nTime; + nBits = block.nBits; + nNonce = block.nNonce; + } + + CBlock GetBlockHeader() const + { + CBlock block; + block.nVersion = nVersion; + if (pprev) + block.hashPrevBlock = pprev->GetBlockHash(); + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block; + } + + uint256 GetBlockHash() const + { + return *phashBlock; + } + + int64 GetBlockTime() const + { + return (int64)nTime; + } + + CBigNum GetBlockWork() const + { + CBigNum bnTarget; + bnTarget.SetCompact(nBits); + if (bnTarget <= 0) + return 0; + return (CBigNum(1)<<256) / (bnTarget+1); + } + + bool IsInMainChain() const + { + return (pnext || this == pindexBest); + } + + bool CheckIndex() const + { + return true; // CheckProofOfWork(GetBlockHash(), nBits); + } + + enum { nMedianTimeSpan=11 }; + + int64 GetMedianTimePast() const + { + int64 pmedian[nMedianTimeSpan]; + int64* pbegin = &pmedian[nMedianTimeSpan]; + int64* pend = &pmedian[nMedianTimeSpan]; + + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) + *(--pbegin) = pindex->GetBlockTime(); + + std::sort(pbegin, pend); + return pbegin[(pend - pbegin)/2]; + } + + int64 GetMedianTime() const + { + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan/2; i++) + { + if (!pindex->pnext) + return GetBlockTime(); + pindex = pindex->pnext; + } + return pindex->GetMedianTimePast(); + } + + + + std::string ToString() const + { + return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", + pprev, pnext, nFile, nBlockPos, nHeight, + hashMerkleRoot.ToString().substr(0,10).c_str(), + GetBlockHash().ToString().substr(0,20).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + +/** Used to marshal pointers into hashes for db storage. */ +class CDiskBlockIndex : public CBlockIndex +{ +public: + uint256 hashPrev; + uint256 hashNext; + + CDiskBlockIndex() + { + hashPrev = 0; + hashNext = 0; + } + + explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) + { + hashPrev = (pprev ? pprev->GetBlockHash() : 0); + hashNext = (pnext ? pnext->GetBlockHash() : 0); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + + READWRITE(hashNext); + READWRITE(nFile); + READWRITE(nBlockPos); + READWRITE(nHeight); + + // block header + READWRITE(this->nVersion); + READWRITE(hashPrev); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + ) + + uint256 GetBlockHash() const + { + CBlock block; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrev; + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block.GetHash(); + } + + + std::string ToString() const + { + std::string str = "CDiskBlockIndex("; + str += CBlockIndex::ToString(); + str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", + GetBlockHash().ToString().c_str(), + hashPrev.ToString().substr(0,20).c_str(), + hashNext.ToString().substr(0,20).c_str()); + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + + + + + +/** Describes a place in the block chain to another node such that if the + * other node doesn't have the same branch, it can find a recent common trunk. + * The further back it is, the further before the fork it may be. + */ +class CBlockLocator +{ +protected: + std::vector vHave; +public: + + CBlockLocator() + { + } + + explicit CBlockLocator(const CBlockIndex* pindex) + { + Set(pindex); + } + + explicit CBlockLocator(uint256 hashBlock) + { + std::map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end()) + Set((*mi).second); + } + + CBlockLocator(const std::vector& vHaveIn) + { + vHave = vHaveIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vHave); + ) + + void SetNull() + { + vHave.clear(); + } + + bool IsNull() + { + return vHave.empty(); + } + + void Set(const CBlockIndex* pindex) + { + vHave.clear(); + int nStep = 1; + while (pindex) + { + vHave.push_back(pindex->GetBlockHash()); + + // Exponentially larger steps back + for (int i = 0; pindex && i < nStep; i++) + pindex = pindex->pprev; + if (vHave.size() > 10) + nStep *= 2; + } + vHave.push_back(hashGenesisBlock); + } + + int GetDistanceBack() + { + // Retrace how far back it was in the sender's branch + int nDistance = 0; + int nStep = 1; + BOOST_FOREACH(const uint256& hash, vHave) + { + std::map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return nDistance; + } + nDistance += nStep; + if (nDistance > 10) + nStep *= 2; + } + return nDistance; + } + + CBlockIndex* GetBlockIndex() + { + // Find the first block the caller has in the main chain + BOOST_FOREACH(const uint256& hash, vHave) + { + std::map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return pindex; + } + } + return pindexGenesisBlock; + } + + uint256 GetBlockHash() + { + // Find the first block the caller has in the main chain + BOOST_FOREACH(const uint256& hash, vHave) + { + std::map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return hash; + } + } + return hashGenesisBlock; + } + + int GetHeight() + { + CBlockIndex* pindex = GetBlockIndex(); + if (!pindex) + return 0; + return pindex->nHeight; + } +}; + + + + + + + + + +/** Alerts are for notifying old versions if they become too obsolete and + * need to upgrade. The message is displayed in the status bar. + * Alert messages are broadcast as a vector of signed data. Unserializing may + * not read the entire buffer if the alert is for a newer version, but older + * versions can still relay the original data. + */ +class CUnsignedAlert +{ +public: + int nVersion; + int64 nRelayUntil; // when newer nodes stop relaying to newer nodes + int64 nExpiration; + int nID; + int nCancel; + std::set setCancel; + int nMinVer; // lowest version inclusive + int nMaxVer; // highest version inclusive + std::set setSubVer; // empty matches all + int nPriority; + + // Actions + std::string strComment; + std::string strStatusBar; + std::string strReserved; + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(nRelayUntil); + READWRITE(nExpiration); + READWRITE(nID); + READWRITE(nCancel); + READWRITE(setCancel); + READWRITE(nMinVer); + READWRITE(nMaxVer); + READWRITE(setSubVer); + READWRITE(nPriority); + + READWRITE(strComment); + READWRITE(strStatusBar); + READWRITE(strReserved); + ) + + void SetNull() + { + nVersion = 1; + nRelayUntil = 0; + nExpiration = 0; + nID = 0; + nCancel = 0; + setCancel.clear(); + nMinVer = 0; + nMaxVer = 0; + setSubVer.clear(); + nPriority = 0; + + strComment.clear(); + strStatusBar.clear(); + strReserved.clear(); + } + + std::string ToString() const + { + std::string strSetCancel; + BOOST_FOREACH(int n, setCancel) + strSetCancel += strprintf("%d ", n); + std::string strSetSubVer; + BOOST_FOREACH(std::string str, setSubVer) + strSetSubVer += "\"" + str + "\" "; + return strprintf( + "CAlert(\n" + " nVersion = %d\n" + " nRelayUntil = %"PRI64d"\n" + " nExpiration = %"PRI64d"\n" + " nID = %d\n" + " nCancel = %d\n" + " setCancel = %s\n" + " nMinVer = %d\n" + " nMaxVer = %d\n" + " setSubVer = %s\n" + " nPriority = %d\n" + " strComment = \"%s\"\n" + " strStatusBar = \"%s\"\n" + ")\n", + nVersion, + nRelayUntil, + nExpiration, + nID, + nCancel, + strSetCancel.c_str(), + nMinVer, + nMaxVer, + strSetSubVer.c_str(), + nPriority, + strComment.c_str(), + strStatusBar.c_str()); + } + + void print() const + { + printf("%s", ToString().c_str()); + } +}; + +/** An alert is a combination of a serialized CUnsignedAlert and a signature. */ +class CAlert : public CUnsignedAlert +{ +public: + std::vector vchMsg; + std::vector vchSig; + + CAlert() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(vchMsg); + READWRITE(vchSig); + ) + + void SetNull() + { + CUnsignedAlert::SetNull(); + vchMsg.clear(); + vchSig.clear(); + } + + bool IsNull() const + { + return (nExpiration == 0); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool IsInEffect() const + { + return (GetAdjustedTime() < nExpiration); + } + + bool Cancels(const CAlert& alert) const + { + if (!IsInEffect()) + return false; // this was a no-op before 31403 + return (alert.nID <= nCancel || setCancel.count(alert.nID)); + } + + bool AppliesTo(int nVersion, std::string strSubVerIn) const + { + // TODO: rework for client-version-embedded-in-strSubVer ? + return (IsInEffect() && + nMinVer <= nVersion && nVersion <= nMaxVer && + (setSubVer.empty() || setSubVer.count(strSubVerIn))); + } + + bool AppliesToMe() const + { + return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector())); + } + + bool RelayTo(CNode* pnode) const + { + if (!IsInEffect()) + return false; + // returns true if wasn't already contained in the set + if (pnode->setKnown.insert(GetHash()).second) + { + if (AppliesTo(pnode->nVersion, pnode->strSubVer) || + AppliesToMe() || + GetAdjustedTime() < nRelayUntil) + { + pnode->PushMessage("alert", *this); + return true; + } + } + return false; + } + + bool CheckSignature() + { + CKey key; + if (!key.SetPubKey(ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9"))) + return error("CAlert::CheckSignature() : SetPubKey failed"); + if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) + return error("CAlert::CheckSignature() : verify signature failed"); + + // Now unserialize the data + CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); + sMsg >> *(CUnsignedAlert*)this; + return true; + } + + bool ProcessAlert(); + + /* + * Get copy of (active) alert object by hash. Returns a null alert if it is not found. + */ + static CAlert getAlertByHash(const uint256 &hash); +}; + +class CTxMemPool +{ +public: + mutable CCriticalSection cs; + std::map mapTx; + std::map mapNextTx; + + bool accept(CTxDB& txdb, CTransaction &tx, + bool fCheckInputs, bool* pfMissingInputs); + bool addUnchecked(const uint256& hash, CTransaction &tx); + bool remove(CTransaction &tx); + void queryHashes(std::vector& vtxid); + + unsigned long size() + { + LOCK(cs); + return mapTx.size(); + } + + bool exists(uint256 hash) + { + return (mapTx.count(hash) != 0); + } + + CTransaction& lookup(uint256 hash) + { + return mapTx[hash]; + } +}; + +extern CTxMemPool mempool; + +#endif diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw new file mode 100644 index 0000000..f01549a --- /dev/null +++ b/src/makefile.linux-mingw @@ -0,0 +1,105 @@ +# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + +DEPSDIR:=/usr/i586-mingw32msvc + +USE_UPNP:=0 + +INCLUDEPATHS= \ + -I"$(DEPSDIR)/boost_1_49_0" \ + -I"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ + -I"$(DEPSDIR)/openssl-1.0.1b/include" \ + -I"$(DEPSDIR)" \ + -I"$(CURDIR)"/obj \ + +LIBPATHS= \ + -L"$(DEPSDIR)/boost_1_49_0/stage/lib" \ + -L"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ + -L"$(DEPSDIR)/openssl-1.0.1b" + +LIBS= \ + -l boost_system-mt-s \ + -l boost_filesystem-mt-s \ + -l boost_program_options-mt-s \ + -l boost_thread_win32-mt-s \ + -l db_cxx \ + -l ssl \ + -l crypto + +DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -DUSE_IPV6 +DEBUGFLAGS=-g +CFLAGS=-O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) + +TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) + +ifdef USE_UPNP + LIBPATHS += -L"$(DEPSDIR)/miniupnpc" + LIBS += -l miniupnpc -l iphlpapi + DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) +endif + +LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l mswsock -l shlwapi + +# TODO: make the mingw builds smarter about dependencies, like the linux/osx builds are +HEADERS = $(wildcard *.h) + +OBJS= \ + obj/version.o \ + obj/checkpoints.o \ + obj/netbase.o \ + obj/addrman.o \ + obj/crypter.o \ + obj/key.o \ + obj/db.o \ + obj/init.o \ + obj/irc.o \ + obj/keystore.o \ + obj/main.o \ + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/rpcdump.o \ + obj/rpcnet.o \ + obj/rpcrawtransaction.o \ + obj/script.o \ + obj/scrypt.o \ + obj/sync.o \ + obj/util.o \ + obj/wallet.o \ + obj/walletdb.o \ + obj/noui.o + +all: casinocoind.exe + +obj/scrypt.o: scrypt.c + i586-mingw32msvc-gcc -c $(CFLAGS) -o $@ $^ + +obj/build.h: FORCE + /bin/sh ../share/genbuild.sh obj/build.h +version.cpp: obj/build.h +DEFS += -DHAVE_BUILD_INFO + +obj/%.o: %.cpp $(HEADERS) + i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $< + +casinocoind.exe: $(OBJS:obj/%=obj/%) + i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) + +TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) + +obj-test/%.o: test/%.cpp $(HEADERS) + i586-mingw32msvc-g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $< + +test_casinocoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) + i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS) + + +clean: + -rm -f obj/*.o + -rm -f casinocoind.exe + -rm -f obj-test/*.o + -rm -f test_casinocoin.exe + -rm -f src/build.h + +FORCE: diff --git a/src/makefile.mingw b/src/makefile.mingw new file mode 100644 index 0000000..0dcc260 --- /dev/null +++ b/src/makefile.mingw @@ -0,0 +1,95 @@ +# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + +USE_UPNP:= + +INCLUDEPATHS= \ + -I"E:\crypto\deps\boost_1_53_0" \ + -I"E:\crypto\deps\db-4.8.30.NC\build_unix" \ + -I"E:\crypto\deps\openssl-1.0.1b\include" + +LIBPATHS= \ + -L"E:\crypto\deps\boost_1_53_0\stage\lib" \ + -L"E:\crypto\deps\db-4.8.30.NC\build_unix" \ + -L"E:\crypto\deps\openssl-1.0.1b" + +LIBS= \ + -l boost_system-mgw46-mt-s-1_53 \ + -l boost_filesystem-mgw46-mt-s-1_53 \ + -l boost_program_options-mgw46-mt-s-1_53 \ + -l boost_thread-mgw46-mt-s-1_53 \ + -l db_cxx \ + -l ssl \ + -l crypto + +DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -DUSE_IPV6 -D__NO_SYSTEM_INCLUDES + +DEBUGFLAGS=-g +CFLAGS=-mthreads -O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -static + +TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) + +ifdef USE_UPNP + INCLUDEPATHS += -I"C:\miniupnpc-1.6-mgw" + LIBPATHS += -L"C:\miniupnpc-1.6-mgw" + LIBS += -l miniupnpc -l iphlpapi + DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) +endif + +LIBS += -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l mswsock -l shlwapi + +# TODO: make the mingw builds smarter about dependencies, like the linux/osx builds are +HEADERS = $(wildcard *.h) + +OBJS= \ + obj/version.o \ + obj/checkpoints.o \ + obj/netbase.o \ + obj/addrman.o \ + obj/crypter.o \ + obj/key.o \ + obj/db.o \ + obj/init.o \ + obj/irc.o \ + obj/keystore.o \ + obj/main.o \ + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/rpcdump.o \ + obj/rpcnet.o \ + obj/rpcrawtransaction.o \ + obj/script.o \ + obj/scrypt.o \ + obj/sync.o \ + obj/util.o \ + obj/wallet.o \ + obj/walletdb.o \ + obj/noui.o + + +all: casinocoind.exe + +obj/scrypt.o: scrypt.c + gcc -c $(CFLAGS) -o $@ $^ + +obj/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +casinocoind.exe: $(OBJS:obj/%=obj/%) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) + +TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) + +obj-test/%.o: test/%.cpp $(HEADERS) + g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $< + +test_casinocoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS) + +clean: + -del /Q casinocoind test_casinocoin + -del /Q obj\* + -del /Q obj-test\* + -del /Q build.h diff --git a/src/makefile.osx b/src/makefile.osx new file mode 100644 index 0000000..a98646d --- /dev/null +++ b/src/makefile.osx @@ -0,0 +1,154 @@ +# -*- mode: Makefile; -*- +# Copyright (c) 2011 Bitcoin Developers +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + +# Mac OS X makefile for casinocoin +# Originally by Laszlo Hanyecz (solar@heliacal.net) + +CXX=llvm-g++ +DEPSDIR=/opt/local + +INCLUDEPATHS= \ + -I"$(CURDIR)" \ + -I"$(CURDIR)"/obj \ + -I"$(DEPSDIR)/include" \ + -I"$(DEPSDIR)/include/db48" + +LIBPATHS= \ + -L"$(DEPSDIR)/lib" \ + -L"$(DEPSDIR)/lib/db48" + +USE_UPNP:=1 + +LIBS= -dead_strip + +TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) + +ifdef STATIC +# Build STATIC if you are redistributing the casinocoind binary +TESTLIBS += \ + $(DEPSDIR)/lib/libboost_unit_test_framework-mt.a +LIBS += \ + $(DEPSDIR)/lib/db48/libdb_cxx-4.8.a \ + $(DEPSDIR)/lib/libboost_system-mt.a \ + $(DEPSDIR)/lib/libboost_filesystem-mt.a \ + $(DEPSDIR)/lib/libboost_program_options-mt.a \ + $(DEPSDIR)/lib/libboost_thread-mt.a \ + $(DEPSDIR)/lib/libssl.a \ + $(DEPSDIR)/lib/libcrypto.a \ + -lz +else +TESTLIBS += \ + -lboost_unit_test_framework-mt +LIBS += \ + -ldb_cxx-4.8 \ + -lboost_system-mt \ + -lboost_filesystem-mt \ + -lboost_program_options-mt \ + -lboost_thread-mt \ + -lssl \ + -lcrypto \ + -lz +TESTDEFS += -DBOOST_TEST_DYN_LINK +endif + +DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DBOOST_SPIRIT_THREADSAFE -DUSE_IPV6 + +ifdef RELEASE +# Compile for maximum compatibility and smallest size. +# This requires that dependencies are compiled +# the same way. +CFLAGS = -mmacosx-version-min=10.5 -arch i386 -O3 +else +CFLAGS = -g +endif + +# ppc doesn't work because we don't support big-endian +CFLAGS += -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ + $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) + +OBJS= \ + obj/version.o \ + obj/checkpoints.o \ + obj/netbase.o \ + obj/addrman.o \ + obj/crypter.o \ + obj/key.o \ + obj/db.o \ + obj/init.o \ + obj/irc.o \ + obj/keystore.o \ + obj/main.o \ + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/rpcdump.o \ + obj/rpcnet.o \ + obj/rpcrawtransaction.o \ + obj/script.o \ + obj/scrypt.o \ + obj/sync.o \ + obj/util.o \ + obj/wallet.o \ + obj/walletdb.o \ + obj/noui.o + +ifdef USE_UPNP + DEFS += -DUSE_UPNP=$(USE_UPNP) +ifdef STATIC + LIBS += $(DEPSDIR)/lib/libminiupnpc.a +else + LIBS += -lminiupnpc +endif +endif + +all: casinocoind + +# auto-generated dependencies: +-include obj/*.P +-include obj-test/*.P + +obj/scrypt.o: scrypt.c + gcc -c $(CFLAGS) -MMD -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +obj/build.h: FORCE + /bin/sh ../share/genbuild.sh obj/build.h +version.cpp: obj/build.h +DEFS += -DHAVE_BUILD_INFO + +obj/%.o: %.cpp + $(CXX) -c $(CFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +casinocoind: $(OBJS:obj/%=obj/%) + $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) + +TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) + +obj-test/%.o: test/%.cpp + $(CXX) -c $(TESTDEFS) $(CFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +test_casinocoin: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) + $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS) + +clean: + -rm -f casinocoind test_casinocoin + -rm -f obj/*.o + -rm -f obj-test/*.o + -rm -f obj/*.P + -rm -f obj-test/*.P + -rm -f src/build.h + +FORCE: diff --git a/src/makefile.unix b/src/makefile.unix new file mode 100644 index 0000000..d198692 --- /dev/null +++ b/src/makefile.unix @@ -0,0 +1,167 @@ +# Copyright (c) 2009-2010 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + +USE_UPNP:=0 + +DEFS=-DUSE_IPV6 -DBOOST_SPIRIT_THREADSAFE + +DEFS += $(addprefix -I,$(CURDIR) $(CURDIR)/obj $(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH)) +LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH)) + +TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) + +LMODE = dynamic +LMODE2 = dynamic +ifdef STATIC + LMODE = static + ifeq (${STATIC}, all) + LMODE2 = static + endif +else + TESTDEFS += -DBOOST_TEST_DYN_LINK +endif + +# for boost 1.37, add -mt to the boost libraries +LIBS += \ + -Wl,-B$(LMODE) \ + -l boost_system$(BOOST_LIB_SUFFIX) \ + -l boost_filesystem$(BOOST_LIB_SUFFIX) \ + -l boost_program_options$(BOOST_LIB_SUFFIX) \ + -l boost_thread$(BOOST_LIB_SUFFIX) \ + -l db_cxx$(BDB_LIB_SUFFIX) \ + -l ssl \ + -l crypto + +ifndef USE_UPNP + override USE_UPNP = - +endif +ifneq (${USE_UPNP}, -) + LIBS += -l miniupnpc + DEFS += -DUSE_UPNP=$(USE_UPNP) +endif + +LIBS+= \ + -Wl,-B$(LMODE2) \ + -l z \ + -l dl \ + -l pthread + + +# Hardening +# Make some classes of vulnerabilities unexploitable in case one is discovered. +# + # This is a workaround for Ubuntu bug #691722, the default -fstack-protector causes + # -fstack-protector-all to be ignored unless -fno-stack-protector is used first. + # see: https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/691722 + HARDENING=-fno-stack-protector + + # Stack Canaries + # Put numbers at the beginning of each stack frame and check that they are the same. + # If a stack buffer if overflowed, it writes over the canary number and then on return + # when that number is checked, it won't be the same and the program will exit with + # a "Stack smashing detected" error instead of being exploited. + HARDENING+=-fstack-protector-all -Wstack-protector + + # Make some important things such as the global offset table read only as soon as + # the dynamic linker is finished building it. This will prevent overwriting of addresses + # which would later be jumped to. + LDHARDENING+=-Wl,-z,relro -Wl,-z,now + + # Build position independent code to take advantage of Address Space Layout Randomization + # offered by some kernels. + # see doc/build-unix.txt for more information. + ifdef PIE + HARDENING+=-fPIE + LDHARDENING+=-pie + endif + + # -D_FORTIFY_SOURCE=2 does some checking for potentially exploitable code patterns in + # the source such overflowing a statically defined buffer. + HARDENING+=-D_FORTIFY_SOURCE=2 +# + + +DEBUGFLAGS=-g + +# CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only +# adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work. +xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ + $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS) + +# LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only +# adds some defaults in front. Unfortunately, LDFLAGS=... $(LDFLAGS) does not work. +xLDFLAGS=$(LDHARDENING) $(LDFLAGS) + +OBJS= \ + obj/version.o \ + obj/checkpoints.o \ + obj/netbase.o \ + obj/addrman.o \ + obj/crypter.o \ + obj/key.o \ + obj/db.o \ + obj/init.o \ + obj/irc.o \ + obj/keystore.o \ + obj/main.o \ + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/rpcdump.o \ + obj/rpcnet.o \ + obj/rpcrawtransaction.o \ + obj/script.o \ + obj/scrypt.o \ + obj/sync.o \ + obj/util.o \ + obj/wallet.o \ + obj/walletdb.o \ + obj/noui.o + + +all: casinocoind + +# auto-generated dependencies: +-include obj/*.P +-include obj-test/*.P + +obj/scrypt.o: scrypt.c + gcc -c -o $@ $^ + +obj/build.h: FORCE + /bin/sh ../share/genbuild.sh obj/build.h +version.cpp: obj/build.h +DEFS += -DHAVE_BUILD_INFO + +obj/%.o: %.cpp + $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +casinocoind: $(OBJS:obj/%=obj/%) + $(CXX) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS) + +TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) + +obj-test/%.o: test/%.cpp + $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + +test_casinocoin: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) + $(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-B$(LMODE) -lboost_unit_test_framework $(xLDFLAGS) $(LIBS) + +clean: + -rm -f casinocoind test_casinocoin + -rm -f obj/*.o + -rm -f obj-test/*.o + -rm -f obj/*.P + -rm -f obj-test/*.P + -rm -f src/build.h + +FORCE: diff --git a/src/mruset.h b/src/mruset.h new file mode 100644 index 0000000..5f2f00c --- /dev/null +++ b/src/mruset.h @@ -0,0 +1,65 @@ +// Copyright (c) 2012 The Bitcoin developers +// Copyright (c) 2012 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_MRUSET_H +#define BITCOIN_MRUSET_H + +#include +#include + +/** STL-like set container that only keeps the most recent N elements. */ +template class mruset +{ +public: + typedef T key_type; + typedef T value_type; + typedef typename std::set::iterator iterator; + typedef typename std::set::const_iterator const_iterator; + typedef typename std::set::size_type size_type; + +protected: + std::set set; + std::deque queue; + size_type nMaxSize; + +public: + mruset(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; } + iterator begin() const { return set.begin(); } + iterator end() const { return set.end(); } + size_type size() const { return set.size(); } + bool empty() const { return set.empty(); } + iterator find(const key_type& k) const { return set.find(k); } + size_type count(const key_type& k) const { return set.count(k); } + bool inline friend operator==(const mruset& a, const mruset& b) { return a.set == b.set; } + bool inline friend operator==(const mruset& a, const std::set& b) { return a.set == b; } + bool inline friend operator<(const mruset& a, const mruset& b) { return a.set < b.set; } + std::pair insert(const key_type& x) + { + std::pair ret = set.insert(x); + if (ret.second) + { + if (nMaxSize && queue.size() == nMaxSize) + { + set.erase(queue.front()); + queue.pop_front(); + } + queue.push_back(x); + } + return ret; + } + size_type max_size() const { return nMaxSize; } + size_type max_size(size_type s) + { + if (s) + while (queue.size() > s) + { + set.erase(queue.front()); + queue.pop_front(); + } + nMaxSize = s; + return nMaxSize; + } +}; + +#endif diff --git a/src/net.cpp b/src/net.cpp new file mode 100644 index 0000000..157c3ce --- /dev/null +++ b/src/net.cpp @@ -0,0 +1,1983 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "irc.h" +#include "db.h" +#include "net.h" +#include "init.h" +#include "strlcpy.h" +#include "addrman.h" +#include "ui_interface.h" + +#ifdef WIN32 +#include +#endif + +#ifdef USE_UPNP +#include +#include +#include +#include +#endif + +using namespace std; +using namespace boost; + +static const int MAX_OUTBOUND_CONNECTIONS = 8; + +void ThreadMessageHandler2(void* parg); +void ThreadSocketHandler2(void* parg); +void ThreadOpenConnections2(void* parg); +void ThreadOpenAddedConnections2(void* parg); +#ifdef USE_UPNP +void ThreadMapPort2(void* parg); +#endif +void ThreadDNSAddressSeed2(void* parg); +bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); + + +struct LocalServiceInfo { + int nScore; + int nPort; +}; + +// +// Global state variables +// +bool fClient = false; +bool fDiscover = true; +bool fUseUPnP = false; +uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); +static CCriticalSection cs_mapLocalHost; +static map mapLocalHost; +static bool vfReachable[NET_MAX] = {}; +static bool vfLimited[NET_MAX] = {}; +static CNode* pnodeLocalHost = NULL; +uint64 nLocalHostNonce = 0; +array vnThreadsRunning; +static std::vector vhListenSocket; +CAddrMan addrman; + +vector vNodes; +CCriticalSection cs_vNodes; +map mapRelay; +deque > vRelayExpiration; +CCriticalSection cs_mapRelay; +map mapAlreadyAskedFor; + +static deque vOneShots; +CCriticalSection cs_vOneShots; + +set setservAddNodeAddresses; +CCriticalSection cs_setservAddNodeAddresses; + +static CSemaphore *semOutbound = NULL; + +void AddOneShot(string strDest) +{ + LOCK(cs_vOneShots); + vOneShots.push_back(strDest); +} + +unsigned short GetListenPort() +{ + return (unsigned short)(GetArg("-port", GetDefaultPort())); +} + +void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd) +{ + // Filter out duplicate requests + if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd) + return; + pindexLastGetBlocksBegin = pindexBegin; + hashLastGetBlocksEnd = hashEnd; + + PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd); +} + +// find 'best' local address for a particular peer +bool GetLocal(CService& addr, const CNetAddr *paddrPeer) +{ + if (fNoListen) + return false; + + int nBestScore = -1; + int nBestReachability = -1; + { + LOCK(cs_mapLocalHost); + for (map::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) + { + int nScore = (*it).second.nScore; + int nReachability = (*it).first.GetReachabilityFrom(paddrPeer); + if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) + { + addr = CService((*it).first, (*it).second.nPort); + nBestReachability = nReachability; + nBestScore = nScore; + } + } + } + return nBestScore >= 0; +} + +// get best local address for a particular peer as a CAddress +CAddress GetLocalAddress(const CNetAddr *paddrPeer) +{ + CAddress ret(CService("0.0.0.0",0),0); + CService addr; + if (GetLocal(addr, paddrPeer)) + { + ret = CAddress(addr); + ret.nServices = nLocalServices; + ret.nTime = GetAdjustedTime(); + } + return ret; +} + +bool RecvLine(SOCKET hSocket, string& strLine) +{ + strLine = ""; + loop + { + char c; + int nBytes = recv(hSocket, &c, 1, 0); + if (nBytes > 0) + { + if (c == '\n') + continue; + if (c == '\r') + return true; + strLine += c; + if (strLine.size() >= 9000) + return true; + } + else if (nBytes <= 0) + { + if (fShutdown) + return false; + if (nBytes < 0) + { + int nErr = WSAGetLastError(); + if (nErr == WSAEMSGSIZE) + continue; + if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS) + { + Sleep(10); + continue; + } + } + if (!strLine.empty()) + return true; + if (nBytes == 0) + { + // socket closed + printf("socket closed\n"); + return false; + } + else + { + // socket error + int nErr = WSAGetLastError(); + printf("recv failed: %d\n", nErr); + return false; + } + } + } +} + +// used when scores of local addresses may have changed +// pushes better local address to peers +void static AdvertizeLocal() +{ + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + if (pnode->fSuccessfullyConnected) + { + CAddress addrLocal = GetLocalAddress(&pnode->addr); + if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal) + { + pnode->PushAddress(addrLocal); + pnode->addrLocal = addrLocal; + } + } + } +} + +void SetReachable(enum Network net, bool fFlag) +{ + LOCK(cs_mapLocalHost); + vfReachable[net] = fFlag; + if (net == NET_IPV6 && fFlag) + vfReachable[NET_IPV4] = true; +} + +// learn a new local address +bool AddLocal(const CService& addr, int nScore) +{ + if (!addr.IsRoutable()) + return false; + + if (!fDiscover && nScore < LOCAL_MANUAL) + return false; + + if (IsLimited(addr)) + return false; + + printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore); + + { + LOCK(cs_mapLocalHost); + bool fAlready = mapLocalHost.count(addr) > 0; + LocalServiceInfo &info = mapLocalHost[addr]; + if (!fAlready || nScore >= info.nScore) { + info.nScore = nScore; + info.nPort = addr.GetPort() + (fAlready ? 1 : 0); + } + SetReachable(addr.GetNetwork()); + } + + AdvertizeLocal(); + + return true; +} + +bool AddLocal(const CNetAddr &addr, int nScore) +{ + return AddLocal(CService(addr, GetListenPort()), nScore); +} + +/** Make a particular network entirely off-limits (no automatic connects to it) */ +void SetLimited(enum Network net, bool fLimited) +{ + if (net == NET_UNROUTABLE) + return; + LOCK(cs_mapLocalHost); + vfLimited[net] = fLimited; +} + +bool IsLimited(enum Network net) +{ + LOCK(cs_mapLocalHost); + return vfLimited[net]; +} + +bool IsLimited(const CNetAddr &addr) +{ + return IsLimited(addr.GetNetwork()); +} + +/** vote for a local address */ +bool SeenLocal(const CService& addr) +{ + { + LOCK(cs_mapLocalHost); + if (mapLocalHost.count(addr) == 0) + return false; + mapLocalHost[addr].nScore++; + } + + AdvertizeLocal(); + + return true; +} + +/** check whether a given address is potentially local */ +bool IsLocal(const CService& addr) +{ + LOCK(cs_mapLocalHost); + return mapLocalHost.count(addr) > 0; +} + +/** check whether a given address is in a network we can probably connect to */ +bool IsReachable(const CNetAddr& addr) +{ + LOCK(cs_mapLocalHost); + enum Network net = addr.GetNetwork(); + return vfReachable[net] && !vfLimited[net]; +} + +bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet) +{ + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str()); + + send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL); + + string strLine; + while (RecvLine(hSocket, strLine)) + { + if (strLine.empty()) // HTTP response is separated from headers by blank line + { + loop + { + if (!RecvLine(hSocket, strLine)) + { + closesocket(hSocket); + return false; + } + if (pszKeyword == NULL) + break; + if (strLine.find(pszKeyword) != string::npos) + { + strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword)); + break; + } + } + closesocket(hSocket); + if (strLine.find("<") != string::npos) + strLine = strLine.substr(0, strLine.find("<")); + strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); + while (strLine.size() > 0 && isspace(strLine[strLine.size()-1])) + strLine.resize(strLine.size()-1); + CService addr(strLine,0,true); + printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); + if (!addr.IsValid() || !addr.IsRoutable()) + return false; + ipRet.SetIP(addr); + return true; + } + } + closesocket(hSocket); + return error("GetMyExternalIP() : connection closed"); +} + +// We now get our external IP from the IRC server first and only use this as a backup +bool GetMyExternalIP(CNetAddr& ipRet) +{ + CService addrConnect; + const char* pszGet; + const char* pszKeyword; + + for (int nLookup = 0; nLookup <= 1; nLookup++) + for (int nHost = 1; nHost <= 2; nHost++) + { + // We should be phasing out our use of sites like these. If we need + // replacements, we should ask for volunteers to put this simple + // php file on their webserver that prints the client IP: + // + if (nHost == 1) + { + addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org + + if (nLookup == 1) + { + CService addrIP("checkip.dyndns.org", 80, true); + if (addrIP.IsValid()) + addrConnect = addrIP; + } + + pszGet = "GET / HTTP/1.1\r\n" + "Host: checkip.dyndns.org\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = "Address:"; + } + else if (nHost == 2) + { + addrConnect = CService("74.208.43.192", 80); // www.showmyip.com + + if (nLookup == 1) + { + CService addrIP("www.showmyip.com", 80, true); + if (addrIP.IsValid()) + addrConnect = addrIP; + } + + pszGet = "GET /simple/ HTTP/1.1\r\n" + "Host: www.showmyip.com\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = NULL; // Returns just IP address + } + + if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet)) + return true; + } + + return false; +} + +void ThreadGetMyExternalIP(void* parg) +{ + // Make this thread recognisable as the external IP detection thread + RenameThread("bitcoin-ext-ip"); + + CNetAddr addrLocalHost; + if (GetMyExternalIP(addrLocalHost)) + { + printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str()); + AddLocal(addrLocalHost, LOCAL_HTTP); + } +} + + + + + +void AddressCurrentlyConnected(const CService& addr) +{ + addrman.Connected(addr); +} + + + + + + + +CNode* FindNode(const CNetAddr& ip) +{ + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if ((CNetAddr)pnode->addr == ip) + return (pnode); + } + return NULL; +} + +CNode* FindNode(std::string addrName) +{ + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->addrName == addrName) + return (pnode); + return NULL; +} + +CNode* FindNode(const CService& addr) +{ + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if ((CService)pnode->addr == addr) + return (pnode); + } + return NULL; +} + +CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout) +{ + if (pszDest == NULL) { + if (IsLocal(addrConnect)) + return NULL; + + // Look for an existing connection + CNode* pnode = FindNode((CService)addrConnect); + if (pnode) + { + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + return pnode; + } + } + + + /// debug print + printf("trying connection %s lastseen=%.1fhrs\n", + pszDest ? pszDest : addrConnect.ToString().c_str(), + pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0); + + // Connect + SOCKET hSocket; + if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, GetDefaultPort()) : ConnectSocket(addrConnect, hSocket)) + { + addrman.Attempt(addrConnect); + + /// debug print + printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str()); + + // Set to nonblocking +#ifdef WIN32 + u_long nOne = 1; + if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) + printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); +#else + if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) + printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno); +#endif + + // Add node + CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false); + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + + { + LOCK(cs_vNodes); + vNodes.push_back(pnode); + } + + pnode->nTimeConnected = GetTime(); + return pnode; + } + else + { + return NULL; + } +} + +void CNode::CloseSocketDisconnect() +{ + fDisconnect = true; + if (hSocket != INVALID_SOCKET) + { + printf("disconnecting node %s\n", addrName.c_str()); + closesocket(hSocket); + hSocket = INVALID_SOCKET; + vRecv.clear(); + } +} + +void CNode::Cleanup() +{ +} + + +void CNode::PushVersion() +{ + /// when NTP implemented, change to just nTime = GetAdjustedTime() + int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); + 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)); + printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str()); + PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, + nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()), nBestHeight); +} + + + + + +std::map CNode::setBanned; +CCriticalSection CNode::cs_setBanned; + +void CNode::ClearBanned() +{ + setBanned.clear(); +} + +bool CNode::IsBanned(CNetAddr ip) +{ + bool fResult = false; + { + LOCK(cs_setBanned); + std::map::iterator i = setBanned.find(ip); + if (i != setBanned.end()) + { + int64 t = (*i).second; + if (GetTime() < t) + fResult = true; + } + } + return fResult; +} + +bool CNode::Misbehaving(int howmuch) +{ + if (addr.IsLocal()) + { + printf("Warning: local node %s misbehaving\n", addrName.c_str()); + return false; + } + + nMisbehavior += howmuch; + if (nMisbehavior >= GetArg("-banscore", 100)) + { + int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban + { + LOCK(cs_setBanned); + if (setBanned[addr] < banTime) + setBanned[addr] = banTime; + } + CloseSocketDisconnect(); + printf("Disconnected %s for misbehavior (score=%d)\n", addrName.c_str(), nMisbehavior); + return true; + } + return false; +} + +#undef X +#define X(name) stats.name = name +void CNode::copyStats(CNodeStats &stats) +{ + X(nServices); + X(nLastSend); + X(nLastRecv); + X(nTimeConnected); + X(addrName); + X(nVersion); + X(strSubVer); + X(fInbound); + X(nReleaseTime); + X(nStartingHeight); + X(nMisbehavior); +} +#undef X + + + + + + + + + + +void ThreadSocketHandler(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); + + // Make this thread recognisable as the networking thread + RenameThread("bitcoin-net"); + + try + { + vnThreadsRunning[THREAD_SOCKETHANDLER]++; + ThreadSocketHandler2(parg); + vnThreadsRunning[THREAD_SOCKETHANDLER]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_SOCKETHANDLER]--; + PrintException(&e, "ThreadSocketHandler()"); + } catch (...) { + vnThreadsRunning[THREAD_SOCKETHANDLER]--; + throw; // support pthread_cancel() + } + printf("ThreadSocketHandler exited\n"); +} + +void ThreadSocketHandler2(void* parg) +{ + printf("ThreadSocketHandler started\n"); + list vNodesDisconnected; + unsigned int nPrevNodeCount = 0; + + loop + { + // + // Disconnect nodes + // + { + LOCK(cs_vNodes); + // Disconnect unused nodes + vector vNodesCopy = vNodes; + BOOST_FOREACH(CNode* pnode, vNodesCopy) + { + if (pnode->fDisconnect || + (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty())) + { + // remove from vNodes + vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); + + // release outbound grant (if any) + pnode->grantOutbound.Release(); + + // close socket and cleanup + pnode->CloseSocketDisconnect(); + pnode->Cleanup(); + + // hold in disconnected pool until all refs are released + pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60); + if (pnode->fNetworkNode || pnode->fInbound) + pnode->Release(); + vNodesDisconnected.push_back(pnode); + } + } + + // Delete disconnected nodes + list vNodesDisconnectedCopy = vNodesDisconnected; + BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy) + { + // wait until threads are done using it + if (pnode->GetRefCount() <= 0) + { + bool fDelete = false; + { + TRY_LOCK(pnode->cs_vSend, lockSend); + if (lockSend) + { + TRY_LOCK(pnode->cs_vRecv, lockRecv); + if (lockRecv) + { + TRY_LOCK(pnode->cs_mapRequests, lockReq); + if (lockReq) + { + TRY_LOCK(pnode->cs_inventory, lockInv); + if (lockInv) + fDelete = true; + } + } + } + } + if (fDelete) + { + vNodesDisconnected.remove(pnode); + delete pnode; + } + } + } + } + if (vNodes.size() != nPrevNodeCount) + { + nPrevNodeCount = vNodes.size(); + uiInterface.NotifyNumConnectionsChanged(vNodes.size()); + } + + + // + // Find which sockets have data to receive + // + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 50000; // frequency to poll pnode->vSend + + fd_set fdsetRecv; + fd_set fdsetSend; + fd_set fdsetError; + FD_ZERO(&fdsetRecv); + FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); + SOCKET hSocketMax = 0; + + BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) { + FD_SET(hListenSocket, &fdsetRecv); + hSocketMax = max(hSocketMax, hListenSocket); + } + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + { + if (pnode->hSocket == INVALID_SOCKET) + continue; + FD_SET(pnode->hSocket, &fdsetRecv); + FD_SET(pnode->hSocket, &fdsetError); + hSocketMax = max(hSocketMax, pnode->hSocket); + { + TRY_LOCK(pnode->cs_vSend, lockSend); + if (lockSend && !pnode->vSend.empty()) + FD_SET(pnode->hSocket, &fdsetSend); + } + } + } + + vnThreadsRunning[THREAD_SOCKETHANDLER]--; + int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout); + vnThreadsRunning[THREAD_SOCKETHANDLER]++; + if (fShutdown) + return; + if (nSelect == SOCKET_ERROR) + { + int nErr = WSAGetLastError(); + if (hSocketMax != INVALID_SOCKET) + { + printf("socket select error %d\n", nErr); + for (unsigned int i = 0; i <= hSocketMax; i++) + FD_SET(i, &fdsetRecv); + } + FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); + Sleep(timeout.tv_usec/1000); + } + + + // + // Accept new connections + // + BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) + if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv)) + { +#ifdef USE_IPV6 + struct sockaddr_storage sockaddr; +#else + struct sockaddr sockaddr; +#endif + socklen_t len = sizeof(sockaddr); + SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); + CAddress addr; + int nInbound = 0; + + if (hSocket != INVALID_SOCKET) + if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) + printf("warning: unknown socket family\n"); + + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->fInbound) + nInbound++; + } + + if (hSocket == INVALID_SOCKET) + { + if (WSAGetLastError() != WSAEWOULDBLOCK) + printf("socket error accept failed: %d\n", WSAGetLastError()); + } + else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS) + { + { + LOCK(cs_setservAddNodeAddresses); + if (!setservAddNodeAddresses.count(addr)) + closesocket(hSocket); + } + } + else if (CNode::IsBanned(addr)) + { + printf("connection from %s dropped (banned)\n", addr.ToString().c_str()); + closesocket(hSocket); + } + else + { + printf("accepted connection %s\n", addr.ToString().c_str()); + CNode* pnode = new CNode(hSocket, addr, "", true); + pnode->AddRef(); + { + LOCK(cs_vNodes); + vNodes.push_back(pnode); + } + } + } + + + // + // Service each socket + // + vector vNodesCopy; + { + LOCK(cs_vNodes); + vNodesCopy = vNodes; + BOOST_FOREACH(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } + BOOST_FOREACH(CNode* pnode, vNodesCopy) + { + if (fShutdown) + return; + + // + // Receive + // + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError)) + { + TRY_LOCK(pnode->cs_vRecv, lockRecv); + if (lockRecv) + { + CDataStream& vRecv = pnode->vRecv; + unsigned int nPos = vRecv.size(); + + if (nPos > ReceiveBufferSize()) { + if (!pnode->fDisconnect) + printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size()); + pnode->CloseSocketDisconnect(); + } + else { + // typical socket buffer is 8K-64K + char pchBuf[0x10000]; + int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + if (nBytes > 0) + { + vRecv.resize(nPos + nBytes); + memcpy(&vRecv[nPos], pchBuf, nBytes); + pnode->nLastRecv = GetTime(); + } + else if (nBytes == 0) + { + // socket closed gracefully + if (!pnode->fDisconnect) + printf("socket closed\n"); + pnode->CloseSocketDisconnect(); + } + else if (nBytes < 0) + { + // error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + if (!pnode->fDisconnect) + printf("socket recv error %d\n", nErr); + pnode->CloseSocketDisconnect(); + } + } + } + } + } + + // + // Send + // + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetSend)) + { + TRY_LOCK(pnode->cs_vSend, lockSend); + if (lockSend) + { + CDataStream& vSend = pnode->vSend; + if (!vSend.empty()) + { + int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT); + if (nBytes > 0) + { + vSend.erase(vSend.begin(), vSend.begin() + nBytes); + pnode->nLastSend = GetTime(); + } + else if (nBytes < 0) + { + // error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + printf("socket send error %d\n", nErr); + pnode->CloseSocketDisconnect(); + } + } + } + } + } + + // + // Inactivity checking + // + if (pnode->vSend.empty()) + pnode->nLastSendEmpty = GetTime(); + if (GetTime() - pnode->nTimeConnected > 60) + { + if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) + { + printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60) + { + printf("socket not sending\n"); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastRecv > 90*60) + { + printf("socket inactivity timeout\n"); + pnode->fDisconnect = true; + } + } + } + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodesCopy) + pnode->Release(); + } + + Sleep(10); + } +} + + + + + + + + + +#ifdef USE_UPNP +void ThreadMapPort(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg)); + + // Make this thread recognisable as the UPnP thread + RenameThread("bitcoin-UPnP"); + + try + { + vnThreadsRunning[THREAD_UPNP]++; + ThreadMapPort2(parg); + vnThreadsRunning[THREAD_UPNP]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_UPNP]--; + PrintException(&e, "ThreadMapPort()"); + } catch (...) { + vnThreadsRunning[THREAD_UPNP]--; + PrintException(NULL, "ThreadMapPort()"); + } + printf("ThreadMapPort exited\n"); +} + +void ThreadMapPort2(void* parg) +{ + printf("ThreadMapPort started\n"); + + char port[6]; + sprintf(port, "%d", GetListenPort()); + + const char * multicastif = 0; + const char * minissdpdpath = 0; + struct UPNPDev * devlist = 0; + char lanaddr[64]; + +#ifndef UPNPDISCOVER_SUCCESS + /* miniupnpc 1.5 */ + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); +#else + /* miniupnpc 1.6 */ + int error = 0; + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); +#endif + + struct UPNPUrls urls; + struct IGDdatas data; + int r; + + r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); + if (r == 1) + { + if (fDiscover) { + char externalIPAddress[40]; + r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); + if(r != UPNPCOMMAND_SUCCESS) + printf("UPnP: GetExternalIPAddress() returned %d\n", r); + else + { + if(externalIPAddress[0]) + { + printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress); + AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP); + } + else + printf("UPnP: GetExternalIPAddress failed.\n"); + } + } + + string strDesc = "CasinoCoin " + FormatFullVersion(); +#ifndef UPNPDISCOVER_SUCCESS + /* miniupnpc 1.5 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port, port, lanaddr, strDesc.c_str(), "TCP", 0); +#else + /* miniupnpc 1.6 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0"); +#endif + + if(r!=UPNPCOMMAND_SUCCESS) + printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", + port, port, lanaddr, r, strupnperror(r)); + else + printf("UPnP Port Mapping successful.\n"); + int i = 1; + loop { + if (fShutdown || !fUseUPnP) + { + r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0); + printf("UPNP_DeletePortMapping() returned : %d\n", r); + freeUPNPDevlist(devlist); devlist = 0; + FreeUPNPUrls(&urls); + return; + } + if (i % 600 == 0) // Refresh every 20 minutes + { +#ifndef UPNPDISCOVER_SUCCESS + /* miniupnpc 1.5 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port, port, lanaddr, strDesc.c_str(), "TCP", 0); +#else + /* miniupnpc 1.6 */ + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, + port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0"); +#endif + + if(r!=UPNPCOMMAND_SUCCESS) + printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", + port, port, lanaddr, r, strupnperror(r)); + else + printf("UPnP Port Mapping successful.\n");; + } + Sleep(2000); + i++; + } + } else { + printf("No valid UPnP IGDs found\n"); + freeUPNPDevlist(devlist); devlist = 0; + if (r != 0) + FreeUPNPUrls(&urls); + loop { + if (fShutdown || !fUseUPnP) + return; + Sleep(2000); + } + } +} + +void MapPort() +{ + if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1) + { + if (!CreateThread(ThreadMapPort, NULL)) + printf("Error: ThreadMapPort(ThreadMapPort) failed\n"); + } +} +#else +void MapPort() +{ + // Intentionally left blank. +} +#endif + +// DNS seeds +// Each pair gives a source name and a seed name. +// The first name is used as information source for addrman. +// The second name should resolve to a list of seed addresses. +static const char *strMainNetDNSSeed[][2] = { + {"casinoco.in seed #1", "seed1.casinoco.in"}, + {"casinoco.in seed #2", "seed2.casinoco.in"}, + {"casinoco.in seed", "seed.casinoco.in"}, + {NULL, NULL} +}; + +static const char *strTestNetDNSSeed[][2] = { + {"casinoco.in testnet seed #1", "testnet-seed1.casinoco.in"}, + {NULL, NULL} +}; + +void ThreadDNSAddressSeed(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg)); + + // Make this thread recognisable as the DNS seeding thread + RenameThread("bitcoin-dnsseed"); + + try + { + vnThreadsRunning[THREAD_DNSSEED]++; + ThreadDNSAddressSeed2(parg); + vnThreadsRunning[THREAD_DNSSEED]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_DNSSEED]--; + PrintException(&e, "ThreadDNSAddressSeed()"); + } catch (...) { + vnThreadsRunning[THREAD_DNSSEED]--; + throw; // support pthread_cancel() + } + printf("ThreadDNSAddressSeed exited\n"); +} + +void ThreadDNSAddressSeed2(void* parg) +{ + printf("ThreadDNSAddressSeed started\n"); + int found = 0; + + if (true) // minimize diff, this is the last version of 0.6.x + { + printf("Loading addresses from DNS seeds (could take a while)\n"); + + static const char *(*strDNSSeed)[2] = fTestNet ? strTestNetDNSSeed : strMainNetDNSSeed; + + for (unsigned int seed_idx = 0; strDNSSeed[seed_idx][0] != NULL; seed_idx++) { + if (GetNameProxy()) { + AddOneShot(strDNSSeed[seed_idx][1]); + } else { + vector vaddr; + vector vAdd; + if (LookupHost(strDNSSeed[seed_idx][1], vaddr)) + { + BOOST_FOREACH(CNetAddr& ip, vaddr) + { + int nOneDay = 24*3600; + CAddress addr = CAddress(CService(ip, GetDefaultPort())); + addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old + vAdd.push_back(addr); + found++; + } + } + addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true)); + } + } + } + + printf("%d addresses found from DNS seeds\n", found); +} + +unsigned int pnSeed[] = +{ + 0xdfae795b, 0x0e0f46a6, 0xaf7f170c, 0x900486bc, 0xcbac226c, 0x3b551ac7, 0x56eb5d50, 0x136f21b2, + 0x8ddd57d0, 0xb291f363, 0xe57a3c47, 0x66c52560, 0x22b49640, 0xc76aaa1f, 0x5a90693e, 0x3534bdd5, + 0x37a06044, 0x43ecf65b, 0x4ce4995b, 0x7a563c43, 0x29d80c47, 0xe995316c, 0x1aeb864a, 0x3efc3d2a, + 0xf0e2a447, 0xaab216d2, 0xe74daa46, 0xa55fdcac, 0x2b8c811f, 0x625ec650, 0x2876a565, 0xfed55d50, + 0x9673bb48, 0xcd50d74a, 0xc048ed5e, 0xfe56ea47, 0x7e91a562, 0x6c6a888e, 0x07d55753, 0x8bb0bf42, + 0xf61bfd53, 0x1c26ea47, 0x849965ae, 0x96045d47, 0x0a4605be, 0x1f6a2a60, 0x8229fd18, 0x21cd11b8, + 0x9ea641ad, 0xad49d543, 0x45a6814a, 0x77ded690, 0x2dea1b52, 0xef73ad55, 0x8cc5614c, 0x43aca146, + 0x04c89851, 0xb130cb50, 0x686ff23c, 0x369a5f4b, 0x3cb58705, 0x54cd844b, 0x370d854f, 0xea812942, + 0xbc452864, 0xcef02a60, 0x6df6f854, 0xb5666251, 0x2d49386c, 0xb3892660, 0x7551f950, 0x0808a496, + 0x848954c6, 0x16f91ead, 0xd8d3834b, 0x7383794c, 0x8c68fc18, 0x7088066c, 0x5147b445, 0x87c052d8, + 0x4ab15cd4, 0xb8d53b44, 0xe5aa194c, 0x38bc6844, 0x5454c854, 0xfd091718, 0x7107a86c, 0x6454c854, + 0xc4bc8832, 0xfc67dcad, 0x091cb2c6, 0xada7ef47, 0xfcb3c05e, 0x0904f560, 0x37485253, 0x58aef763, + 0xfe716044, 0x1347eb63, 0xad435946, 0xb629d459, 0xf1785851, 0x6f3ec34a, 0xee079e4e, 0x515b7c46, + 0x1be31e98, 0x69f2e862, 0xd2d16f62, 0xb8cc9662, 0x340ad8b4, 0xdb15ee54, 0xaa81af51, 0xdfc57046, + 0xa44fbd42, 0x64f90456, 0x030dc65a, 0xd9842660, 0x03b6da18, 0x64786d4a, 0x8c8f338f, 0x0ec07acb, + 0xb4a5b34f, 0x3c815032, 0x330c1c71, 0x2abe814a, 0xdf0d62ae, 0x33e64979, 0x634dae58, 0xb14d40ad, + 0x948afe45, 0xf8545e4a, 0x9289f37b, 0x2c28a565, 0x25498232, 0x2dabed62, 0xb54df37b, 0x424a7d4c, + 0x1570456c, 0x0cf6bf42, 0x6e4a3f44, 0xa87158c3, 0x6910fb47, 0x29b8a247, 0xcb8d1518, 0x1d326596, + 0x3636dd50, 0xf9e5d762, 0x59d09a5e, 0x41a63e47, 0x5200a6b8, 0x38b71318, 0xc0c3456f, 0x02c6a43c, + 0xc92909b0, 0xa6b913d8, 0xe8b4e462, 0x6e30ac4c, 0x64439ca8, 0xdf8c5a18, 0xc24751d5, 0x5dc9fc6c, + 0xa9a15861, 0x87c4a73b, 0x243441ad, 0x2a853c42, 0x0188339a, 0xf3570f18, 0x0be83d44, 0xffa97257, + 0x23e026d0, 0x86b43760, 0x35ab664c, 0x22740f48, 0x6b6d4318, 0x9a1b1bd8, 0x12d0b64f, 0xd388b23e, + 0xd75cfddc, 0x8780cc47, 0x780e0e45, 0x2251cc82, 0x19fe8418, 0xefa5602a, 0xfb5f1074, 0xdc26ccc7, + 0xad5e7e4c, 0xb271922e, 0xb7054242, 0x9b9d7b47, 0xf9d4d862, 0x0de6e6d8, 0xf3dbcd48, 0x677fc3cc, + 0x7e6e1552, 0x40d69a18, 0x4cb1e152, 0xb4278c18, 0xa5be002e, 0xa95aac43, 0x6587454b, 0x513de262, + 0x15505a4e, 0x92434f46, 0x56522d79, 0x8453c918, 0x821b7544, 0xea69df50, 0xc7da4f5f, 0xcd12dc55, + 0x598a9147, 0x65ef7262, 0xdc454f46, 0x2119bc2e, 0xbedc7eae, 0x6ca8f536, 0x4497eb18, 0xe7ef80c3, + 0xd9a48e4b, 0x52946dcb, 0xcff428b2, 0x2eca1018, 0x4a685747, 0x77967045, 0x68801132, 0x9149ca62, + 0x04cc0844, 0xd65745b8, 0x4fb08218, 0x31362041, 0xa56c1d46, 0x89af1e47, 0x2d3fdb47, 0x1a3c146c, + 0xda1a694a, 0xf534c848, 0x8eee1eb7, 0xb7aac547, 0x1324f450, 0xaa88f745, 0x77e4aa8d, 0x8a1d52b8, + 0xb2499044, 0x26cb1918, 0x926d5c41, 0x4c218a4b, 0x27a90a4c, 0x1cbc8b59, 0x24ff7d4c, 0x391cc36d, + 0x0b58fddc, 0xc3ac0844, 0xe9d90ad8, 0x1b2f412e, 0x6a221b60, 0xe3518048, 0xc4071975, 0x1c3f72d8, + 0x1e8822d9, 0x067c7a76, 0x557cd782, 0xd5df0e43, 0x831a19bc, 0xe270ac55, 0x2106be5f, 0x49130087, + 0xdd1f0164, 0x76c75753, 0x2e935d02, 0x5491f460, 0x05736344, 0x748c3bda, 0x9534e95c, 0x64e9e444, + 0x96d55d61, 0xd9421656, 0xb044a143, 0xd2ca5a61, 0xbe074854, 0x48dadd43, 0x9cf29b18, 0x4641ee5c, + 0xa2581b53, 0xd585b86c, 0xa77c8a55, 0x5bd5aa47, 0x3b1a3947, 0x4cbcda51, 0x881a94b2, 0x463dc058, + 0xdc241618, 0x9f3b5d47, 0xdd431b4c, 0x76c9db57, 0x2dbfae47, 0x71a8fb53, 0x5447d562, 0x27f1e44e, + 0x0d7aa76c, 0x3e714945, 0x3fa9c544, 0xa6683532, 0x96e0fa45, 0xc4f8d782, 0xd6bddf62, 0xa1536d54, + 0x9404aa56, 0xca7bd742, 0x5ebc0164, 0x37737f45, 0x0fb8d2cc, 0x8dd4c04a, 0xdef43160, 0x71ff5053, + 0xbfe55d5f, 0x3539b34c, 0x90cdbeb8, 0xdb4e2247, 0x3bcc0b1f, 0xce5e5144, 0x7d7f57c7, 0xeeef3d55, + 0xea4a7752, 0x4a1906ae, 0x21e1cc6c, 0xe5b21cad, 0x10ab554b, 0xf553b147, 0xb796d162, 0x0aff2744, + 0x6b657054, 0x9115a665, 0xd873fb4d, 0x5abcd418, 0xccaf8ad5, 0x8dfb0718, 0x3bd6c248, 0xa581614c, + 0x18516041, 0xfa8c8e32, 0x96d33ea8, 0x0fed615f, 0x7b34c9dd, 0x928fa944, 0xb598b0ba, 0x9de9d562, + 0xa9c3bd4b, 0x5c275cae, 0xd61a8945, 0xcdc47f60, 0x0a46e962, 0x6596ed18, 0xae7ac46b, 0x5bcc4748, + 0x9ad6ba18, 0x1c428d4b, 0x9d0efa59, 0x68c006d1, 0xaedf5f41, 0x7caf0918, 0x48519b32, 0x091d1d46, + 0x36c0d176, 0xdb5be248, 0xc21d3b46, 0x18c61418, 0xd5a26044, 0x05898d18, 0xf11ee3be, 0xd10340ad, + 0xea33e218, 0xc4f3b742, 0xe5a50f18, 0x46f63b4a, 0xff72341f, 0x7c901dad, 0xc74f1162, 0xdf2b5032, + 0xc29b296c, 0x3c8eec5c, 0xfa8eaf6e, 0xc0bb5475, 0x4d2e1a46, 0x31f55a42, 0xa4fd211b, 0x8eed4147, + 0x506a3f18, 0x28521856, 0x88ccec47, 0xa8a92160, 0x4aa70e18, 0x1e644442, 0xc657ddd8, 0x368ce663, + 0xbe9859d1, 0x3e245ad4, 0xe6029744, 0x31de1f52, 0x4c617544, 0x945830ae, 0x5f82b543, 0xccfa574b, + 0xdee3b944, 0xb80bfcd8, 0x80b85741, 0x0980a545, 0x1c8dac62, 0x82ba6e62, 0x03c6ea42, 0x74c53b44, + 0xf9e02ebd, 0xcc3f715b, 0x942b0145, 0x9c8da545, 0x31980925, 0xcb9dd562, 0xf0ba0e4c, 0x9208564e, + 0x8ba74055, 0x96ed6c4b, 0x4057d74a, 0xc8d569d8, 0xfd48e4a5, 0x2f695670, 0x8387d418, 0x0902dd5f, + 0xf15aef47, 0x4368c65a, 0x2aeea988, 0xbdf6a94c, 0x7136165f, 0x86ea3dae, 0x8bbd1c6c, 0x9d2ed447, + 0x1987b59e, 0xc2bbb74f, 0x34b70b5c, 0xfaf65741, 0xab46e763, 0x33d454c6, 0xc26df645, 0x5f7351cf, + 0xf2ebefdc, 0xd4165c61, 0xafada73b, 0x68eaf7de, 0x0cee73d4, 0xc1753532, 0xda64f555, 0x6144406d, + 0x5eb0fb6c, 0x8993c90e, 0xab6d8792, 0x06d8a95f, 0xc60cfe45, 0xe3efb948, 0x0a393744, 0x8f47bcce, + 0x44b7d4b0, 0x3080fb4d, 0x2b95e744, 0xb010324d, 0xf820e247, 0x47384b80, 0xa54c41bc, 0x63a07618, + 0x004c4f5f, 0xde9aca47, 0xf9a842b8, 0x7208ae4b, 0x59927257, 0x2d1ea27c, 0x0386c65e, 0x3d0b6b3a, + 0x4ce6bd4b, 0x49ca67d5, 0xe1333bcb, 0x97684f5f, 0x54d130ad, 0x62470b25, 0xc11acab2, 0x6e7f947a, + 0x93f08056, 0x40588256, 0xf069e048, 0x4d224952, 0xcb846250, 0x4c9eaf6e, 0x7a2efe53, 0xa67ac3d1, + 0x64e3604a, 0xb5e154b2, 0x622a941f, 0xea76ca5c, 0x63f0515d, 0xe63efe62, 0x2ccbda72, 0x1c262b44, + 0x336fd956, 0x9d9f687a, 0x85d88856, 0xfc77be2e, 0x1c41bb7c, 0xf29c554d, 0x1268ee50, 0xd82d1abc, + 0x037a083a, 0xca5c8240, 0xf76fa73b, 0x2589494d, 0x3499fe4d, 0x67005553, 0xef8295b6, 0x21ca9662, + 0x4f8f1532, 0x480541b2, 0x0311d779, 0xb8b9a73b, 0xdb570a70, 0x93542dba, 0xde05a765, 0x23e863b0, + 0x69590352, 0xc8df0d56, 0x7e44db5d, 0x626aa97c, 0xf08b904f, 0x8be7063a, 0x288da94f, 0x7c9d1a41, + 0xae369478, 0xb1376c7a, 0x2b66cf18, 0xb021cf18, 0xafad957a, 0x8b69d62e, 0x32d3a87c, 0xc4ad846d, + 0x04c9888d, 0x418a3c02, 0x4f680471, 0x5881bd5e, 0x80bf0b1f, 0x569f966d, 0xae28fb5c, 0x25816c4a +}; + + +void DumpAddresses() +{ + int64 nStart = GetTimeMillis(); + + CAddrDB adb; + adb.Write(addrman); + + printf("Flushed %d addresses to peers.dat %"PRI64d"ms\n", + addrman.size(), GetTimeMillis() - nStart); +} + +void ThreadDumpAddress2(void* parg) +{ + vnThreadsRunning[THREAD_DUMPADDRESS]++; + while (!fShutdown) + { + DumpAddresses(); + vnThreadsRunning[THREAD_DUMPADDRESS]--; + Sleep(100000); + vnThreadsRunning[THREAD_DUMPADDRESS]++; + } + vnThreadsRunning[THREAD_DUMPADDRESS]--; +} + +void ThreadDumpAddress(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg)); + + // Make this thread recognisable as the address dumping thread + RenameThread("bitcoin-adrdump"); + + try + { + ThreadDumpAddress2(parg); + } + catch (std::exception& e) { + PrintException(&e, "ThreadDumpAddress()"); + } + printf("ThreadDumpAddress exited\n"); +} + +void ThreadOpenConnections(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); + + // Make this thread recognisable as the connection opening thread + RenameThread("bitcoin-opencon"); + + try + { + vnThreadsRunning[THREAD_OPENCONNECTIONS]++; + ThreadOpenConnections2(parg); + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + PrintException(&e, "ThreadOpenConnections()"); + } catch (...) { + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + PrintException(NULL, "ThreadOpenConnections()"); + } + printf("ThreadOpenConnections exited\n"); +} + +void static ProcessOneShot() +{ + string strDest; + { + LOCK(cs_vOneShots); + if (vOneShots.empty()) + return; + strDest = vOneShots.front(); + vOneShots.pop_front(); + } + CAddress addr; + CSemaphoreGrant grant(*semOutbound, true); + if (grant) { + if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true)) + AddOneShot(strDest); + } +} + +void ThreadOpenConnections2(void* parg) +{ + printf("ThreadOpenConnections started\n"); + + // Connect to specific addresses + if (mapArgs.count("-connect")) + { + for (int64 nLoop = 0;; nLoop++) + { + ProcessOneShot(); + BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"]) + { + CAddress addr; + OpenNetworkConnection(addr, NULL, strAddr.c_str()); + for (int i = 0; i < 10 && i < nLoop; i++) + { + Sleep(500); + if (fShutdown) + return; + } + } + } + } + + // Initiate network connections + int64 nStart = GetTime(); + loop + { + ProcessOneShot(); + + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + Sleep(500); + vnThreadsRunning[THREAD_OPENCONNECTIONS]++; + if (fShutdown) + return; + + + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + CSemaphoreGrant grant(*semOutbound); + vnThreadsRunning[THREAD_OPENCONNECTIONS]++; + if (fShutdown) + return; + + // Add seed nodes if IRC isn't working + if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet) + { + std::vector vAdd; + for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) + { + // It'll only connect to one or two seed nodes because once it connects, + // it'll get a pile of addresses with newer timestamps. + // Seed nodes are given a random 'last seen time' of between one and two + // weeks ago. + const int64 nOneWeek = 7*24*60*60; + struct in_addr ip; + memcpy(&ip, &pnSeed[i], sizeof(ip)); + CAddress addr(CService(ip, GetDefaultPort())); + addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek; + vAdd.push_back(addr); + } + addrman.Add(vAdd, CNetAddr("127.0.0.1")); + } + + // + // Choose an address to connect to based on most recently seen + // + CAddress addrConnect; + + // Only connect out to one peer per network group (/16 for IPv4). + // Do this here so we don't have to critsect vNodes inside mapAddresses critsect. + int nOutbound = 0; + set > setConnected; + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) { + if (!pnode->fInbound) { + setConnected.insert(pnode->addr.GetGroup()); + nOutbound++; + } + } + } + + int64 nANow = GetAdjustedTime(); + + int nTries = 0; + loop + { + // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections) + CAddress addr = addrman.Select(10 + min(nOutbound,8)*10); + + // if we selected an invalid address, restart + if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) + break; + + nTries++; + + if (IsLimited(addr)) + continue; + + // only consider very recently tried nodes after 30 failed attempts + if (nANow - addr.nLastTry < 600 && nTries < 30) + continue; + + // do not allow non-default ports, unless after 50 invalid addresses selected already + if (addr.GetPort() != GetDefaultPort() && nTries < 50) + continue; + + addrConnect = addr; + break; + } + + if (addrConnect.IsValid()) + OpenNetworkConnection(addrConnect, &grant); + } +} + +void ThreadOpenAddedConnections(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg)); + + // Make this thread recognisable as the connection opening thread + RenameThread("bitcoin-opencon"); + + try + { + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; + ThreadOpenAddedConnections2(parg); + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + PrintException(&e, "ThreadOpenAddedConnections()"); + } catch (...) { + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + PrintException(NULL, "ThreadOpenAddedConnections()"); + } + printf("ThreadOpenAddedConnections exited\n"); +} + +void ThreadOpenAddedConnections2(void* parg) +{ + printf("ThreadOpenAddedConnections started\n"); + + if (mapArgs.count("-addnode") == 0) + return; + + if (GetNameProxy()) { + while(!fShutdown) { + BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) { + CAddress addr; + CSemaphoreGrant grant(*semOutbound); + OpenNetworkConnection(addr, &grant, strAddNode.c_str()); + Sleep(500); + } + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + Sleep(120000); // Retry every 2 minutes + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; + } + return; + } + + vector > vservAddressesToAdd(0); + BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) + { + vector vservNode(0); + if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0)) + { + vservAddressesToAdd.push_back(vservNode); + { + LOCK(cs_setservAddNodeAddresses); + BOOST_FOREACH(CService& serv, vservNode) + setservAddNodeAddresses.insert(serv); + } + } + } + loop + { + vector > vservConnectAddresses = vservAddressesToAdd; + // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry + // (keeping in mind that addnode entries can have many IPs if fNameLookup) + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + for (vector >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++) + BOOST_FOREACH(CService& addrNode, *(it)) + if (pnode->addr == addrNode) + { + it = vservConnectAddresses.erase(it); + it--; + break; + } + } + BOOST_FOREACH(vector& vserv, vservConnectAddresses) + { + CSemaphoreGrant grant(*semOutbound); + OpenNetworkConnection(CAddress(*(vserv.begin())), &grant); + Sleep(500); + if (fShutdown) + return; + } + if (fShutdown) + return; + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + Sleep(120000); // Retry every 2 minutes + vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; + if (fShutdown) + return; + } +} + +// if succesful, this moves the passed grant to the constructed node +bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot) +{ + // + // Initiate outbound network connection + // + if (fShutdown) + return false; + if (!strDest) + if (IsLocal(addrConnect) || + FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) || + FindNode(addrConnect.ToStringIPPort().c_str())) + return false; + if (strDest && FindNode(strDest)) + return false; + + vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + CNode* pnode = ConnectNode(addrConnect, strDest); + vnThreadsRunning[THREAD_OPENCONNECTIONS]++; + if (fShutdown) + return false; + if (!pnode) + return false; + if (grantOutbound) + grantOutbound->MoveTo(pnode->grantOutbound); + pnode->fNetworkNode = true; + if (fOneShot) + pnode->fOneShot = true; + + return true; +} + + + + + + + + +void ThreadMessageHandler(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); + + // Make this thread recognisable as the message handling thread + RenameThread("bitcoin-msghand"); + + try + { + vnThreadsRunning[THREAD_MESSAGEHANDLER]++; + ThreadMessageHandler2(parg); + vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + } + catch (std::exception& e) { + vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + PrintException(&e, "ThreadMessageHandler()"); + } catch (...) { + vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + PrintException(NULL, "ThreadMessageHandler()"); + } + printf("ThreadMessageHandler exited\n"); +} + +void ThreadMessageHandler2(void* parg) +{ + printf("ThreadMessageHandler started\n"); + SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); + while (!fShutdown) + { + vector vNodesCopy; + { + LOCK(cs_vNodes); + vNodesCopy = vNodes; + BOOST_FOREACH(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } + + // Poll the connected nodes for messages + CNode* pnodeTrickle = NULL; + if (!vNodesCopy.empty()) + pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())]; + BOOST_FOREACH(CNode* pnode, vNodesCopy) + { + // Receive messages + { + TRY_LOCK(pnode->cs_vRecv, lockRecv); + if (lockRecv) + ProcessMessages(pnode); + } + if (fShutdown) + return; + + // Send messages + { + TRY_LOCK(pnode->cs_vSend, lockSend); + if (lockSend) + SendMessages(pnode, pnode == pnodeTrickle); + } + if (fShutdown) + return; + } + + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodesCopy) + pnode->Release(); + } + + // Wait and allow messages to bunch up. + // Reduce vnThreadsRunning so StopNode has permission to exit while + // we're sleeping, but we must always check fShutdown after doing this. + vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + Sleep(100); + if (fRequestShutdown) + StartShutdown(); + vnThreadsRunning[THREAD_MESSAGEHANDLER]++; + if (fShutdown) + return; + } +} + + + + + + +bool BindListenPort(const CService &addrBind, string& strError) +{ + strError = ""; + int nOne = 1; + +#ifdef WIN32 + // Initialize Windows Sockets + WSADATA wsadata; + int ret = WSAStartup(MAKEWORD(2,2), &wsadata); + if (ret != NO_ERROR) + { + strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret); + printf("%s\n", strError.c_str()); + return false; + } +#endif + + // Create socket for listening for incoming connections +#ifdef USE_IPV6 + struct sockaddr_storage sockaddr; +#else + struct sockaddr sockaddr; +#endif + socklen_t len = sizeof(sockaddr); + if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len)) + { + strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str()); + printf("%s\n", strError.c_str()); + return false; + } + + SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (hListenSocket == INVALID_SOCKET) + { + strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + +#ifdef SO_NOSIGPIPE + // Different way of disabling SIGPIPE on BSD + setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); +#endif + +#ifndef WIN32 + // Allow binding if the port is still in TIME_WAIT state after + // the program was closed and restarted. Not an issue on windows. + setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); +#endif + + +#ifdef WIN32 + // Set to nonblocking, incoming connections will also inherit this + if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR) +#else + if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) +#endif + { + strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + +#ifdef USE_IPV6 + // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option + // and enable it by default or not. Try to enable it, if possible. + if (addrBind.IsIPv6()) { +#ifdef IPV6_V6ONLY + setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int)); +#endif +#ifdef WIN32 + int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */; + int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */; + // this call is allowed to fail + setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int)); +#endif + } +#endif + + if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) + { + int nErr = WSAGetLastError(); + if (nErr == WSAEADDRINUSE) + strError = strprintf(_("Unable to bind to %s on this computer. CasinoCoin is probably already running."), addrBind.ToString().c_str()); + else + strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr)); + printf("%s\n", strError.c_str()); + return false; + } + printf("Bound to %s\n", addrBind.ToString().c_str()); + + // Listen for incoming connections + if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) + { + strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + vhListenSocket.push_back(hListenSocket); + + if (addrBind.IsRoutable() && fDiscover) + AddLocal(addrBind, LOCAL_BIND); + + return true; +} + +void static Discover() +{ + if (!fDiscover) + return; + +#ifdef WIN32 + // Get local host ip + char pszHostName[1000] = ""; + if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) + { + vector vaddr; + if (LookupHost(pszHostName, vaddr)) + { + BOOST_FOREACH (const CNetAddr &addr, vaddr) + { + AddLocal(addr, LOCAL_IF); + } + } + } +#else + // Get local host ip + struct ifaddrs* myaddrs; + if (getifaddrs(&myaddrs) == 0) + { + for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == NULL) continue; + if ((ifa->ifa_flags & IFF_UP) == 0) continue; + if (strcmp(ifa->ifa_name, "lo") == 0) continue; + if (strcmp(ifa->ifa_name, "lo0") == 0) continue; + if (ifa->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr); + CNetAddr addr(s4->sin_addr); + if (AddLocal(addr, LOCAL_IF)) + printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str()); + } +#ifdef USE_IPV6 + else if (ifa->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr); + CNetAddr addr(s6->sin6_addr); + if (AddLocal(addr, LOCAL_IF)) + printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str()); + } +#endif + } + freeifaddrs(myaddrs); + } +#endif + + CreateThread(ThreadGetMyExternalIP, NULL); +} + +void StartNode(void* parg) +{ + // Make this thread recognisable as the startup thread + RenameThread("bitcoin-start"); + + if (semOutbound == NULL) { + // initialize semaphore + int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125)); + semOutbound = new CSemaphore(nMaxOutbound); + } + + if (pnodeLocalHost == NULL) + pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices)); + + Discover(); + + // + // Start threads + // + + if (!GetBoolArg("-dnsseed", true)) + printf("DNS seeding disabled\n"); + else + if (!CreateThread(ThreadDNSAddressSeed, NULL)) + printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n"); + + // Map ports with UPnP + if (fUseUPnP) + MapPort(); + + // Get addresses from IRC and advertise ours + if (!CreateThread(ThreadIRCSeed, NULL)) + printf("Error: CreateThread(ThreadIRCSeed) failed\n"); + + // Send and receive from sockets, accept connections + if (!CreateThread(ThreadSocketHandler, NULL)) + printf("Error: CreateThread(ThreadSocketHandler) failed\n"); + + // Initiate outbound connections from -addnode + if (!CreateThread(ThreadOpenAddedConnections, NULL)) + printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n"); + + // Initiate outbound connections + if (!CreateThread(ThreadOpenConnections, NULL)) + printf("Error: CreateThread(ThreadOpenConnections) failed\n"); + + // Process messages + if (!CreateThread(ThreadMessageHandler, NULL)) + printf("Error: CreateThread(ThreadMessageHandler) failed\n"); + + // Dump network addresses + if (!CreateThread(ThreadDumpAddress, NULL)) + printf("Error; CreateThread(ThreadDumpAddress) failed\n"); +} + +bool StopNode() +{ + printf("StopNode()\n"); + fShutdown = true; + nTransactionsUpdated++; + int64 nStart = GetTime(); + if (semOutbound) + for (int i=0; ipost(); + do + { + int nThreadsRunning = 0; + for (int n = 0; n < THREAD_MAX; n++) + nThreadsRunning += vnThreadsRunning[n]; + if (nThreadsRunning == 0) + break; + if (GetTime() - nStart > 20) + break; + Sleep(20); + } while(true); + if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n"); + if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n"); + if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n"); + 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"); +#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"); + while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0) + Sleep(20); + Sleep(50); + DumpAddresses(); + return true; +} + +class CNetCleanup +{ +public: + CNetCleanup() + { + } + ~CNetCleanup() + { + // Close sockets + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->hSocket != INVALID_SOCKET) + closesocket(pnode->hSocket); + BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) + if (hListenSocket != INVALID_SOCKET) + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + +#ifdef WIN32 + // Shutdown Windows Sockets + WSACleanup(); +#endif + } +} +instance_of_cnetcleanup; diff --git a/src/net.h b/src/net.h new file mode 100644 index 0000000..7feab74 --- /dev/null +++ b/src/net.h @@ -0,0 +1,692 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_NET_H +#define BITCOIN_NET_H + +#include +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#include "mruset.h" +#include "netbase.h" +#include "protocol.h" +#include "addrman.h" + +class CRequestTracker; +class CNode; +class CBlockIndex; +extern int nBestHeight; + + + +inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); } +inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } + +void AddOneShot(std::string strDest); +bool RecvLine(SOCKET hSocket, std::string& strLine); +bool GetMyExternalIP(CNetAddr& ipRet); +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(); +unsigned short GetListenPort(); +bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string())); +void StartNode(void* parg); +bool StopNode(); + +enum +{ + LOCAL_NONE, // unknown + LOCAL_IF, // address a local interface listens on + LOCAL_BIND, // address explicit bound to + LOCAL_UPNP, // address reported by UPnP + LOCAL_IRC, // address reported by IRC (deprecated) + LOCAL_HTTP, // address reported by whatismyip.com and similars + LOCAL_MANUAL, // address explicitly specified (-externalip=) + + LOCAL_MAX +}; + +void SetLimited(enum Network net, bool fLimited = true); +bool IsLimited(enum Network net); +bool IsLimited(const CNetAddr& addr); +bool AddLocal(const CService& addr, int nScore = LOCAL_NONE); +bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); +bool SeenLocal(const CService& addr); +bool IsLocal(const CService& addr); +bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); +bool IsReachable(const CNetAddr &addr); +void SetReachable(enum Network net, bool fFlag = true); +CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); + + +enum +{ + MSG_TX = 1, + MSG_BLOCK, +}; + +class CRequestTracker +{ +public: + void (*fn)(void*, CDataStream&); + void* param1; + + explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL) + { + fn = fnIn; + param1 = param1In; + } + + bool IsNull() + { + return fn == NULL; + } +}; + + +/** Thread types */ +enum threadId +{ + THREAD_SOCKETHANDLER, + THREAD_OPENCONNECTIONS, + THREAD_MESSAGEHANDLER, + THREAD_MINER, + THREAD_RPCLISTENER, + THREAD_UPNP, + THREAD_DNSSEED, + THREAD_ADDEDCONNECTIONS, + THREAD_DUMPADDRESS, + THREAD_RPCHANDLER, + + THREAD_MAX +}; + +extern bool fClient; +extern bool fDiscover; +extern bool fUseUPnP; +extern uint64 nLocalServices; +extern uint64 nLocalHostNonce; +extern boost::array vnThreadsRunning; +extern CAddrMan addrman; + +extern std::vector vNodes; +extern CCriticalSection cs_vNodes; +extern std::map mapRelay; +extern std::deque > vRelayExpiration; +extern CCriticalSection cs_mapRelay; +extern std::map mapAlreadyAskedFor; + + + + +class CNodeStats +{ +public: + uint64 nServices; + int64 nLastSend; + int64 nLastRecv; + int64 nTimeConnected; + std::string addrName; + int nVersion; + std::string strSubVer; + bool fInbound; + int64 nReleaseTime; + int nStartingHeight; + int nMisbehavior; +}; + + + + + +/** Information about a peer */ +class CNode +{ +public: + // socket + uint64 nServices; + SOCKET hSocket; + CDataStream vSend; + CDataStream vRecv; + CCriticalSection cs_vSend; + CCriticalSection cs_vRecv; + int64 nLastSend; + int64 nLastRecv; + int64 nLastSendEmpty; + int64 nTimeConnected; + int nHeaderStart; + unsigned int nMessageStart; + CAddress addr; + std::string addrName; + CService addrLocal; + int nVersion; + std::string strSubVer; + bool fOneShot; + bool fClient; + bool fInbound; + bool fNetworkNode; + bool fSuccessfullyConnected; + bool fDisconnect; + CSemaphoreGrant grantOutbound; +protected: + int nRefCount; + + // Denial-of-service detection/prevention + // Key is ip address, value is banned-until-time + static std::map setBanned; + static CCriticalSection cs_setBanned; + int nMisbehavior; + +public: + int64 nReleaseTime; + std::map mapRequests; + CCriticalSection cs_mapRequests; + uint256 hashContinue; + CBlockIndex* pindexLastGetBlocksBegin; + uint256 hashLastGetBlocksEnd; + int nStartingHeight; + + // flood relay + std::vector vAddrToSend; + std::set setAddrKnown; + bool fGetAddr; + std::set setKnown; + + // inventory based relay + mruset setInventoryKnown; + std::vector vInventoryToSend; + CCriticalSection cs_inventory; + std::multimap mapAskFor; + + CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION) + { + nServices = 0; + hSocket = hSocketIn; + nLastSend = 0; + nLastRecv = 0; + nLastSendEmpty = GetTime(); + nTimeConnected = GetTime(); + nHeaderStart = -1; + nMessageStart = -1; + addr = addrIn; + addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn; + nVersion = 0; + strSubVer = ""; + fOneShot = false; + fClient = false; // set by version message + fInbound = fInboundIn; + fNetworkNode = false; + fSuccessfullyConnected = false; + fDisconnect = false; + nRefCount = 0; + nReleaseTime = 0; + hashContinue = 0; + pindexLastGetBlocksBegin = 0; + hashLastGetBlocksEnd = 0; + nStartingHeight = -1; + fGetAddr = false; + nMisbehavior = 0; + setInventoryKnown.max_size(SendBufferSize() / 1000); + + // Be shy and don't send version until we hear + if (!fInbound) + PushVersion(); + } + + ~CNode() + { + if (hSocket != INVALID_SOCKET) + { + closesocket(hSocket); + hSocket = INVALID_SOCKET; + } + } + +private: + CNode(const CNode&); + void operator=(const CNode&); +public: + + + int GetRefCount() + { + return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); + } + + CNode* AddRef(int64 nTimeout=0) + { + if (nTimeout != 0) + nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout); + else + nRefCount++; + return this; + } + + void Release() + { + nRefCount--; + } + + + + void AddAddressKnown(const CAddress& addr) + { + setAddrKnown.insert(addr); + } + + void PushAddress(const CAddress& addr) + { + // Known checking here is only to save space from duplicates. + // SendMessages will filter it again for knowns that were added + // after addresses were pushed. + if (addr.IsValid() && !setAddrKnown.count(addr)) + vAddrToSend.push_back(addr); + } + + + void AddInventoryKnown(const CInv& inv) + { + { + LOCK(cs_inventory); + setInventoryKnown.insert(inv); + } + } + + void PushInventory(const CInv& inv) + { + { + LOCK(cs_inventory); + if (!setInventoryKnown.count(inv)) + vInventoryToSend.push_back(inv); + } + } + + void AskFor(const CInv& inv) + { + // We're using mapAskFor as a priority queue, + // the key is the earliest time the request can be sent + int64& nRequestTime = mapAlreadyAskedFor[inv]; + if (fDebugNet) + printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime); + + // Make sure not to reuse time indexes to keep things in the same order + int64 nNow = (GetTime() - 1) * 1000000; + static int64 nLastTime; + ++nLastTime; + nNow = std::max(nNow, nLastTime); + nLastTime = nNow; + + // Each retry is 2 minutes after the last + nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow); + mapAskFor.insert(std::make_pair(nRequestTime, inv)); + } + + + + void BeginMessage(const char* pszCommand) + { + ENTER_CRITICAL_SECTION(cs_vSend); + if (nHeaderStart != -1) + AbortMessage(); + nHeaderStart = vSend.size(); + vSend << CMessageHeader(pszCommand, 0); + nMessageStart = vSend.size(); + if (fDebug) + printf("sending: %s ", pszCommand); + } + + void AbortMessage() + { + if (nHeaderStart < 0) + return; + vSend.resize(nHeaderStart); + nHeaderStart = -1; + nMessageStart = -1; + LEAVE_CRITICAL_SECTION(cs_vSend); + + if (fDebug) + printf("(aborted)\n"); + } + + void EndMessage() + { + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) + { + printf("dropmessages DROPPING SEND MESSAGE\n"); + AbortMessage(); + return; + } + + if (nHeaderStart < 0) + return; + + // Set the size + unsigned int nSize = vSend.size() - nMessageStart; + memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize)); + + // Set the checksum + uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end()); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum)); + memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum)); + + if (fDebug) { + printf("(%d bytes)\n", nSize); + } + + nHeaderStart = -1; + nMessageStart = -1; + LEAVE_CRITICAL_SECTION(cs_vSend); + } + + void EndMessageAbortIfEmpty() + { + if (nHeaderStart < 0) + return; + int nSize = vSend.size() - nMessageStart; + if (nSize > 0) + EndMessage(); + else + AbortMessage(); + } + + + + void PushVersion(); + + + void PushMessage(const char* pszCommand) + { + try + { + BeginMessage(pszCommand); + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1) + { + try + { + BeginMessage(pszCommand); + vSend << a1; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + + void PushRequest(const char* pszCommand, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + { + LOCK(cs_mapRequests); + mapRequests[hashReply] = CRequestTracker(fn, param1); + } + + PushMessage(pszCommand, hashReply); + } + + template + void PushRequest(const char* pszCommand, const T1& a1, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + { + LOCK(cs_mapRequests); + mapRequests[hashReply] = CRequestTracker(fn, param1); + } + + PushMessage(pszCommand, hashReply, a1); + } + + template + void PushRequest(const char* pszCommand, const T1& a1, const T2& a2, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + { + LOCK(cs_mapRequests); + mapRequests[hashReply] = CRequestTracker(fn, param1); + } + + PushMessage(pszCommand, hashReply, a1, a2); + } + + + + void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd); + bool IsSubscribed(unsigned int nChannel); + void Subscribe(unsigned int nChannel, unsigned int nHops=0); + void CancelSubscribe(unsigned int nChannel); + void CloseSocketDisconnect(); + void Cleanup(); + + + // Denial-of-service detection/prevention + // The idea is to detect peers that are behaving + // badly and disconnect/ban them, but do it in a + // one-coding-mistake-won't-shatter-the-entire-network + // way. + // IMPORTANT: There should be nothing I can give a + // node that it will forward on that will make that + // node's peers drop it. If there is, an attacker + // can isolate a node and/or try to split the network. + // Dropping a node for sending stuff that is invalid + // now but might be valid in a later version is also + // dangerous, because it can cause a network split + // between nodes running old code and nodes running + // new code. + static void ClearBanned(); // needed for unit testing + static bool IsBanned(CNetAddr ip); + bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot + void copyStats(CNodeStats &stats); +}; + + + + + + + + + + +inline void RelayInventory(const CInv& inv) +{ + // Put on lists to offer to the other nodes + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + pnode->PushInventory(inv); + } +} + +template +void RelayMessage(const CInv& inv, const T& a) +{ + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss.reserve(10000); + ss << a; + RelayMessage(inv, ss); +} + +template<> +inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) +{ + { + LOCK(cs_mapRelay); + // Expire old relay messages + while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) + { + mapRelay.erase(vRelayExpiration.front().second); + vRelayExpiration.pop_front(); + } + + // Save original serialized message so newer versions are preserved + mapRelay.insert(std::make_pair(inv, ss)); + vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv)); + } + + RelayInventory(inv); +} + + +#endif diff --git a/src/netbase.cpp b/src/netbase.cpp new file mode 100644 index 0000000..ca39fa5 --- /dev/null +++ b/src/netbase.cpp @@ -0,0 +1,1165 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "netbase.h" +#include "util.h" + +#ifndef WIN32 +#include +#endif + +#include "strlcpy.h" +#include // for to_lower() + +using namespace std; + +// Settings +typedef std::pair proxyType; +static proxyType proxyInfo[NET_MAX]; +static proxyType nameproxyInfo; +int nConnectTimeout = 5000; +bool fNameLookup = false; + +static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; + +enum Network ParseNetwork(std::string net) { + boost::to_lower(net); + if (net == "ipv4") return NET_IPV4; + if (net == "ipv6") return NET_IPV6; + if (net == "tor") return NET_TOR; + if (net == "i2p") return NET_I2P; + return NET_UNROUTABLE; +} + +void SplitHostPort(std::string in, int &portOut, std::string &hostOut) { + size_t colon = in.find_last_of(':'); + // if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator + bool fHaveColon = colon != in.npos; + bool fBracketed = fHaveColon && (in[0]=='[' && in[colon-1]==']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe + bool fMultiColon = fHaveColon && (in.find_last_of(':',colon-1) != in.npos); + if (fHaveColon && (colon==0 || fBracketed || !fMultiColon)) { + char *endp = NULL; + int n = strtol(in.c_str() + colon + 1, &endp, 10); + if (endp && *endp == 0 && n >= 0) { + in = in.substr(0, colon); + if (n > 0 && n < 0x10000) + portOut = n; + } + } + if (in.size()>0 && in[0] == '[' && in[in.size()-1] == ']') + hostOut = in.substr(1, in.size()-2); + else + hostOut = in; +} + +bool static LookupIntern(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup) +{ + vIP.clear(); + + { + CNetAddr addr; + if (addr.SetSpecial(std::string(pszName))) { + vIP.push_back(addr); + return true; + } + } + + struct addrinfo aiHint; + memset(&aiHint, 0, sizeof(struct addrinfo)); + + aiHint.ai_socktype = SOCK_STREAM; + aiHint.ai_protocol = IPPROTO_TCP; +#ifdef WIN32 +# ifdef USE_IPV6 + aiHint.ai_family = AF_UNSPEC; +# else + aiHint.ai_family = AF_INET; +# endif + aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST; +#else +# ifdef USE_IPV6 + aiHint.ai_family = AF_UNSPEC; +# else + aiHint.ai_family = AF_INET; +# endif + aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; +#endif + struct addrinfo *aiRes = NULL; + int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); + if (nErr) + return false; + + struct addrinfo *aiTrav = aiRes; + while (aiTrav != NULL && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions)) + { + if (aiTrav->ai_family == AF_INET) + { + assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in)); + vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr)); + } + +#ifdef USE_IPV6 + if (aiTrav->ai_family == AF_INET6) + { + assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6)); + vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr)); + } +#endif + + aiTrav = aiTrav->ai_next; + } + + freeaddrinfo(aiRes); + + return (vIP.size() > 0); +} + +bool LookupHost(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup) +{ + if (pszName[0] == 0) + return false; + char psz[256]; + char *pszHost = psz; + strlcpy(psz, pszName, sizeof(psz)); + if (psz[0] == '[' && psz[strlen(psz)-1] == ']') + { + pszHost = psz+1; + psz[strlen(psz)-1] = 0; + } + + return LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup); +} + +bool LookupHostNumeric(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions) +{ + return LookupHost(pszName, vIP, nMaxSolutions, false); +} + +bool Lookup(const char *pszName, std::vector& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions) +{ + if (pszName[0] == 0) + return false; + int port = portDefault; + std::string hostname = ""; + SplitHostPort(std::string(pszName), port, hostname); + + std::vector vIP; + bool fRet = LookupIntern(hostname.c_str(), vIP, nMaxSolutions, fAllowLookup); + if (!fRet) + return false; + vAddr.resize(vIP.size()); + for (unsigned int i = 0; i < vIP.size(); i++) + vAddr[i] = CService(vIP[i], port); + return true; +} + +bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup) +{ + std::vector vService; + bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1); + if (!fRet) + return false; + addr = vService[0]; + return true; +} + +bool LookupNumeric(const char *pszName, CService& addr, int portDefault) +{ + return Lookup(pszName, addr, portDefault, false); +} + +bool static Socks4(const CService &addrDest, SOCKET& hSocket) +{ + printf("SOCKS4 connecting %s\n", addrDest.ToString().c_str()); + if (!addrDest.IsIPv4()) + { + closesocket(hSocket); + return error("Proxy destination is not IPv4"); + } + char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; + struct sockaddr_in addr; + socklen_t len = sizeof(addr); + if (!addrDest.GetSockAddr((struct sockaddr*)&addr, &len) || addr.sin_family != AF_INET) + { + closesocket(hSocket); + return error("Cannot get proxy destination address"); + } + memcpy(pszSocks4IP + 2, &addr.sin_port, 2); + memcpy(pszSocks4IP + 4, &addr.sin_addr, 4); + char* pszSocks4 = pszSocks4IP; + int nSize = sizeof(pszSocks4IP); + + int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL); + if (ret != nSize) + { + closesocket(hSocket); + return error("Error sending to proxy"); + } + char pchRet[8]; + if (recv(hSocket, pchRet, 8, 0) != 8) + { + closesocket(hSocket); + return error("Error reading proxy response"); + } + if (pchRet[1] != 0x5a) + { + closesocket(hSocket); + if (pchRet[1] != 0x5b) + printf("ERROR: Proxy returned error %d\n", pchRet[1]); + return false; + } + printf("SOCKS4 connected %s\n", addrDest.ToString().c_str()); + return true; +} + +bool static Socks5(string strDest, int port, SOCKET& hSocket) +{ + printf("SOCKS5 connecting %s\n", strDest.c_str()); + if (strDest.size() > 255) + { + closesocket(hSocket); + return error("Hostname too long"); + } + char pszSocks5Init[] = "\5\1\0"; + char *pszSocks5 = pszSocks5Init; + ssize_t nSize = sizeof(pszSocks5Init) - 1; + + ssize_t ret = send(hSocket, pszSocks5, nSize, MSG_NOSIGNAL); + if (ret != nSize) + { + closesocket(hSocket); + return error("Error sending to proxy"); + } + char pchRet1[2]; + if (recv(hSocket, pchRet1, 2, 0) != 2) + { + closesocket(hSocket); + return error("Error reading proxy response"); + } + if (pchRet1[0] != 0x05 || pchRet1[1] != 0x00) + { + closesocket(hSocket); + return error("Proxy failed to initialize"); + } + string strSocks5("\5\1"); + strSocks5 += '\000'; strSocks5 += '\003'; + strSocks5 += static_cast(std::min((int)strDest.size(), 255)); + strSocks5 += strDest; + strSocks5 += static_cast((port >> 8) & 0xFF); + strSocks5 += static_cast((port >> 0) & 0xFF); + ret = send(hSocket, strSocks5.c_str(), strSocks5.size(), MSG_NOSIGNAL); + if (ret != (ssize_t)strSocks5.size()) + { + closesocket(hSocket); + return error("Error sending to proxy"); + } + char pchRet2[4]; + if (recv(hSocket, pchRet2, 4, 0) != 4) + { + closesocket(hSocket); + return error("Error reading proxy response"); + } + if (pchRet2[0] != 0x05) + { + closesocket(hSocket); + return error("Proxy failed to accept request"); + } + if (pchRet2[1] != 0x00) + { + closesocket(hSocket); + switch (pchRet2[1]) + { + case 0x01: return error("Proxy error: general failure"); + case 0x02: return error("Proxy error: connection not allowed"); + case 0x03: return error("Proxy error: network unreachable"); + case 0x04: return error("Proxy error: host unreachable"); + case 0x05: return error("Proxy error: connection refused"); + case 0x06: return error("Proxy error: TTL expired"); + case 0x07: return error("Proxy error: protocol error"); + case 0x08: return error("Proxy error: address type not supported"); + default: return error("Proxy error: unknown"); + } + } + if (pchRet2[2] != 0x00) + { + closesocket(hSocket); + return error("Error: malformed proxy response"); + } + char pchRet3[256]; + switch (pchRet2[3]) + { + case 0x01: ret = recv(hSocket, pchRet3, 4, 0) != 4; break; + case 0x04: ret = recv(hSocket, pchRet3, 16, 0) != 16; break; + case 0x03: + { + ret = recv(hSocket, pchRet3, 1, 0) != 1; + if (ret) + return error("Error reading from proxy"); + int nRecv = pchRet3[0]; + ret = recv(hSocket, pchRet3, nRecv, 0) != nRecv; + break; + } + default: closesocket(hSocket); return error("Error: malformed proxy response"); + } + if (ret) + { + closesocket(hSocket); + return error("Error reading from proxy"); + } + if (recv(hSocket, pchRet3, 2, 0) != 2) + { + closesocket(hSocket); + return error("Error reading from proxy"); + } + printf("SOCKS5 connected %s\n", strDest.c_str()); + return true; +} + +bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout) +{ + hSocketRet = INVALID_SOCKET; + +#ifdef USE_IPV6 + struct sockaddr_storage sockaddr; +#else + struct sockaddr sockaddr; +#endif + socklen_t len = sizeof(sockaddr); + if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) { + printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str()); + return false; + } + + SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (hSocket == INVALID_SOCKET) + return false; +#ifdef SO_NOSIGPIPE + int set = 1; + setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); +#endif + +#ifdef WIN32 + u_long fNonblock = 1; + if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) +#else + int fFlags = fcntl(hSocket, F_GETFL, 0); + if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1) +#endif + { + closesocket(hSocket); + return false; + } + + if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) + { + // WSAEINVAL is here because some legacy version of winsock uses it + if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL) + { + struct timeval timeout; + timeout.tv_sec = nTimeout / 1000; + timeout.tv_usec = (nTimeout % 1000) * 1000; + + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(hSocket, &fdset); + int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); + if (nRet == 0) + { + printf("connection timeout\n"); + closesocket(hSocket); + return false; + } + if (nRet == SOCKET_ERROR) + { + printf("select() for connection failed: %i\n",WSAGetLastError()); + closesocket(hSocket); + return false; + } + socklen_t nRetSize = sizeof(nRet); +#ifdef WIN32 + if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) +#else + if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) +#endif + { + printf("getsockopt() for connection failed: %i\n",WSAGetLastError()); + closesocket(hSocket); + return false; + } + if (nRet != 0) + { + printf("connect() failed after select(): %s\n",strerror(nRet)); + closesocket(hSocket); + return false; + } + } +#ifdef WIN32 + else if (WSAGetLastError() != WSAEISCONN) +#else + else +#endif + { + printf("connect() failed: %i\n",WSAGetLastError()); + closesocket(hSocket); + return false; + } + } + + // this isn't even strictly necessary + // CNode::ConnectNode immediately turns the socket back to non-blocking + // but we'll turn it back to blocking just in case +#ifdef WIN32 + fNonblock = 0; + if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) +#else + fFlags = fcntl(hSocket, F_GETFL, 0); + if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR) +#endif + { + closesocket(hSocket); + return false; + } + + hSocketRet = hSocket; + 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; i6 && strName.substr(strName.size() - 6, 6) == ".onion") { + std::vector vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str()); + if (vchAddr.size() != 16-sizeof(pchOnionCat)) + return false; + memcpy(ip, pchOnionCat, sizeof(pchOnionCat)); + for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++) + ip[i + sizeof(pchOnionCat)] = vchAddr[i]; + return true; + } + if (strName.size()>11 && strName.substr(strName.size() - 11, 11) == ".oc.b32.i2p") { + std::vector vchAddr = DecodeBase32(strName.substr(0, strName.size() - 11).c_str()); + if (vchAddr.size() != 16-sizeof(pchGarliCat)) + return false; + memcpy(ip, pchOnionCat, sizeof(pchGarliCat)); + for (unsigned int i=0; i<16-sizeof(pchGarliCat); i++) + ip[i + sizeof(pchGarliCat)] = vchAddr[i]; + return true; + } + return false; +} + +CNetAddr::CNetAddr() +{ + Init(); +} + +CNetAddr::CNetAddr(const struct in_addr& ipv4Addr) +{ + memcpy(ip, pchIPv4, 12); + memcpy(ip+12, &ipv4Addr, 4); +} + +#ifdef USE_IPV6 +CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr) +{ + memcpy(ip, &ipv6Addr, 16); +} +#endif + +CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup) +{ + Init(); + std::vector vIP; + if (LookupHost(pszIp, vIP, 1, fAllowLookup)) + *this = vIP[0]; +} + +CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup) +{ + Init(); + std::vector vIP; + if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup)) + *this = vIP[0]; +} + +int CNetAddr::GetByte(int n) const +{ + return ip[15-n]; +} + +bool CNetAddr::IsIPv4() const +{ + return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0); +} + +bool CNetAddr::IsIPv6() const +{ + return (!IsIPv4() && !IsTor() && !IsI2P()); +} + +bool CNetAddr::IsRFC1918() const +{ + return IsIPv4() && ( + GetByte(3) == 10 || + (GetByte(3) == 192 && GetByte(2) == 168) || + (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31))); +} + +bool CNetAddr::IsRFC3927() const +{ + return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254); +} + +bool CNetAddr::IsRFC3849() const +{ + return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8; +} + +bool CNetAddr::IsRFC3964() const +{ + return (GetByte(15) == 0x20 && GetByte(14) == 0x02); +} + +bool CNetAddr::IsRFC6052() const +{ + static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0}; + return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0); +} + +bool CNetAddr::IsRFC4380() const +{ + return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0); +} + +bool CNetAddr::IsRFC4862() const +{ + static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0}; + return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0); +} + +bool CNetAddr::IsRFC4193() const +{ + return ((GetByte(15) & 0xFE) == 0xFC); +} + +bool CNetAddr::IsRFC6145() const +{ + static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0}; + return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0); +} + +bool CNetAddr::IsRFC4843() const +{ + return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10); +} + +bool CNetAddr::IsTor() const +{ + return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0); +} + +bool CNetAddr::IsI2P() const +{ + return (memcmp(ip, pchGarliCat, sizeof(pchGarliCat)) == 0); +} + +bool CNetAddr::IsLocal() const +{ + // IPv4 loopback + if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0)) + return true; + + // IPv6 loopback (::1/128) + static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + if (memcmp(ip, pchLocal, 16) == 0) + return true; + + return false; +} + +bool CNetAddr::IsMulticast() const +{ + return (IsIPv4() && (GetByte(3) & 0xF0) == 0xE0) + || (GetByte(15) == 0xFF); +} + +bool CNetAddr::IsValid() const +{ + // Clean up 3-byte shifted addresses caused by garbage in size field + // of addr messages from versions before 0.2.9 checksum. + // Two consecutive addr messages look like this: + // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... + // so if the first length field is garbled, it reads the second batch + // of addr misaligned by 3 bytes. + if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0) + return false; + + // unspecified IPv6 address (::/128) + unsigned char ipNone[16] = {}; + if (memcmp(ip, ipNone, 16) == 0) + return false; + + // documentation IPv6 address + if (IsRFC3849()) + return false; + + if (IsIPv4()) + { + // INADDR_NONE + uint32_t ipNone = INADDR_NONE; + if (memcmp(ip+12, &ipNone, 4) == 0) + return false; + + // 0 + ipNone = 0; + if (memcmp(ip+12, &ipNone, 4) == 0) + return false; + } + + return true; +} + +bool CNetAddr::IsRoutable() const +{ + return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || (IsRFC4193() && !IsTor() && !IsI2P()) || IsRFC4843() || IsLocal()); +} + +enum Network CNetAddr::GetNetwork() const +{ + if (!IsRoutable()) + return NET_UNROUTABLE; + + if (IsIPv4()) + return NET_IPV4; + + if (IsTor()) + return NET_TOR; + + if (IsI2P()) + return NET_I2P; + + return NET_IPV6; +} + +std::string CNetAddr::ToStringIP() const +{ + if (IsTor()) + return EncodeBase32(&ip[6], 10) + ".onion"; + if (IsI2P()) + return EncodeBase32(&ip[6], 10) + ".oc.b32.i2p"; + CService serv(*this, 0); +#ifdef USE_IPV6 + struct sockaddr_storage sockaddr; +#else + struct sockaddr sockaddr; +#endif + socklen_t socklen = sizeof(sockaddr); + if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) { + char name[1025] = ""; + if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST)) + return std::string(name); + } + if (IsIPv4()) + return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); + else + return strprintf("%x:%x:%x:%x:%x:%x:%x:%x", + GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12), + GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8), + GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4), + GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0)); +} + +std::string CNetAddr::ToString() const +{ + return ToStringIP(); +} + +bool operator==(const CNetAddr& a, const CNetAddr& b) +{ + return (memcmp(a.ip, b.ip, 16) == 0); +} + +bool operator!=(const CNetAddr& a, const CNetAddr& b) +{ + return (memcmp(a.ip, b.ip, 16) != 0); +} + +bool operator<(const CNetAddr& a, const CNetAddr& b) +{ + return (memcmp(a.ip, b.ip, 16) < 0); +} + +bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const +{ + if (!IsIPv4()) + return false; + memcpy(pipv4Addr, ip+12, 4); + return true; +} + +#ifdef USE_IPV6 +bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const +{ + memcpy(pipv6Addr, ip, 16); + return true; +} +#endif + +// get canonical identifier of an address' group +// no two connections will be attempted to addresses with the same group +std::vector CNetAddr::GetGroup() const +{ + std::vector vchRet; + int nClass = NET_IPV6; + int nStartByte = 0; + int nBits = 16; + + // all local addresses belong to the same group + if (IsLocal()) + { + nClass = 255; + nBits = 0; + } + + // all unroutable addresses belong to the same group + if (!IsRoutable()) + { + nClass = NET_UNROUTABLE; + nBits = 0; + } + // for IPv4 addresses, '1' + the 16 higher-order bits of the IP + // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix + else if (IsIPv4() || IsRFC6145() || IsRFC6052()) + { + nClass = NET_IPV4; + nStartByte = 12; + } + // for 6to4 tunneled addresses, use the encapsulated IPv4 address + else if (IsRFC3964()) + { + nClass = NET_IPV4; + nStartByte = 2; + } + // for Teredo-tunneled IPv6 addresses, use the encapsulated IPv4 address + else if (IsRFC4380()) + { + vchRet.push_back(NET_IPV4); + vchRet.push_back(GetByte(3) ^ 0xFF); + vchRet.push_back(GetByte(2) ^ 0xFF); + return vchRet; + } + else if (IsTor()) + { + nClass = NET_TOR; + nStartByte = 6; + nBits = 4; + } + else if (IsI2P()) + { + nClass = NET_I2P; + nStartByte = 6; + nBits = 4; + } + // for he.net, use /36 groups + else if (GetByte(15) == 0x20 && GetByte(14) == 0x11 && GetByte(13) == 0x04 && GetByte(12) == 0x70) + nBits = 36; + // for the rest of the IPv6 network, use /32 groups + else + nBits = 32; + + vchRet.push_back(nClass); + while (nBits >= 8) + { + vchRet.push_back(GetByte(15 - nStartByte)); + nStartByte++; + nBits -= 8; + } + if (nBits > 0) + vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1)); + + return vchRet; +} + +uint64 CNetAddr::GetHash() const +{ + uint256 hash = Hash(&ip[0], &ip[16]); + uint64 nRet; + memcpy(&nRet, &hash, sizeof(nRet)); + return nRet; +} + +void CNetAddr::print() const +{ + printf("CNetAddr(%s)\n", ToString().c_str()); +} + +// private extensions to enum Network, only returned by GetExtNetwork, +// and only used in GetReachabilityFrom +static const int NET_UNKNOWN = NET_MAX + 0; +static const int NET_TEREDO = NET_MAX + 1; +int static GetExtNetwork(const CNetAddr *addr) +{ + if (addr == NULL) + return NET_UNKNOWN; + if (addr->IsRFC4380()) + return NET_TEREDO; + return addr->GetNetwork(); +} + +/** Calculates a metric for how reachable (*this) is from a given partner */ +int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const +{ + enum Reachability { + REACH_UNREACHABLE, + REACH_DEFAULT, + REACH_TEREDO, + REACH_IPV6_WEAK, + REACH_IPV4, + REACH_IPV6_STRONG, + REACH_PRIVATE + }; + + if (!IsRoutable()) + return REACH_UNREACHABLE; + + int ourNet = GetExtNetwork(this); + int theirNet = GetExtNetwork(paddrPartner); + bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145(); + + switch(theirNet) { + case NET_IPV4: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_IPV4: return REACH_IPV4; + } + case NET_IPV6: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_TEREDO: return REACH_TEREDO; + case NET_IPV4: return REACH_IPV4; + case NET_IPV6: return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunneled + } + case NET_TOR: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well + case NET_TOR: return REACH_PRIVATE; + } + case NET_I2P: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_I2P: return REACH_PRIVATE; + } + case NET_TEREDO: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_TEREDO: return REACH_TEREDO; + case NET_IPV6: return REACH_IPV6_WEAK; + case NET_IPV4: return REACH_IPV4; + } + case NET_UNKNOWN: + case NET_UNROUTABLE: + default: + switch(ourNet) { + default: return REACH_DEFAULT; + case NET_TEREDO: return REACH_TEREDO; + case NET_IPV6: return REACH_IPV6_WEAK; + case NET_IPV4: return REACH_IPV4; + case NET_I2P: return REACH_PRIVATE; // assume connections from unroutable addresses are + case NET_TOR: return REACH_PRIVATE; // either from Tor/I2P, or don't care about our address + } + } +} + +void CService::Init() +{ + port = 0; +} + +CService::CService() +{ + Init(); +} + +CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn) +{ +} + +CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn) +{ +} + +#ifdef USE_IPV6 +CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn) +{ +} +#endif + +CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port)) +{ + assert(addr.sin_family == AF_INET); +} + +#ifdef USE_IPV6 +CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port)) +{ + assert(addr.sin6_family == AF_INET6); +} +#endif + +bool CService::SetSockAddr(const struct sockaddr *paddr) +{ + switch (paddr->sa_family) { + case AF_INET: + *this = CService(*(const struct sockaddr_in*)paddr); + return true; +#ifdef USE_IPV6 + case AF_INET6: + *this = CService(*(const struct sockaddr_in6*)paddr); + return true; +#endif + default: + return false; + } +} + +CService::CService(const char *pszIpPort, bool fAllowLookup) +{ + Init(); + CService ip; + if (Lookup(pszIpPort, ip, 0, fAllowLookup)) + *this = ip; +} + +CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup) +{ + Init(); + CService ip; + if (Lookup(pszIpPort, ip, portDefault, fAllowLookup)) + *this = ip; +} + +CService::CService(const std::string &strIpPort, bool fAllowLookup) +{ + Init(); + CService ip; + if (Lookup(strIpPort.c_str(), ip, 0, fAllowLookup)) + *this = ip; +} + +CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup) +{ + Init(); + CService ip; + if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup)) + *this = ip; +} + +unsigned short CService::GetPort() const +{ + return port; +} + +bool operator==(const CService& a, const CService& b) +{ + return (CNetAddr)a == (CNetAddr)b && a.port == b.port; +} + +bool operator!=(const CService& a, const CService& b) +{ + return (CNetAddr)a != (CNetAddr)b || a.port != b.port; +} + +bool operator<(const CService& a, const CService& b) +{ + return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port); +} + +bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const +{ + if (IsIPv4()) { + if (*addrlen < (socklen_t)sizeof(struct sockaddr_in)) + return false; + *addrlen = sizeof(struct sockaddr_in); + struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr; + memset(paddrin, 0, *addrlen); + if (!GetInAddr(&paddrin->sin_addr)) + return false; + paddrin->sin_family = AF_INET; + paddrin->sin_port = htons(port); + return true; + } +#ifdef USE_IPV6 + if (IsIPv6()) { + if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6)) + return false; + *addrlen = sizeof(struct sockaddr_in6); + struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr; + memset(paddrin6, 0, *addrlen); + if (!GetIn6Addr(&paddrin6->sin6_addr)) + return false; + paddrin6->sin6_family = AF_INET6; + paddrin6->sin6_port = htons(port); + return true; + } +#endif + return false; +} + +std::vector CService::GetKey() const +{ + std::vector vKey; + vKey.resize(18); + memcpy(&vKey[0], ip, 16); + vKey[16] = port / 0x100; + vKey[17] = port & 0x0FF; + return vKey; +} + +std::string CService::ToStringPort() const +{ + return strprintf("%i", port); +} + +std::string CService::ToStringIPPort() const +{ + if (IsIPv4() || IsTor() || IsI2P()) { + return ToStringIP() + ":" + ToStringPort(); + } else { + return "[" + ToStringIP() + "]:" + ToStringPort(); + } +} + +std::string CService::ToString() const +{ + return ToStringIPPort(); +} + +void CService::print() const +{ + printf("CService(%s)\n", ToString().c_str()); +} + +void CService::SetPort(unsigned short portIn) +{ + port = portIn; +} diff --git a/src/netbase.h b/src/netbase.h new file mode 100644 index 0000000..f23e433 --- /dev/null +++ b/src/netbase.h @@ -0,0 +1,153 @@ +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_NETBASE_H +#define BITCOIN_NETBASE_H + +#include +#include + +#include "serialize.h" +#include "compat.h" + +extern int nConnectTimeout; + +#ifdef WIN32 +// In MSVC, this is defined as a macro, undefine it to prevent a compile and link error +#undef SetPort +#endif + +enum Network +{ + NET_UNROUTABLE, + NET_IPV4, + NET_IPV6, + NET_TOR, + NET_I2P, + + NET_MAX, +}; + +extern int nConnectTimeout; +extern bool fNameLookup; + +/** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */ +class CNetAddr +{ + protected: + unsigned char ip[16]; // in network byte order + + public: + CNetAddr(); + CNetAddr(const struct in_addr& ipv4Addr); + explicit CNetAddr(const char *pszIp, bool fAllowLookup = false); + explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false); + void Init(); + void SetIP(const CNetAddr& ip); + bool SetSpecial(const std::string &strName); // for Tor and I2P addresses + bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) + bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor/I2P) + bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) + bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32) + bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16) + bool IsRFC3964() const; // IPv6 6to4 tunneling (2002::/16) + bool IsRFC4193() const; // IPv6 unique local (FC00::/15) + bool IsRFC4380() const; // IPv6 Teredo tunneling (2001::/32) + bool IsRFC4843() const; // IPv6 ORCHID (2001:10::/28) + bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64) + bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96) + bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) + bool IsTor() const; + bool IsI2P() const; + bool IsLocal() const; + bool IsRoutable() const; + bool IsValid() const; + bool IsMulticast() const; + enum Network GetNetwork() const; + std::string ToString() const; + std::string ToStringIP() const; + int GetByte(int n) const; + uint64 GetHash() const; + bool GetInAddr(struct in_addr* pipv4Addr) const; + std::vector GetGroup() const; + int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const; + void print() const; + +#ifdef USE_IPV6 + CNetAddr(const struct in6_addr& pipv6Addr); + bool GetIn6Addr(struct in6_addr* pipv6Addr) const; +#endif + + friend bool operator==(const CNetAddr& a, const CNetAddr& b); + friend bool operator!=(const CNetAddr& a, const CNetAddr& b); + friend bool operator<(const CNetAddr& a, const CNetAddr& b); + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(ip)); + ) +}; + +/** A combination of a network address (CNetAddr) and a (TCP) port */ +class CService : public CNetAddr +{ + protected: + unsigned short port; // host order + + public: + CService(); + CService(const CNetAddr& ip, unsigned short port); + CService(const struct in_addr& ipv4Addr, unsigned short port); + CService(const struct sockaddr_in& addr); + explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false); + explicit CService(const char *pszIpPort, bool fAllowLookup = false); + explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false); + explicit CService(const std::string& strIpPort, bool fAllowLookup = false); + void Init(); + void SetPort(unsigned short portIn); + unsigned short GetPort() const; + bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const; + bool SetSockAddr(const struct sockaddr* paddr); + friend bool operator==(const CService& a, const CService& b); + friend bool operator!=(const CService& a, const CService& b); + friend bool operator<(const CService& a, const CService& b); + std::vector GetKey() const; + std::string ToString() const; + std::string ToStringPort() const; + std::string ToStringIPPort() const; + void print() const; + +#ifdef USE_IPV6 + CService(const struct in6_addr& ipv6Addr, unsigned short port); + CService(const struct sockaddr_in6& addr); +#endif + + IMPLEMENT_SERIALIZE + ( + CService* pthis = const_cast(this); + READWRITE(FLATDATA(ip)); + unsigned short portN = htons(port); + READWRITE(portN); + if (fRead) + pthis->port = ntohs(portN); + ) +}; + +enum Network ParseNetwork(std::string net); +void SplitHostPort(std::string in, int &portOut, std::string &hostOut); +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& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true); +bool LookupHostNumeric(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions = 0); +bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true); +bool Lookup(const char *pszName, std::vector& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0); +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); + +#endif diff --git a/src/noui.cpp b/src/noui.cpp new file mode 100644 index 0000000..81183cc --- /dev/null +++ b/src/noui.cpp @@ -0,0 +1,30 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "ui_interface.h" +#include "init.h" +#include "bitcoinrpc.h" + +#include + +static int noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) +{ + printf("%s: %s\n", caption.c_str(), message.c_str()); + fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); + return 4; +} + +static bool noui_ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption) +{ + return true; +} + +void noui_connect() +{ + // Connect bitcoind signal handlers + uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox); + uiInterface.ThreadSafeAskFee.connect(noui_ThreadSafeAskFee); +} diff --git a/src/protocol.cpp b/src/protocol.cpp new file mode 100644 index 0000000..9c0c1b9 --- /dev/null +++ b/src/protocol.cpp @@ -0,0 +1,152 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "protocol.h" +#include "util.h" +#include "netbase.h" + +#ifndef WIN32 +# include +#endif + +static const char* ppszTypeName[] = +{ + "ERROR", + "tx", + "block", +}; + +CMessageHeader::CMessageHeader() +{ + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + memset(pchCommand, 0, sizeof(pchCommand)); + pchCommand[1] = 1; + nMessageSize = -1; + nChecksum = 0; +} + +CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) +{ + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + strncpy(pchCommand, pszCommand, COMMAND_SIZE); + nMessageSize = nMessageSizeIn; + nChecksum = 0; +} + +std::string CMessageHeader::GetCommand() const +{ + if (pchCommand[COMMAND_SIZE-1] == 0) + return std::string(pchCommand, pchCommand + strlen(pchCommand)); + else + return std::string(pchCommand, pchCommand + COMMAND_SIZE); +} + +bool CMessageHeader::IsValid() const +{ + // Check start string + if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) + return false; + + // Check the command string for errors + for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) + { + if (*p1 == 0) + { + // Must be all zeros after the first zero + for (; p1 < pchCommand + COMMAND_SIZE; p1++) + if (*p1 != 0) + return false; + } + else if (*p1 < ' ' || *p1 > 0x7E) + return false; + } + + // Message size + if (nMessageSize > MAX_SIZE) + { + printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize); + return false; + } + + return true; +} + + + +CAddress::CAddress() : CService() +{ + Init(); +} + +CAddress::CAddress(CService ipIn, uint64 nServicesIn) : CService(ipIn) +{ + Init(); + nServices = nServicesIn; +} + +void CAddress::Init() +{ + nServices = NODE_NETWORK; + nTime = 100000000; + nLastTry = 0; +} + +CInv::CInv() +{ + type = 0; + hash = 0; +} + +CInv::CInv(int typeIn, const uint256& hashIn) +{ + type = typeIn; + hash = hashIn; +} + +CInv::CInv(const std::string& strType, const uint256& hashIn) +{ + unsigned int i; + for (i = 1; i < ARRAYLEN(ppszTypeName); i++) + { + if (strType == ppszTypeName[i]) + { + type = i; + break; + } + } + if (i == ARRAYLEN(ppszTypeName)) + throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); + hash = hashIn; +} + +bool operator<(const CInv& a, const CInv& b) +{ + return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); +} + +bool CInv::IsKnownType() const +{ + return (type >= 1 && type < (int)ARRAYLEN(ppszTypeName)); +} + +const char* CInv::GetCommand() const +{ + if (!IsKnownType()) + throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type)); + return ppszTypeName[type]; +} + +std::string CInv::ToString() const +{ + return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str()); +} + +void CInv::print() const +{ + printf("CInv(%s)\n", ToString().c_str()); +} + diff --git a/src/protocol.h b/src/protocol.h new file mode 100644 index 0000000..39b682f --- /dev/null +++ b/src/protocol.h @@ -0,0 +1,139 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef __cplusplus +# error This header can only be compiled as C++. +#endif + +#ifndef __INCLUDED_PROTOCOL_H__ +#define __INCLUDED_PROTOCOL_H__ + +#include "serialize.h" +#include "netbase.h" +#include +#include "uint256.h" + +extern bool fTestNet; +static inline unsigned short GetDefaultPort(const bool testnet = fTestNet) +{ + return testnet ? 17950 : 47950; +} + + +extern unsigned char pchMessageStart[4]; + +/** Message header. + * (4) message start. + * (12) command. + * (4) size. + * (4) checksum. + */ +class CMessageHeader +{ + public: + CMessageHeader(); + CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn); + + std::string GetCommand() const; + bool IsValid() const; + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + READWRITE(nChecksum); + ) + + // TODO: make private (improves encapsulation) + public: + enum { + MESSAGE_START_SIZE=sizeof(::pchMessageStart), + COMMAND_SIZE=12, + MESSAGE_SIZE_SIZE=sizeof(int), + CHECKSUM_SIZE=sizeof(int), + + MESSAGE_SIZE_OFFSET=MESSAGE_START_SIZE+COMMAND_SIZE, + CHECKSUM_OFFSET=MESSAGE_SIZE_OFFSET+MESSAGE_SIZE_SIZE + }; + char pchMessageStart[MESSAGE_START_SIZE]; + char pchCommand[COMMAND_SIZE]; + unsigned int nMessageSize; + unsigned int nChecksum; +}; + +/** nServices flags */ +enum +{ + NODE_NETWORK = (1 << 0), +}; + +/** A CService with information about it as peer */ +class CAddress : public CService +{ + public: + CAddress(); + explicit CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK); + + void Init(); + + IMPLEMENT_SERIALIZE + ( + CAddress* pthis = const_cast(this); + CService* pip = (CService*)pthis; + if (fRead) + pthis->Init(); + if (nType & SER_DISK) + READWRITE(nVersion); + if ((nType & SER_DISK) || + (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) + READWRITE(nTime); + READWRITE(nServices); + READWRITE(*pip); + ) + + void print() const; + + // TODO: make private (improves encapsulation) + public: + uint64 nServices; + + // disk and network only + unsigned int nTime; + + // memory only + int64 nLastTry; +}; + +/** inv message data */ +class CInv +{ + public: + CInv(); + CInv(int typeIn, const uint256& hashIn); + CInv(const std::string& strType, const uint256& hashIn); + + IMPLEMENT_SERIALIZE + ( + READWRITE(type); + READWRITE(hash); + ) + + friend bool operator<(const CInv& a, const CInv& b); + + bool IsKnownType() const; + const char* GetCommand() const; + std::string ToString() const; + void print() const; + + // TODO: make private (improves encapsulation) + public: + int type; + uint256 hash; +}; + +#endif // __INCLUDED_PROTOCOL_H__ diff --git a/src/qt/aboutdialog.cpp b/src/qt/aboutdialog.cpp new file mode 100644 index 0000000..0b98bef --- /dev/null +++ b/src/qt/aboutdialog.cpp @@ -0,0 +1,30 @@ +#include "aboutdialog.h" +#include "ui_aboutdialog.h" +#include "clientmodel.h" + +#include "version.h" + +AboutDialog::AboutDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutDialog) +{ + ui->setupUi(this); +} + +void AboutDialog::setModel(ClientModel *model) +{ + if(model) + { + ui->versionLabel->setText(model->formatFullVersion()); + } +} + +AboutDialog::~AboutDialog() +{ + delete ui; +} + +void AboutDialog::on_buttonBox_accepted() +{ + close(); +} diff --git a/src/qt/aboutdialog.h b/src/qt/aboutdialog.h new file mode 100644 index 0000000..2ed9e9e --- /dev/null +++ b/src/qt/aboutdialog.h @@ -0,0 +1,28 @@ +#ifndef ABOUTDIALOG_H +#define ABOUTDIALOG_H + +#include + +namespace Ui { + class AboutDialog; +} +class ClientModel; + +/** "About" dialog box */ +class AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent = 0); + ~AboutDialog(); + + void setModel(ClientModel *model); +private: + Ui::AboutDialog *ui; + +private slots: + void on_buttonBox_accepted(); +}; + +#endif // ABOUTDIALOG_H diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp new file mode 100644 index 0000000..8a74a47 --- /dev/null +++ b/src/qt/addressbookpage.cpp @@ -0,0 +1,374 @@ +#include "addressbookpage.h" +#include "ui_addressbookpage.h" + +#include "addresstablemodel.h" +#include "optionsmodel.h" +#include "bitcoingui.h" +#include "editaddressdialog.h" +#include "csvmodelwriter.h" +#include "guiutil.h" + +#include +#include +#include +#include + +#ifdef USE_QRCODE +#include "qrcodedialog.h" +#endif + +AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : + QDialog(parent), + ui(new Ui::AddressBookPage), + model(0), + optionsModel(0), + mode(mode), + tab(tab) +{ + ui->setupUi(this); + +#ifdef Q_WS_MAC // Icons on push buttons are very uncommon on Mac + ui->newAddressButton->setIcon(QIcon()); + ui->copyToClipboard->setIcon(QIcon()); + ui->deleteButton->setIcon(QIcon()); +#endif + +#ifndef USE_QRCODE + ui->showQRCode->setVisible(false); +#endif + + switch(mode) + { + case ForSending: + connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept())); + ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->tableView->setFocus(); + break; + case ForEditing: + ui->buttonBox->setVisible(false); + break; + } + switch(tab) + { + case SendingTab: + ui->labelExplanation->setVisible(false); + ui->deleteButton->setVisible(true); + ui->signMessage->setVisible(false); + break; + case ReceivingTab: + ui->deleteButton->setVisible(false); + ui->signMessage->setVisible(true); + break; + } + + // Context menu actions + QAction *copyLabelAction = new QAction(tr("Copy &Label"), this); + QAction *copyAddressAction = new QAction(ui->copyToClipboard->text(), this); + QAction *editAction = new QAction(tr("&Edit"), this); + QAction *showQRCodeAction = new QAction(ui->showQRCode->text(), this); + QAction *signMessageAction = new QAction(ui->signMessage->text(), this); + QAction *verifyMessageAction = new QAction(ui->verifyMessage->text(), this); + deleteAction = new QAction(ui->deleteButton->text(), this); + + // Build context menu + contextMenu = new QMenu(); + contextMenu->addAction(copyAddressAction); + contextMenu->addAction(copyLabelAction); + contextMenu->addAction(editAction); + if(tab == SendingTab) + contextMenu->addAction(deleteAction); + contextMenu->addSeparator(); + contextMenu->addAction(showQRCodeAction); + if(tab == ReceivingTab) + contextMenu->addAction(signMessageAction); + else if(tab == SendingTab) + contextMenu->addAction(verifyMessageAction); + + // Connect signals for context menu actions + connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyToClipboard_clicked())); + connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction())); + connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction())); + connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteButton_clicked())); + connect(showQRCodeAction, SIGNAL(triggered()), this, SLOT(on_showQRCode_clicked())); + connect(signMessageAction, SIGNAL(triggered()), this, SLOT(on_signMessage_clicked())); + connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(on_verifyMessage_clicked())); + + connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); + + // Pass through accept action from button box + connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); +} + +AddressBookPage::~AddressBookPage() +{ + delete ui; +} + +void AddressBookPage::setModel(AddressTableModel *model) +{ + this->model = model; + if(!model) + return; + + proxyModel = new QSortFilterProxyModel(this); + proxyModel->setSourceModel(model); + proxyModel->setDynamicSortFilter(true); + proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + switch(tab) + { + case ReceivingTab: + // Receive filter + proxyModel->setFilterRole(AddressTableModel::TypeRole); + proxyModel->setFilterFixedString(AddressTableModel::Receive); + break; + case SendingTab: + // Send filter + proxyModel->setFilterRole(AddressTableModel::TypeRole); + proxyModel->setFilterFixedString(AddressTableModel::Send); + break; + } + ui->tableView->setModel(proxyModel); + ui->tableView->sortByColumn(0, Qt::AscendingOrder); + + // Set column widths + ui->tableView->horizontalHeader()->resizeSection( + AddressTableModel::Address, 320); + ui->tableView->horizontalHeader()->setResizeMode( + AddressTableModel::Label, QHeaderView::Stretch); + + connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + this, SLOT(selectionChanged())); + + // Select row for newly created address + connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(selectNewAddress(QModelIndex,int,int))); + + selectionChanged(); +} + +void AddressBookPage::setOptionsModel(OptionsModel *optionsModel) +{ + this->optionsModel = optionsModel; +} + +void AddressBookPage::on_copyToClipboard_clicked() +{ + GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address); +} + +void AddressBookPage::onCopyLabelAction() +{ + GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Label); +} + +void AddressBookPage::onEditAction() +{ + if(!ui->tableView->selectionModel()) + return; + QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows(); + if(indexes.isEmpty()) + return; + + EditAddressDialog dlg( + tab == SendingTab ? + EditAddressDialog::EditSendingAddress : + EditAddressDialog::EditReceivingAddress); + dlg.setModel(model); + QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0)); + dlg.loadRow(origIndex.row()); + dlg.exec(); +} + +void AddressBookPage::on_signMessage_clicked() +{ + QTableView *table = ui->tableView; + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + QString addr; + + foreach (QModelIndex index, indexes) + { + QVariant address = index.data(); + addr = address.toString(); + } + + emit signMessage(addr); +} + +void AddressBookPage::on_verifyMessage_clicked() +{ + QTableView *table = ui->tableView; + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + QString addr; + + foreach (QModelIndex index, indexes) + { + QVariant address = index.data(); + addr = address.toString(); + } + + emit verifyMessage(addr); +} + +void AddressBookPage::on_newAddressButton_clicked() +{ + if(!model) + return; + EditAddressDialog dlg( + tab == SendingTab ? + EditAddressDialog::NewSendingAddress : + EditAddressDialog::NewReceivingAddress, this); + dlg.setModel(model); + if(dlg.exec()) + { + newAddressToSelect = dlg.getAddress(); + } +} + +void AddressBookPage::on_deleteButton_clicked() +{ + QTableView *table = ui->tableView; + if(!table->selectionModel()) + return; + QModelIndexList indexes = table->selectionModel()->selectedRows(); + if(!indexes.isEmpty()) + { + table->model()->removeRow(indexes.at(0).row()); + } +} + +void AddressBookPage::selectionChanged() +{ + // Set button states based on selected tab and selection + QTableView *table = ui->tableView; + if(!table->selectionModel()) + return; + + if(table->selectionModel()->hasSelection()) + { + switch(tab) + { + case SendingTab: + // In sending tab, allow deletion of selection + ui->deleteButton->setEnabled(true); + ui->deleteButton->setVisible(true); + deleteAction->setEnabled(true); + ui->signMessage->setEnabled(false); + ui->signMessage->setVisible(false); + ui->verifyMessage->setEnabled(true); + ui->verifyMessage->setVisible(true); + break; + case ReceivingTab: + // Deleting receiving addresses, however, is not allowed + ui->deleteButton->setEnabled(false); + ui->deleteButton->setVisible(false); + deleteAction->setEnabled(false); + ui->signMessage->setEnabled(true); + ui->signMessage->setVisible(true); + ui->verifyMessage->setEnabled(false); + ui->verifyMessage->setVisible(false); + break; + } + ui->copyToClipboard->setEnabled(true); + ui->showQRCode->setEnabled(true); + } + else + { + ui->deleteButton->setEnabled(false); + ui->showQRCode->setEnabled(false); + ui->copyToClipboard->setEnabled(false); + ui->signMessage->setEnabled(false); + ui->verifyMessage->setEnabled(false); + } +} + +void AddressBookPage::done(int retval) +{ + QTableView *table = ui->tableView; + if(!table->selectionModel() || !table->model()) + return; + // When this is a tab/widget and not a model dialog, ignore "done" + if(mode == ForEditing) + return; + + // Figure out which address was selected, and return it + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + + foreach (QModelIndex index, indexes) + { + QVariant address = table->model()->data(index); + returnValue = address.toString(); + } + + if(returnValue.isEmpty()) + { + // If no address entry selected, return rejected + retval = Rejected; + } + + QDialog::done(retval); +} + +void AddressBookPage::exportClicked() +{ + // CSV is currently the only supported format + QString filename = GUIUtil::getSaveFileName( + this, + tr("Export Address Book Data"), QString(), + tr("Comma separated file (*.csv)")); + + if (filename.isNull()) return; + + CSVModelWriter writer(filename); + + // name, column, role + writer.setModel(proxyModel); + writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole); + writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole); + + if(!writer.write()) + { + QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename), + QMessageBox::Abort, QMessageBox::Abort); + } +} + +void AddressBookPage::on_showQRCode_clicked() +{ +#ifdef USE_QRCODE + QTableView *table = ui->tableView; + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + + foreach (QModelIndex index, indexes) + { + QString address = index.data().toString(), label = index.sibling(index.row(), 0).data(Qt::EditRole).toString(); + + QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this); + if(optionsModel) + dialog->setModel(optionsModel); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + } +#endif +} + +void AddressBookPage::contextualMenu(const QPoint &point) +{ + QModelIndex index = ui->tableView->indexAt(point); + if(index.isValid()) + { + contextMenu->exec(QCursor::pos()); + } +} + +void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int end) +{ + QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent)); + if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect)) + { + // Select row of newly created address, once + ui->tableView->setFocus(); + ui->tableView->selectRow(idx.row()); + newAddressToSelect.clear(); + } +} diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h new file mode 100644 index 0000000..df87486 --- /dev/null +++ b/src/qt/addressbookpage.h @@ -0,0 +1,85 @@ +#ifndef ADDRESSBOOKPAGE_H +#define ADDRESSBOOKPAGE_H + +#include + +namespace Ui { + class AddressBookPage; +} +class AddressTableModel; +class OptionsModel; + +QT_BEGIN_NAMESPACE +class QTableView; +class QItemSelection; +class QSortFilterProxyModel; +class QMenu; +class QModelIndex; +QT_END_NAMESPACE + +/** Widget that shows a list of sending or receiving addresses. + */ +class AddressBookPage : public QDialog +{ + Q_OBJECT + +public: + enum Tabs { + SendingTab = 0, + ReceivingTab = 1 + }; + + enum Mode { + ForSending, /**< Open address book to pick address for sending */ + ForEditing /**< Open address book for editing */ + }; + + explicit AddressBookPage(Mode mode, Tabs tab, QWidget *parent = 0); + ~AddressBookPage(); + + void setModel(AddressTableModel *model); + void setOptionsModel(OptionsModel *optionsModel); + const QString &getReturnValue() const { return returnValue; } + +public slots: + void done(int retval); + void exportClicked(); + +private: + Ui::AddressBookPage *ui; + AddressTableModel *model; + OptionsModel *optionsModel; + Mode mode; + Tabs tab; + QString returnValue; + QSortFilterProxyModel *proxyModel; + QMenu *contextMenu; + QAction *deleteAction; + QString newAddressToSelect; + +private slots: + void on_deleteButton_clicked(); + void on_newAddressButton_clicked(); + /** Copy address of currently selected address entry to clipboard */ + void on_copyToClipboard_clicked(); + void on_signMessage_clicked(); + void on_verifyMessage_clicked(); + void selectionChanged(); + void on_showQRCode_clicked(); + /** Spawn contextual menu (right mouse menu) for address book entry */ + void contextualMenu(const QPoint &point); + + /** Copy label of currently selected address entry to clipboard */ + void onCopyLabelAction(); + /** Edit currently selected address entry */ + void onEditAction(); + + /** New entry/entries were added to address table */ + void selectNewAddress(const QModelIndex &parent, int begin, int end); + +signals: + void signMessage(QString addr); + void verifyMessage(QString addr); +}; + +#endif // ADDRESSBOOKDIALOG_H diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp new file mode 100644 index 0000000..e65d391 --- /dev/null +++ b/src/qt/addresstablemodel.cpp @@ -0,0 +1,406 @@ +#include "addresstablemodel.h" +#include "guiutil.h" +#include "walletmodel.h" + +#include "wallet.h" +#include "base58.h" + +#include +#include + +const QString AddressTableModel::Send = "S"; +const QString AddressTableModel::Receive = "R"; + +struct AddressTableEntry +{ + enum Type { + Sending, + Receiving + }; + + Type type; + QString label; + QString address; + + AddressTableEntry() {} + AddressTableEntry(Type type, const QString &label, const QString &address): + type(type), label(label), address(address) {} +}; + +struct AddressTableEntryLessThan +{ + bool operator()(const AddressTableEntry &a, const AddressTableEntry &b) const + { + return a.address < b.address; + } + bool operator()(const AddressTableEntry &a, const QString &b) const + { + return a.address < b; + } + bool operator()(const QString &a, const AddressTableEntry &b) const + { + return a < b.address; + } +}; + +// Private implementation +class AddressTablePriv +{ +public: + CWallet *wallet; + QList cachedAddressTable; + AddressTableModel *parent; + + AddressTablePriv(CWallet *wallet, AddressTableModel *parent): + wallet(wallet), parent(parent) {} + + void refreshAddressTable() + { + cachedAddressTable.clear(); + { + LOCK(wallet->cs_wallet); + BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& item, wallet->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + const std::string& strName = item.second; + bool fMine = IsMine(*wallet, address.Get()); + cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending, + QString::fromStdString(strName), + QString::fromStdString(address.ToString()))); + } + } + } + + void updateEntry(const QString &address, const QString &label, bool isMine, int status) + { + // Find address / label in model + QList::iterator lower = qLowerBound( + cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan()); + QList::iterator upper = qUpperBound( + cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan()); + int lowerIndex = (lower - cachedAddressTable.begin()); + int upperIndex = (upper - cachedAddressTable.begin()); + bool inModel = (lower != upper); + AddressTableEntry::Type newEntryType = isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending; + + switch(status) + { + case CT_NEW: + if(inModel) + { + OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_NOW, but entry is already in model\n"); + break; + } + parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex); + cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address)); + parent->endInsertRows(); + break; + case CT_UPDATED: + if(!inModel) + { + OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_UPDATED, but entry is not in model\n"); + break; + } + lower->type = newEntryType; + lower->label = label; + parent->emitDataChanged(lowerIndex); + break; + case CT_DELETED: + if(!inModel) + { + OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_DELETED, but entry is not in model\n"); + break; + } + parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); + cachedAddressTable.erase(lower, upper); + parent->endRemoveRows(); + break; + } + } + + int size() + { + return cachedAddressTable.size(); + } + + AddressTableEntry *index(int idx) + { + if(idx >= 0 && idx < cachedAddressTable.size()) + { + return &cachedAddressTable[idx]; + } + else + { + return 0; + } + } +}; + +AddressTableModel::AddressTableModel(CWallet *wallet, WalletModel *parent) : + QAbstractTableModel(parent),walletModel(parent),wallet(wallet),priv(0) +{ + columns << tr("Label") << tr("Address"); + priv = new AddressTablePriv(wallet, this); + priv->refreshAddressTable(); +} + +AddressTableModel::~AddressTableModel() +{ + delete priv; +} + +int AddressTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int AddressTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns.length(); +} + +QVariant AddressTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + AddressTableEntry *rec = static_cast(index.internalPointer()); + + if(role == Qt::DisplayRole || role == Qt::EditRole) + { + switch(index.column()) + { + case Label: + if(rec->label.isEmpty() && role == Qt::DisplayRole) + { + return tr("(no label)"); + } + else + { + return rec->label; + } + case Address: + return rec->address; + } + } + else if (role == Qt::FontRole) + { + QFont font; + if(index.column() == Address) + { + font = GUIUtil::bitcoinAddressFont(); + } + return font; + } + else if (role == TypeRole) + { + switch(rec->type) + { + case AddressTableEntry::Sending: + return Send; + case AddressTableEntry::Receiving: + return Receive; + default: break; + } + } + return QVariant(); +} + +bool AddressTableModel::setData(const QModelIndex & index, const QVariant & value, int role) +{ + if(!index.isValid()) + return false; + AddressTableEntry *rec = static_cast(index.internalPointer()); + + editStatus = OK; + + if(role == Qt::EditRole) + { + switch(index.column()) + { + case Label: + 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 + if(!walletModel->validateAddress(value.toString())) + { + editStatus = INVALID_ADDRESS; + return false; + } + // Double-check that we're not overwriting a receiving address + if(rec->type == AddressTableEntry::Sending) + { + { + LOCK(wallet->cs_wallet); + // Remove old entry + wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get()); + // Add new entry with new address + wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()).Get(), rec->label.toStdString()); + } + } + break; + } + + return true; + } + return false; +} + +QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole) + { + return columns[section]; + } + } + return QVariant(); +} + +Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const +{ + if(!index.isValid()) + return 0; + AddressTableEntry *rec = static_cast(index.internalPointer()); + + Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + // Can edit address and label for sending addresses, + // and only label for receiving addresses. + if(rec->type == AddressTableEntry::Sending || + (rec->type == AddressTableEntry::Receiving && index.column()==Label)) + { + retval |= Qt::ItemIsEditable; + } + return retval; +} + +QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & parent) const +{ + Q_UNUSED(parent); + AddressTableEntry *data = priv->index(row); + if(data) + { + return createIndex(row, column, priv->index(row)); + } + else + { + return QModelIndex(); + } +} + +void AddressTableModel::updateEntry(const QString &address, const QString &label, bool isMine, int status) +{ + // Update address book model from Bitcoin core + priv->updateEntry(address, label, isMine, status); +} + +QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address) +{ + std::string strLabel = label.toStdString(); + std::string strAddress = address.toStdString(); + + editStatus = OK; + + if(type == Send) + { + if(!walletModel->validateAddress(address)) + { + editStatus = INVALID_ADDRESS; + return QString(); + } + // Check for duplicate addresses + { + LOCK(wallet->cs_wallet); + if(wallet->mapAddressBook.count(CBitcoinAddress(strAddress).Get())) + { + editStatus = DUPLICATE_ADDRESS; + return QString(); + } + } + } + else if(type == Receive) + { + // Generate a new address to associate with given label + WalletModel::UnlockContext ctx(walletModel->requestUnlock()); + if(!ctx.isValid()) + { + // Unlock wallet failed or was cancelled + editStatus = WALLET_UNLOCK_FAILURE; + return QString(); + } + CPubKey newKey; + if(!wallet->GetKeyFromPool(newKey, true)) + { + editStatus = KEY_GENERATION_FAILURE; + return QString(); + } + strAddress = CBitcoinAddress(newKey.GetID()).ToString(); + } + else + { + return QString(); + } + // Add entry + { + LOCK(wallet->cs_wallet); + wallet->SetAddressBookName(CBitcoinAddress(strAddress).Get(), strLabel); + } + return QString::fromStdString(strAddress); +} + +bool AddressTableModel::removeRows(int row, int count, const QModelIndex & parent) +{ + Q_UNUSED(parent); + AddressTableEntry *rec = priv->index(row); + if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving) + { + // Can only remove one row at a time, and cannot remove rows not in model. + // Also refuse to remove receiving addresses. + return false; + } + { + LOCK(wallet->cs_wallet); + wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get()); + } + return true; +} + +/* Look up label for address in address book, if not found return empty string. + */ +QString AddressTableModel::labelForAddress(const QString &address) const +{ + { + LOCK(wallet->cs_wallet); + CBitcoinAddress address_parsed(address.toStdString()); + std::map::iterator mi = wallet->mapAddressBook.find(address_parsed.Get()); + if (mi != wallet->mapAddressBook.end()) + { + return QString::fromStdString(mi->second); + } + } + return QString(); +} + +int AddressTableModel::lookupAddress(const QString &address) const +{ + QModelIndexList lst = match(index(0, Address, QModelIndex()), + Qt::EditRole, address, 1, Qt::MatchExactly); + if(lst.isEmpty()) + { + return -1; + } + else + { + return lst.at(0).row(); + } +} + +void AddressTableModel::emitDataChanged(int idx) +{ + emit dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex())); +} diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h new file mode 100644 index 0000000..42974e3 --- /dev/null +++ b/src/qt/addresstablemodel.h @@ -0,0 +1,91 @@ +#ifndef ADDRESSTABLEMODEL_H +#define ADDRESSTABLEMODEL_H + +#include +#include + +class AddressTablePriv; +class CWallet; +class WalletModel; + +/** + Qt model of the address book in the core. This allows views to access and modify the address book. + */ +class AddressTableModel : public QAbstractTableModel +{ + Q_OBJECT +public: + explicit AddressTableModel(CWallet *wallet, WalletModel *parent = 0); + ~AddressTableModel(); + + enum ColumnIndex { + Label = 0, /**< User specified label */ + Address = 1 /**< Bitcoin address */ + }; + + enum RoleIndex { + TypeRole = Qt::UserRole /**< Type of address (#Send or #Receive) */ + }; + + /** Return status of edit/insert operation */ + enum EditStatus { + OK, + INVALID_ADDRESS, /**< Unparseable address */ + DUPLICATE_ADDRESS, /**< Address already in address book */ + WALLET_UNLOCK_FAILURE, /**< Wallet could not be unlocked to create new receiving address */ + KEY_GENERATION_FAILURE /**< Generating a new public key for a receiving address failed */ + }; + + static const QString Send; /**< Specifies send address */ + static const QString Receive; /**< Specifies receive address */ + + /** @name Methods overridden from QAbstractTableModel + @{*/ + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex & index, const QVariant & value, int role); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex & parent) const; + bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()); + Qt::ItemFlags flags(const QModelIndex & index) const; + /*@}*/ + + /* Add an address to the model. + Returns the added address on success, and an empty string otherwise. + */ + QString addRow(const QString &type, const QString &label, const QString &address); + + /* Look up label for address in address book, if not found return empty string. + */ + QString labelForAddress(const QString &address) const; + + /* Look up row index of an address in the model. + Return -1 if not found. + */ + int lookupAddress(const QString &address) const; + + EditStatus getEditStatus() const { return editStatus; } + +private: + WalletModel *walletModel; + CWallet *wallet; + AddressTablePriv *priv; + QStringList columns; + EditStatus editStatus; + + /** Notify listeners that data changed. */ + void emitDataChanged(int index); + +signals: + void defaultAddressChanged(const QString &address); + +public slots: + /* Update address list from core. + */ + void updateEntry(const QString &address, const QString &label, bool isMine, int status); + + friend class AddressTablePriv; +}; + +#endif // ADDRESSTABLEMODEL_H diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp new file mode 100644 index 0000000..7a2b64b --- /dev/null +++ b/src/qt/askpassphrasedialog.cpp @@ -0,0 +1,239 @@ +#include "askpassphrasedialog.h" +#include "ui_askpassphrasedialog.h" + +#include "guiconstants.h" +#include "walletmodel.h" + +#include +#include +#include + +AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : + QDialog(parent), + ui(new Ui::AskPassphraseDialog), + mode(mode), + model(0), + fCapsLock(false) +{ + ui->setupUi(this); + ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE); + ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE); + ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE); + + // Setup Caps Lock detection. + ui->passEdit1->installEventFilter(this); + ui->passEdit2->installEventFilter(this); + ui->passEdit3->installEventFilter(this); + + switch(mode) + { + case Encrypt: // Ask passphrase x2 + ui->passLabel1->hide(); + ui->passEdit1->hide(); + ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of 10 or more random characters, or eight or more words.")); + setWindowTitle(tr("Encrypt wallet")); + break; + case Unlock: // Ask passphrase + ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet.")); + ui->passLabel2->hide(); + ui->passEdit2->hide(); + ui->passLabel3->hide(); + ui->passEdit3->hide(); + setWindowTitle(tr("Unlock wallet")); + break; + case Decrypt: // Ask passphrase + ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet.")); + ui->passLabel2->hide(); + ui->passEdit2->hide(); + ui->passLabel3->hide(); + ui->passEdit3->hide(); + setWindowTitle(tr("Decrypt wallet")); + break; + case ChangePass: // Ask old passphrase + new passphrase x2 + setWindowTitle(tr("Change passphrase")); + ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet.")); + break; + } + + textChanged(); + connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); +} + +AskPassphraseDialog::~AskPassphraseDialog() +{ + // Attempt to overwrite text so that they do not linger around in memory + ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size())); + ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size())); + ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size())); + delete ui; +} + +void AskPassphraseDialog::setModel(WalletModel *model) +{ + this->model = model; +} + +void AskPassphraseDialog::accept() +{ + SecureString oldpass, newpass1, newpass2; + if(!model) + return; + oldpass.reserve(MAX_PASSPHRASE_SIZE); + newpass1.reserve(MAX_PASSPHRASE_SIZE); + newpass2.reserve(MAX_PASSPHRASE_SIZE); + // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) + // Alternately, find a way to make this input mlock()'d to begin with. + oldpass.assign(ui->passEdit1->text().toStdString().c_str()); + newpass1.assign(ui->passEdit2->text().toStdString().c_str()); + newpass2.assign(ui->passEdit3->text().toStdString().c_str()); + + switch(mode) + { + case Encrypt: { + if(newpass1.empty() || newpass2.empty()) + { + // Cannot encrypt with empty passphrase + break; + } + QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"), + tr("WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR CASINOCOINS!\nAre you sure you wish to encrypt your wallet?"), + QMessageBox::Yes|QMessageBox::Cancel, + QMessageBox::Cancel); + if(retval == QMessageBox::Yes) + { + if(newpass1 == newpass2) + { + if(model->setWalletEncrypted(true, newpass1)) + { + QMessageBox::warning(this, tr("Wallet encrypted"), + tr("CasinoCoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your casinocoins from being stolen by malware infecting your computer.")); + QApplication::quit(); + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted.")); + } + QDialog::accept(); // Success + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("The supplied passphrases do not match.")); + } + } + else + { + QDialog::reject(); // Cancelled + } + } break; + case Unlock: + if(!model->setWalletLocked(false, oldpass)) + { + QMessageBox::critical(this, tr("Wallet unlock failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + else + { + QDialog::accept(); // Success + } + break; + case Decrypt: + if(!model->setWalletEncrypted(false, oldpass)) + { + QMessageBox::critical(this, tr("Wallet decryption failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + else + { + QDialog::accept(); // Success + } + break; + case ChangePass: + if(newpass1 == newpass2) + { + if(model->changePassphrase(oldpass, newpass1)) + { + QMessageBox::information(this, tr("Wallet encrypted"), + tr("Wallet passphrase was successfully changed.")); + QDialog::accept(); // Success + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("The supplied passphrases do not match.")); + } + break; + } +} + +void AskPassphraseDialog::textChanged() +{ + // Validate input, set Ok button to enabled when accepable + bool acceptable = false; + switch(mode) + { + case Encrypt: // New passphrase x2 + acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); + break; + case Unlock: // Old passphrase x1 + case Decrypt: + acceptable = !ui->passEdit1->text().isEmpty(); + break; + case ChangePass: // Old passphrase x1, new passphrase x2 + acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); + break; + } + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable); +} + +bool AskPassphraseDialog::event(QEvent *event) +{ + // Detect Caps Lock key press. + if (event->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(event); + if (ke->key() == Qt::Key_CapsLock) { + fCapsLock = !fCapsLock; + } + if (fCapsLock) { + ui->capsLabel->setText(tr("Warning: The Caps Lock key is on.")); + } else { + ui->capsLabel->clear(); + } + } + return QWidget::event(event); +} + +bool AskPassphraseDialog::eventFilter(QObject *, QEvent *event) +{ + /* Detect Caps Lock. + * There is no good OS-independent way to check a key state in Qt, but we + * can detect Caps Lock by checking for the following condition: + * Shift key is down and the result is a lower case character, or + * Shift key is not down and the result is an upper case character. + */ + if (event->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(event); + QString str = ke->text(); + if (str.length() != 0) { + const QChar *psz = str.unicode(); + bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0; + if ((fShift && psz->isLower()) || (!fShift && psz->isUpper())) { + fCapsLock = true; + ui->capsLabel->setText(tr("Warning: The Caps Lock key is on.")); + } else if (psz->isLetter()) { + fCapsLock = false; + ui->capsLabel->clear(); + } + } + } + return false; +} diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h new file mode 100644 index 0000000..b500ff4 --- /dev/null +++ b/src/qt/askpassphrasedialog.h @@ -0,0 +1,45 @@ +#ifndef ASKPASSPHRASEDIALOG_H +#define ASKPASSPHRASEDIALOG_H + +#include + +namespace Ui { + class AskPassphraseDialog; +} + +class WalletModel; + +/** Multifunctional dialog to ask for passphrases. Used for encryption, unlocking, and changing the passphrase. + */ +class AskPassphraseDialog : public QDialog +{ + Q_OBJECT + +public: + enum Mode { + Encrypt, /**< Ask passphrase twice and encrypt */ + Unlock, /**< Ask passphrase and unlock */ + ChangePass, /**< Ask old passphrase + new passphrase twice */ + Decrypt /**< Ask passphrase and decrypt wallet */ + }; + + explicit AskPassphraseDialog(Mode mode, QWidget *parent = 0); + ~AskPassphraseDialog(); + + void accept(); + + void setModel(WalletModel *model); + +private: + Ui::AskPassphraseDialog *ui; + Mode mode; + WalletModel *model; + bool fCapsLock; + +private slots: + void textChanged(); + bool event(QEvent *event); + bool eventFilter(QObject *, QEvent *event); +}; + +#endif // ASKPASSPHRASEDIALOG_H diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp new file mode 100644 index 0000000..a99de62 --- /dev/null +++ b/src/qt/bitcoin.cpp @@ -0,0 +1,316 @@ +/* + * W.J. van der Laan 2011-2012 + */ +#include "bitcoingui.h" +#include "clientmodel.h" +#include "walletmodel.h" +#include "optionsmodel.h" +#include "guiutil.h" +#include "guiconstants.h" + +#include "init.h" +#include "ui_interface.h" +#include "qtipcserver.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED) +#define _BITCOIN_QT_PLUGINS_INCLUDED +#define __INSURE__ +#include +Q_IMPORT_PLUGIN(qcncodecs) +Q_IMPORT_PLUGIN(qjpcodecs) +Q_IMPORT_PLUGIN(qtwcodecs) +Q_IMPORT_PLUGIN(qkrcodecs) +Q_IMPORT_PLUGIN(qtaccessiblewidgets) +#endif + +// Need a global reference for the notifications to find the GUI +static BitcoinGUI *guiref; +static QSplashScreen *splashref; + +static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) +{ + // Message from network thread + if(guiref) + { + bool modal = (style & CClientUIInterface::MODAL); + // in case of modal message, use blocking connection to wait for user to click OK + QMetaObject::invokeMethod(guiref, "error", + modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(caption)), + Q_ARG(QString, QString::fromStdString(message)), + Q_ARG(bool, modal)); + } + else + { + printf("%s: %s\n", caption.c_str(), message.c_str()); + fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); + } +} + +static bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption) +{ + if(!guiref) + return false; + if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon) + return true; + bool payFee = false; + + QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(), + Q_ARG(qint64, nFeeRequired), + Q_ARG(bool*, &payFee)); + + return payFee; +} + +static void ThreadSafeHandleURI(const std::string& strURI) +{ + if(!guiref) + return; + + QMetaObject::invokeMethod(guiref, "handleURI", GUIUtil::blockingGUIThreadConnection(), + Q_ARG(QString, QString::fromStdString(strURI))); +} + +static void InitMessage(const std::string &message) +{ + if(splashref) + { + splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(255,255,200)); + QApplication::instance()->processEvents(); + } +} + +static void QueueShutdown() +{ + QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection); +} + +/* + Translate string to current locale using Qt. + */ +static std::string Translate(const char* psz) +{ + return QCoreApplication::translate("bitcoin-core", psz).toStdString(); +} + +/* Handle runaway exceptions. Shows a message box with the problem and quits the program. + */ +static void handleRunawayException(std::exception *e) +{ + PrintExceptionContinue(e, "Runaway exception"); + QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occured. CasinoCoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning)); + exit(1); +} + +#ifndef BITCOIN_QT_TEST +int main(int argc, char *argv[]) +{ +// TODO: implement URI support on the Mac. +#if !defined(MAC_OSX) + // Do this early as we don't want to bother initializing if we are just calling IPC + for (int i = 1; i < argc; i++) + { + if (boost::algorithm::istarts_with(argv[i], "casinocoin:")) + { + const char *strURI = argv[i]; + try { + boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME); + if (mq.try_send(strURI, strlen(strURI), 0)) + // if URI could be sent to the message queue exit here + exit(0); + else + // if URI could not be sent to the message queue do a normal Bitcoin-Qt startup + break; + } + catch (boost::interprocess::interprocess_exception &ex) { + // don't log the "file not found" exception, because that's normal for + // the first start of the first instance + if (ex.get_error_code() != boost::interprocess::not_found_error) + { + printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); + break; + } + } + } + } +#endif + + // Internal string conversion is all UTF-8 + QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); + QTextCodec::setCodecForCStrings(QTextCodec::codecForTr()); + + Q_INIT_RESOURCE(bitcoin); + QApplication app(argc, argv); + + // Install global event filter that makes sure that long tooltips can be word-wrapped + app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app)); + + // Command-line options take precedence: + ParseParameters(argc, argv); + + // ... then bitcoin.conf: + if (!boost::filesystem::is_directory(GetDataDir(false))) + { + fprintf(stderr, "Error: Specified directory does not exist\n"); + return 1; + } + ReadConfigFile(mapArgs, mapMultiArgs); + + // Application identification (must be set before OptionsModel is initialized, + // as it is used to locate QSettings) + app.setOrganizationName("CasinoCoin"); + app.setOrganizationDomain("casinocoin.org"); + if(GetBoolArg("-testnet")) // Separate UI settings for testnet + app.setApplicationName("CasinoCoin-Qt-testnet"); + else + app.setApplicationName("CasinoCoin-Qt"); + + // ... then GUI settings: + OptionsModel optionsModel; + + // Get desired locale (e.g. "de_DE") from command line or use system locale + QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString())); + QString lang = lang_territory; + // Convert to "de" only by truncating "_DE" + lang.truncate(lang_territory.lastIndexOf('_')); + + QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; + // Load language files for configured locale: + // - First load the translator for the base language, without territory + // - Then load the more specific locale translator + + // Load e.g. qt_de.qm + if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + app.installTranslator(&qtTranslatorBase); + + // Load e.g. qt_de_DE.qm + if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + app.installTranslator(&qtTranslator); + + // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc) + if (translatorBase.load(lang, ":/translations/")) + app.installTranslator(&translatorBase); + + // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc) + if (translator.load(lang_territory, ":/translations/")) + app.installTranslator(&translator); + + // Subscribe to global signals from core + uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox); + uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee); + uiInterface.ThreadSafeHandleURI.connect(ThreadSafeHandleURI); + uiInterface.InitMessage.connect(InitMessage); + uiInterface.QueueShutdown.connect(QueueShutdown); + uiInterface.Translate.connect(Translate); + + // Show help message immediately after parsing command-line options (for "-lang") and setting locale, + // but before showing splash screen. + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + GUIUtil::HelpMessageBox help; + help.showOrPrint(); + return 1; + } + + QSplashScreen splash(QPixmap(":/images/splash"), 0); + if (GetBoolArg("-splash", true) && !GetBoolArg("-min")) + { + splash.show(); + splash.setAutoFillBackground(true); + splashref = &splash; + } + + app.processEvents(); + + app.setQuitOnLastWindowClosed(false); + + try + { + // Regenerate startup link, to fix links to old versions + if (GUIUtil::GetStartOnSystemStartup()) + GUIUtil::SetStartOnSystemStartup(true); + + BitcoinGUI window; + guiref = &window; + if(AppInit2()) + { + { + // Put this in a block, so that the Model objects are cleaned up before + // calling Shutdown(). + + optionsModel.Upgrade(); // Must be done after AppInit2 + + if (splashref) + splash.finish(&window); + + ClientModel clientModel(&optionsModel); + WalletModel walletModel(pwalletMain, &optionsModel); + + window.setClientModel(&clientModel); + window.setWalletModel(&walletModel); + + // If -min option passed, start window minimized. + if(GetBoolArg("-min")) + { + window.showMinimized(); + } + else + { + window.show(); + } +// TODO: implement URI support on the Mac. +#if !defined(MAC_OSX) + + // Place this here as guiref has to be defined if we dont want to lose URIs + ipcInit(); + + // Check for URI in argv + for (int i = 1; i < argc; i++) + { + if (boost::algorithm::istarts_with(argv[i], "casinocoin:")) + { + const char *strURI = argv[i]; + try { + boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME); + mq.try_send(strURI, strlen(strURI), 0); + } + catch (boost::interprocess::interprocess_exception &ex) { + printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); + break; + } + } + } +#endif + app.exec(); + + window.hide(); + window.setClientModel(0); + window.setWalletModel(0); + guiref = 0; + } + // Shutdown the core and it's threads, but don't exit Bitcoin-Qt here + Shutdown(NULL); + } + else + { + return 1; + } + } catch (std::exception& e) { + handleRunawayException(&e); + } catch (...) { + handleRunawayException(NULL); + } + return 0; +} +#endif // BITCOIN_QT_TEST diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc new file mode 100644 index 0000000..9733abd --- /dev/null +++ b/src/qt/bitcoin.qrc @@ -0,0 +1,89 @@ + + + res/icons/bitcoin.png + res/icons/address-book.png + res/icons/quit.png + res/icons/send.png + res/icons/toolbar.png + res/icons/connect0_16.png + res/icons/connect1_16.png + res/icons/connect2_16.png + res/icons/connect3_16.png + res/icons/connect4_16.png + res/icons/transaction0.png + res/icons/transaction2.png + res/icons/clock1.png + res/icons/clock2.png + res/icons/clock3.png + res/icons/clock4.png + res/icons/clock5.png + res/icons/configure.png + res/icons/receive.png + res/icons/editpaste.png + res/icons/editcopy.png + res/icons/add.png + res/icons/bitcoin_testnet.png + res/icons/toolbar_testnet.png + res/icons/edit.png + res/icons/history.png + res/icons/overview.png + res/icons/export.png + res/icons/synced.png + res/icons/remove.png + res/icons/tx_input.png + res/icons/tx_output.png + res/icons/tx_inout.png + res/icons/tx_mined.png + res/icons/lock_closed.png + res/icons/lock_open.png + res/icons/key.png + res/icons/filesave.png + res/icons/qrcode.png + res/icons/debugwindow.png + + + res/images/about.png + res/images/splash2.jpg + res/images/wallet.png + + + res/movies/update_spinner.mng + + + locale/bitcoin_bg.qm + locale/bitcoin_ca_ES.qm + locale/bitcoin_cs.qm + locale/bitcoin_da.qm + locale/bitcoin_de.qm + locale/bitcoin_el_GR.qm + locale/bitcoin_en.qm + locale/bitcoin_es.qm + locale/bitcoin_es_CL.qm + locale/bitcoin_et.qm + locale/bitcoin_eu_ES.qm + locale/bitcoin_fa.qm + locale/bitcoin_fa_IR.qm + locale/bitcoin_fi.qm + locale/bitcoin_fr.qm + locale/bitcoin_fr_CA.qm + locale/bitcoin_he.qm + locale/bitcoin_hr.qm + locale/bitcoin_hu.qm + locale/bitcoin_it.qm + locale/bitcoin_lt.qm + locale/bitcoin_nb.qm + locale/bitcoin_nl.qm + locale/bitcoin_pl.qm + locale/bitcoin_pt_BR.qm + locale/bitcoin_pt_PT.qm + locale/bitcoin_ro_RO.qm + locale/bitcoin_ru.qm + locale/bitcoin_sk.qm + locale/bitcoin_sr.qm + locale/bitcoin_sv.qm + locale/bitcoin_tr.qm + locale/bitcoin_uk.qm + locale/bitcoin_zh_CN.qm + locale/bitcoin_zh_TW.qm + + diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp new file mode 100644 index 0000000..d2b93e7 --- /dev/null +++ b/src/qt/bitcoinaddressvalidator.cpp @@ -0,0 +1,77 @@ +#include "bitcoinaddressvalidator.h" + +/* Base58 characters are: + "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + + This is: + - All numbers except for '0' + - All uppercase letters except for 'I' and 'O' + - All lowercase letters except for 'l' + + User friendly Base58 input can map + - 'l' and 'I' to '1' + - '0' and 'O' to 'o' +*/ + +BitcoinAddressValidator::BitcoinAddressValidator(QObject *parent) : + QValidator(parent) +{ +} + +QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) const +{ + // Correction + for(int idx=0; idx= '0' && ch<='9') || + (ch >= 'a' && ch<='z') || + (ch >= 'A' && ch<='Z')) && + ch != 'l' && ch != 'I' && ch != '0' && ch != 'O') + { + // Alphanumeric and not a 'forbidden' character + } + else + { + state = QValidator::Invalid; + } + } + + // Empty address is "intermediate" input + if(input.isEmpty()) + { + state = QValidator::Intermediate; + } + + return state; +} diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h new file mode 100644 index 0000000..9710d12 --- /dev/null +++ b/src/qt/bitcoinaddressvalidator.h @@ -0,0 +1,24 @@ +#ifndef BITCOINADDRESSVALIDATOR_H +#define BITCOINADDRESSVALIDATOR_H + +#include + +/** Base48 entry widget validator. + Corrects near-miss characters and refuses characters that are no part of base48. + */ +class BitcoinAddressValidator : public QValidator +{ + Q_OBJECT +public: + explicit BitcoinAddressValidator(QObject *parent = 0); + + State validate(QString &input, int &pos) const; + + static const int MaxAddressLength = 35; +signals: + +public slots: + +}; + +#endif // BITCOINADDRESSVALIDATOR_H diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp new file mode 100644 index 0000000..9514ec8 --- /dev/null +++ b/src/qt/bitcoinamountfield.cpp @@ -0,0 +1,168 @@ +#include "bitcoinamountfield.h" +#include "qvaluecombobox.h" +#include "bitcoinunits.h" + +#include "guiconstants.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BitcoinAmountField::BitcoinAmountField(QWidget *parent): + QWidget(parent), amount(0), currentUnit(-1) +{ + amount = new QDoubleSpinBox(this); + amount->setLocale(QLocale::c()); + amount->setDecimals(8); + amount->installEventFilter(this); + amount->setMaximumWidth(170); + amount->setSingleStep(0.001); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(amount); + unit = new QValueComboBox(this); + unit->setModel(new BitcoinUnits(this)); + layout->addWidget(unit); + layout->addStretch(1); + layout->setContentsMargins(0,0,0,0); + + setLayout(layout); + + setFocusPolicy(Qt::TabFocus); + setFocusProxy(amount); + + // If one if the widgets changes, the combined content changes as well + connect(amount, SIGNAL(valueChanged(QString)), this, SIGNAL(textChanged())); + connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int))); + + // Set default based on configuration + unitChanged(unit->currentIndex()); +} + +void BitcoinAmountField::setText(const QString &text) +{ + if (text.isEmpty()) + amount->clear(); + else + amount->setValue(text.toDouble()); +} + +void BitcoinAmountField::clear() +{ + amount->clear(); + unit->setCurrentIndex(0); +} + +bool BitcoinAmountField::validate() +{ + bool valid = true; + if (amount->value() == 0.0) + valid = false; + if (valid && !BitcoinUnits::parse(currentUnit, text(), 0)) + valid = false; + + setValid(valid); + + return valid; +} + +void BitcoinAmountField::setValid(bool valid) +{ + if (valid) + amount->setStyleSheet(""); + else + amount->setStyleSheet(STYLE_INVALID); +} + +QString BitcoinAmountField::text() const +{ + if (amount->text().isEmpty()) + return QString(); + else + return amount->text(); +} + +bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::FocusIn) + { + // Clear invalid flag on focus + setValid(true); + } + else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) + { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Comma) + { + // Translate a comma into a period + QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count()); + qApp->sendEvent(object, &periodKeyEvent); + return true; + } + } + return QWidget::eventFilter(object, event); +} + +QWidget *BitcoinAmountField::setupTabChain(QWidget *prev) +{ + QWidget::setTabOrder(prev, amount); + return amount; +} + +qint64 BitcoinAmountField::value(bool *valid_out) const +{ + qint64 val_out = 0; + bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out); + if(valid_out) + { + *valid_out = valid; + } + return val_out; +} + +void BitcoinAmountField::setValue(qint64 value) +{ + setText(BitcoinUnits::format(currentUnit, value)); +} + +void BitcoinAmountField::unitChanged(int idx) +{ + // Use description tooltip for current unit for the combobox + unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString()); + + // Determine new unit ID + int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt(); + + // Parse current value and convert to new unit + bool valid = false; + qint64 currentValue = value(&valid); + + currentUnit = newUnit; + + // Set max length after retrieving the value, to prevent truncation + amount->setDecimals(BitcoinUnits::decimals(currentUnit)); + amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals())); + + if(valid) + { + // If value was valid, re-place it in the widget with the new unit + setValue(currentValue); + } + else + { + // If current value is invalid, just clear field + setText(""); + } + setValid(true); +} + +void BitcoinAmountField::setDisplayUnit(int newUnit) +{ + unit->setValue(newUnit); +} diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h new file mode 100644 index 0000000..ead8bdb --- /dev/null +++ b/src/qt/bitcoinamountfield.h @@ -0,0 +1,60 @@ +#ifndef BITCOINFIELD_H +#define BITCOINFIELD_H + +#include + +QT_BEGIN_NAMESPACE +class QDoubleSpinBox; +class QValueComboBox; +QT_END_NAMESPACE + +/** Widget for entering bitcoin amounts. + */ +class BitcoinAmountField: public QWidget +{ + Q_OBJECT + Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY textChanged USER true) +public: + explicit BitcoinAmountField(QWidget *parent = 0); + + qint64 value(bool *valid=0) const; + void setValue(qint64 value); + + /** Mark current value as invalid in UI. */ + void setValid(bool valid); + /** Perform input validation, mark field as invalid if entered value is not valid. */ + bool validate(); + + /** Change unit used to display amount. */ + void setDisplayUnit(int unit); + + /** Make field empty and ready for new input. */ + void clear(); + + /** Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907), + in these cases we have to set it up manually. + */ + QWidget *setupTabChain(QWidget *prev); + +signals: + void textChanged(); + +protected: + /** Intercept focus-in event and ',' keypresses */ + bool eventFilter(QObject *object, QEvent *event); + +private: + QDoubleSpinBox *amount; + QValueComboBox *unit; + int currentUnit; + + void setText(const QString &text); + QString text() const; + +private slots: + void unitChanged(int idx); + +}; + + +#endif // BITCOINFIELD_H diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp new file mode 100644 index 0000000..16aa068 --- /dev/null +++ b/src/qt/bitcoingui.cpp @@ -0,0 +1,919 @@ +/* + * Qt4 bitcoin GUI. + * + * W.J. van der Laan 2011-2012 + * The Bitcoin Developers 2011-2012 + * The CasinoCoin Developers 201-2013 + */ +#include "bitcoingui.h" +#include "transactiontablemodel.h" +#include "addressbookpage.h" +#include "sendcoinsdialog.h" +#include "signverifymessagedialog.h" +#include "optionsdialog.h" +#include "aboutdialog.h" +#include "clientmodel.h" +#include "walletmodel.h" +#include "editaddressdialog.h" +#include "optionsmodel.h" +#include "transactiondescdialog.h" +#include "addresstablemodel.h" +#include "transactionview.h" +#include "overviewpage.h" +#include "bitcoinunits.h" +#include "guiconstants.h" +#include "askpassphrasedialog.h" +#include "notificator.h" +#include "guiutil.h" +#include "rpcconsole.h" + +#ifdef Q_WS_MAC +#include "macdockiconhandler.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +BitcoinGUI::BitcoinGUI(QWidget *parent): + QMainWindow(parent), + clientModel(0), + walletModel(0), + encryptWalletAction(0), + changePassphraseAction(0), + aboutQtAction(0), + trayIcon(0), + notificator(0), + rpcConsole(0) +{ + resize(850, 550); + setWindowTitle(tr("CasinoCoin") + " - " + tr("Wallet")); +#ifndef Q_WS_MAC + qApp->setWindowIcon(QIcon(":icons/bitcoin")); + setWindowIcon(QIcon(":icons/bitcoin")); +#else + setUnifiedTitleAndToolBarOnMac(true); + QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); +#endif + // Accept D&D of URIs + setAcceptDrops(true); + + // Create actions for the toolbar, menu bar and tray/dock icon + createActions(); + + // Create application menu bar + createMenuBar(); + + // Create the toolbars + createToolBars(); + + // Create the tray icon (or setup the dock icon) + createTrayIcon(); + + // Create tabs + overviewPage = new OverviewPage(); + + transactionsPage = new QWidget(this); + QVBoxLayout *vbox = new QVBoxLayout(); + transactionView = new TransactionView(this); + vbox->addWidget(transactionView); + transactionsPage->setLayout(vbox); + + addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab); + + receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab); + + sendCoinsPage = new SendCoinsDialog(this); + + signVerifyMessageDialog = new SignVerifyMessageDialog(this); + + centralWidget = new QStackedWidget(this); + centralWidget->addWidget(overviewPage); + centralWidget->addWidget(transactionsPage); + centralWidget->addWidget(addressBookPage); + centralWidget->addWidget(receiveCoinsPage); + centralWidget->addWidget(sendCoinsPage); +#ifdef FIRST_CLASS_MESSAGING + centralWidget->addWidget(signVerifyMessageDialog); +#endif + setCentralWidget(centralWidget); + + // Create status bar + statusBar(); + + // Status bar notification icons + QFrame *frameBlocks = new QFrame(); + frameBlocks->setContentsMargins(0,0,0,0); + frameBlocks->setMinimumWidth(73); + frameBlocks->setMaximumWidth(73); + QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks); + frameBlocksLayout->setContentsMargins(3,0,3,0); + frameBlocksLayout->setSpacing(3); + labelEncryptionIcon = new QLabel(); + labelConnectionsIcon = new QLabel(); + labelBlocksIcon = new QLabel(); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelEncryptionIcon); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelConnectionsIcon); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelBlocksIcon); + frameBlocksLayout->addStretch(); + + // Progress bar and label for blocks download + progressBarLabel = new QLabel(); + progressBarLabel->setVisible(false); + progressBar = new QProgressBar(); + progressBar->setAlignment(Qt::AlignCenter); + progressBar->setVisible(false); + + statusBar()->addWidget(progressBarLabel); + statusBar()->addWidget(progressBar); + statusBar()->addPermanentWidget(frameBlocks); + + syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this); + + // Clicking on a transaction on the overview page simply sends you to transaction history page + connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage())); + connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex))); + + // Doubleclicking on a transaction on the transaction history page shows details + connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails())); + + rpcConsole = new RPCConsole(this); + connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show())); + + // Clicking on "Verify Message" in the address book sends you to the verify message tab + connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString))); + // Clicking on "Sign Message" in the receive coins page sends you to the sign message tab + connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString))); + + gotoOverviewPage(); +} + +BitcoinGUI::~BitcoinGUI() +{ + if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu) + trayIcon->hide(); +#ifdef Q_WS_MAC + delete appMenuBar; +#endif +} + +void BitcoinGUI::createActions() +{ + QActionGroup *tabGroup = new QActionGroup(this); + + overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this); + overviewAction->setToolTip(tr("Show general overview of wallet")); + overviewAction->setCheckable(true); + overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1)); + tabGroup->addAction(overviewAction); + + historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this); + historyAction->setToolTip(tr("Browse transaction history")); + historyAction->setCheckable(true); + historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4)); + tabGroup->addAction(historyAction); + + addressBookAction = new QAction(QIcon(":/icons/address-book"), tr("&Address Book"), this); + addressBookAction->setToolTip(tr("Edit the list of stored addresses and labels")); + addressBookAction->setCheckable(true); + addressBookAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5)); + tabGroup->addAction(addressBookAction); + + receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive coins"), this); + receiveCoinsAction->setToolTip(tr("Show the list of addresses for receiving payments")); + receiveCoinsAction->setCheckable(true); + receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); + tabGroup->addAction(receiveCoinsAction); + + sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send coins"), this); + sendCoinsAction->setToolTip(tr("Send coins to a CasinoCoin address")); + sendCoinsAction->setCheckable(true); + sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); + tabGroup->addAction(sendCoinsAction); + + signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this); + signMessageAction->setToolTip(tr("Sign a message to prove you own a Bitcoin address")); + tabGroup->addAction(signMessageAction); + + verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this); + verifyMessageAction->setToolTip(tr("Verify a message to ensure it was signed with a specified Bitcoin address")); + tabGroup->addAction(verifyMessageAction); + +#ifdef FIRST_CLASS_MESSAGING + firstClassMessagingAction = new QAction(QIcon(":/icons/edit"), tr("S&ignatures"), this); + firstClassMessagingAction->setToolTip(signMessageAction->toolTip() + QString(". / ") + verifyMessageAction->toolTip() + QString(".")); + firstClassMessagingAction->setCheckable(true); + tabGroup->addAction(firstClassMessagingAction); +#endif + + connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage())); + connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); + connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage())); + connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); + connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); + connect(signMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); + connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); +#ifdef FIRST_CLASS_MESSAGING + connect(firstClassMessagingAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + // Always start with the sign message tab for FIRST_CLASS_MESSAGING + connect(firstClassMessagingAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); +#endif + + quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this); + quitAction->setToolTip(tr("Quit application")); + quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); + quitAction->setMenuRole(QAction::QuitRole); + aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About CasinoCoin"), this); + aboutAction->setToolTip(tr("Show information about CasinoCoin")); + aboutAction->setMenuRole(QAction::AboutRole); + aboutQtAction = new QAction(tr("About &Qt"), this); + aboutQtAction->setToolTip(tr("Show information about Qt")); + aboutQtAction->setMenuRole(QAction::AboutQtRole); + optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); + optionsAction->setToolTip(tr("Modify configuration options for CasinoCoin")); + optionsAction->setMenuRole(QAction::PreferencesRole); + toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("Show/Hide &CasinoCoin"), this); + toggleHideAction->setToolTip(tr("Show or hide the CasinoCoin window")); + exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this); + exportAction->setToolTip(tr("Export the data in the current tab to a file")); + encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); + encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet")); + encryptWalletAction->setCheckable(true); + backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); + backupWalletAction->setToolTip(tr("Backup wallet to another location")); + changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this); + changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption")); + openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this); + openRPCConsoleAction->setToolTip(tr("Open debugging and diagnostic console")); + + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked())); + connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); + connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden())); + connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool))); + connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet())); + connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase())); +} + +void BitcoinGUI::createMenuBar() +{ +#ifdef Q_WS_MAC + // Create a decoupled menu bar on Mac which stays even if the window is closed + appMenuBar = new QMenuBar(); +#else + // Get the main window's menu bar on other platforms + appMenuBar = menuBar(); +#endif + + // Configure the menus + QMenu *file = appMenuBar->addMenu(tr("&File")); + file->addAction(backupWalletAction); + file->addAction(exportAction); +#ifndef FIRST_CLASS_MESSAGING + file->addAction(signMessageAction); + file->addAction(verifyMessageAction); +#endif + file->addSeparator(); + file->addAction(quitAction); + + QMenu *settings = appMenuBar->addMenu(tr("&Settings")); + settings->addAction(encryptWalletAction); + settings->addAction(changePassphraseAction); + settings->addSeparator(); + settings->addAction(optionsAction); + + QMenu *help = appMenuBar->addMenu(tr("&Help")); + help->addAction(openRPCConsoleAction); + help->addSeparator(); + help->addAction(aboutAction); + help->addAction(aboutQtAction); +} + +void BitcoinGUI::createToolBars() +{ + QToolBar *toolbar = addToolBar(tr("Tabs toolbar")); + toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + toolbar->addAction(overviewAction); + toolbar->addAction(sendCoinsAction); + toolbar->addAction(receiveCoinsAction); + toolbar->addAction(historyAction); + toolbar->addAction(addressBookAction); +#ifdef FIRST_CLASS_MESSAGING + toolbar->addAction(firstClassMessagingAction); +#endif + + QToolBar *toolbar2 = addToolBar(tr("Actions toolbar")); + toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + toolbar2->addAction(exportAction); +} + +void BitcoinGUI::setClientModel(ClientModel *clientModel) +{ + this->clientModel = clientModel; + if(clientModel) + { + // Replace some strings and icons, when using the testnet + if(clientModel->isTestNet()) + { + setWindowTitle(windowTitle() + QString(" ") + tr("[testnet]")); +#ifndef Q_WS_MAC + qApp->setWindowIcon(QIcon(":icons/bitcoin_testnet")); + setWindowIcon(QIcon(":icons/bitcoin_testnet")); +#else + MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet")); +#endif + if(trayIcon) + { + trayIcon->setToolTip(tr("CasinoCoin client") + QString(" ") + tr("[testnet]")); + trayIcon->setIcon(QIcon(":/icons/toolbar_testnet")); + toggleHideAction->setIcon(QIcon(":/icons/toolbar_testnet")); + } + + aboutAction->setIcon(QIcon(":/icons/toolbar_testnet")); + } + + // Keep up to date with client + setNumConnections(clientModel->getNumConnections()); + connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); + + setNumBlocks(clientModel->getNumBlocks(), clientModel->getNumBlocksOfPeers()); + connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int))); + + // Report errors from network/worker thread + connect(clientModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); + + rpcConsole->setClientModel(clientModel); + addressBookPage->setOptionsModel(clientModel->getOptionsModel()); + receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel()); + } +} + +void BitcoinGUI::setWalletModel(WalletModel *walletModel) +{ + this->walletModel = walletModel; + if(walletModel) + { + // Report errors from wallet thread + connect(walletModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); + + // Put transaction list in tabs + transactionView->setModel(walletModel); + + overviewPage->setModel(walletModel); + addressBookPage->setModel(walletModel->getAddressTableModel()); + receiveCoinsPage->setModel(walletModel->getAddressTableModel()); + sendCoinsPage->setModel(walletModel); + signVerifyMessageDialog->setModel(walletModel); + + setEncryptionStatus(walletModel->getEncryptionStatus()); + connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int))); + + // Balloon popup for new transaction + connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(incomingTransaction(QModelIndex,int,int))); + + // Ask for passphrase if needed + connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); + } +} + +void BitcoinGUI::createTrayIcon() +{ + QMenu *trayIconMenu; +#ifndef Q_WS_MAC + trayIcon = new QSystemTrayIcon(this); + trayIconMenu = new QMenu(this); + trayIcon->setContextMenu(trayIconMenu); + trayIcon->setToolTip(tr("CasinoCoin client")); + trayIcon->setIcon(QIcon(":/icons/toolbar")); + connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + trayIcon->show(); +#else + // Note: On Mac, the dock icon is used to provide the tray's functionality. + MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); + trayIconMenu = dockIconHandler->dockMenu(); +#endif + + // Configuration of the tray icon (or dock icon) icon menu + trayIconMenu->addAction(toggleHideAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(sendCoinsAction); + trayIconMenu->addAction(receiveCoinsAction); +#ifndef FIRST_CLASS_MESSAGING + trayIconMenu->addSeparator(); +#endif + trayIconMenu->addAction(signMessageAction); + 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); +#endif + + notificator = new Notificator(qApp->applicationName(), trayIcon); +} + +#ifndef Q_WS_MAC +void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) +{ + if(reason == QSystemTrayIcon::Trigger) + { + // Click on system tray icon triggers "show/hide CasinoCoin" + toggleHideAction->trigger(); + } +} +#endif + +void BitcoinGUI::optionsClicked() +{ + if(!clientModel || !clientModel->getOptionsModel()) + return; + OptionsDialog dlg; + dlg.setModel(clientModel->getOptionsModel()); + dlg.exec(); +} + +void BitcoinGUI::aboutClicked() +{ + AboutDialog dlg; + dlg.setModel(clientModel); + dlg.exec(); +} + +void BitcoinGUI::setNumConnections(int count) +{ + QString icon; + switch(count) + { + case 0: icon = ":/icons/connect_0"; break; + case 1: case 2: case 3: icon = ":/icons/connect_1"; break; + case 4: case 5: case 6: icon = ":/icons/connect_2"; break; + case 7: case 8: case 9: icon = ":/icons/connect_3"; break; + default: icon = ":/icons/connect_4"; break; + } + labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelConnectionsIcon->setToolTip(tr("%n active connection(s) to CasinoCoin network", "", count)); +} + +void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) +{ + // don't show / hide progressBar and it's label if we have no connection(s) to the network + if (!clientModel || clientModel->getNumConnections() == 0) + { + progressBarLabel->setVisible(false); + progressBar->setVisible(false); + + return; + } + + QString tooltip; + + if(count < nTotalBlocks) + { + int nRemainingBlocks = nTotalBlocks - count; + float nPercentageDone = count / (nTotalBlocks * 0.01f); + + if (clientModel->getStatusBarWarnings() == "") + { + progressBarLabel->setText(tr("Synchronizing with network...")); + progressBarLabel->setVisible(true); + progressBar->setFormat(tr("~%n block(s) remaining", "", nRemainingBlocks)); + progressBar->setMaximum(nTotalBlocks); + progressBar->setValue(count); + progressBar->setVisible(true); + } + else + { + progressBarLabel->setText(clientModel->getStatusBarWarnings()); + progressBarLabel->setVisible(true); + progressBar->setVisible(false); + } + tooltip = tr("Downloaded %1 of %2 blocks of transaction history (%3% done).").arg(count).arg(nTotalBlocks).arg(nPercentageDone, 0, 'f', 2); + } + else + { + if (clientModel->getStatusBarWarnings() == "") + progressBarLabel->setVisible(false); + else + { + progressBarLabel->setText(clientModel->getStatusBarWarnings()); + progressBarLabel->setVisible(true); + } + progressBar->setVisible(false); + tooltip = tr("Downloaded %1 blocks of transaction history.").arg(count); + } + + tooltip = tr("Current difficulty is %1.").arg(clientModel->GetDifficulty()) + QString("
") + tooltip; + + QDateTime now = QDateTime::currentDateTime(); + QDateTime lastBlockDate = clientModel->getLastBlockDate(); + int secs = lastBlockDate.secsTo(now); + QString text; + + // Represent time from last generated block in human readable text + if(secs <= 0) + { + // Fully up to date. Leave text empty. + } + else if(secs < 60) + { + text = tr("%n second(s) ago","",secs); + } + else if(secs < 60*60) + { + text = tr("%n minute(s) ago","",secs/60); + } + else if(secs < 24*60*60) + { + text = tr("%n hour(s) ago","",secs/(60*60)); + } + else + { + text = tr("%n day(s) ago","",secs/(60*60*24)); + } + + // Set icon state: spinning if catching up, tick otherwise + if(secs < 90*60 && count >= nTotalBlocks) + { + tooltip = tr("Up to date") + QString(".
") + tooltip; + labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + + overviewPage->showOutOfSyncWarning(false); + } + else + { + tooltip = tr("Catching up...") + QString("
") + tooltip; + labelBlocksIcon->setMovie(syncIconMovie); + syncIconMovie->start(); + + overviewPage->showOutOfSyncWarning(true); + } + + if(!text.isEmpty()) + { + tooltip += QString("
"); + tooltip += tr("Last received block was generated %1.").arg(text); + } + + // Don't word-wrap this (fixed-width) tooltip + tooltip = QString("") + tooltip + QString(""); + + labelBlocksIcon->setToolTip(tooltip); + progressBarLabel->setToolTip(tooltip); + progressBar->setToolTip(tooltip); +} + +void BitcoinGUI::error(const QString &title, const QString &message, bool modal) +{ + // Report errors from network/worker thread + if(modal) + { + QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok); + } else { + notificator->notify(Notificator::Critical, title, message); + } +} + +void BitcoinGUI::changeEvent(QEvent *e) +{ + QMainWindow::changeEvent(e); +#ifndef Q_WS_MAC // Ignored on Mac + if(e->type() == QEvent::WindowStateChange) + { + if(clientModel && clientModel->getOptionsModel()->getMinimizeToTray()) + { + QWindowStateChangeEvent *wsevt = static_cast(e); + if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized()) + { + QTimer::singleShot(0, this, SLOT(hide())); + e->ignore(); + } + } + } +#endif +} + +void BitcoinGUI::closeEvent(QCloseEvent *event) +{ + if(clientModel) + { +#ifndef Q_WS_MAC // Ignored on Mac + if(!clientModel->getOptionsModel()->getMinimizeToTray() && + !clientModel->getOptionsModel()->getMinimizeOnClose()) + { + qApp->quit(); + } +#endif + } + QMainWindow::closeEvent(event); +} + +void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee) +{ + QString strMessage = + tr("This transaction is over the size limit. You can still send it for a fee of %1, " + "which goes to the nodes that process your transaction and helps to support the network. " + "Do you want to pay the fee?").arg( + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired)); + QMessageBox::StandardButton retval = QMessageBox::question( + this, tr("Confirm transaction fee"), strMessage, + QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes); + *payFee = (retval == QMessageBox::Yes); +} + +void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int end) +{ + if(!walletModel || !clientModel) + return; + TransactionTableModel *ttm = walletModel->getTransactionTableModel(); + qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent) + .data(Qt::EditRole).toULongLong(); + if(!clientModel->inInitialBlockDownload()) + { + // On new transaction, make an info balloon + // Unless the initial block download is in progress, to prevent balloon-spam + QString date = ttm->index(start, TransactionTableModel::Date, parent) + .data().toString(); + QString type = ttm->index(start, TransactionTableModel::Type, parent) + .data().toString(); + QString address = ttm->index(start, TransactionTableModel::ToAddress, parent) + .data().toString(); + QIcon icon = qvariant_cast(ttm->index(start, + TransactionTableModel::ToAddress, parent) + .data(Qt::DecorationRole)); + + notificator->notify(Notificator::Information, + (amount)<0 ? tr("Sent transaction") : + tr("Incoming transaction"), + tr("Date: %1\n" + "Amount: %2\n" + "Type: %3\n" + "Address: %4\n") + .arg(date) + .arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true)) + .arg(type) + .arg(address), icon); + } +} + +void BitcoinGUI::gotoOverviewPage() +{ + overviewAction->setChecked(true); + centralWidget->setCurrentWidget(overviewPage); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +} + +void BitcoinGUI::gotoHistoryPage() +{ + historyAction->setChecked(true); + centralWidget->setCurrentWidget(transactionsPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked())); +} + +void BitcoinGUI::gotoAddressBookPage() +{ + addressBookAction->setChecked(true); + centralWidget->setCurrentWidget(addressBookPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked())); +} + +void BitcoinGUI::gotoReceiveCoinsPage() +{ + receiveCoinsAction->setChecked(true); + centralWidget->setCurrentWidget(receiveCoinsPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked())); +} + +void BitcoinGUI::gotoSendCoinsPage() +{ + sendCoinsAction->setChecked(true); + centralWidget->setCurrentWidget(sendCoinsPage); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +} + +void BitcoinGUI::gotoSignMessageTab(QString addr) +{ +#ifdef FIRST_CLASS_MESSAGING + firstClassMessagingAction->setChecked(true); + centralWidget->setCurrentWidget(signVerifyMessageDialog); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + + signVerifyMessageDialog->showTab_SM(false); +#else + // call show() in showTab_SM() + signVerifyMessageDialog->showTab_SM(true); +#endif + + if(!addr.isEmpty()) + signVerifyMessageDialog->setAddress_SM(addr); +} + +void BitcoinGUI::gotoVerifyMessageTab(QString addr) +{ +#ifdef FIRST_CLASS_MESSAGING + firstClassMessagingAction->setChecked(true); + centralWidget->setCurrentWidget(signVerifyMessageDialog); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + + signVerifyMessageDialog->showTab_VM(false); +#else + // call show() in showTab_VM() + signVerifyMessageDialog->showTab_VM(true); +#endif + + if(!addr.isEmpty()) + signVerifyMessageDialog->setAddress_VM(addr); +} + +void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event) +{ + // Accept only URIs + if(event->mimeData()->hasUrls()) + event->acceptProposedAction(); +} + +void BitcoinGUI::dropEvent(QDropEvent *event) +{ + if(event->mimeData()->hasUrls()) + { + int nValidUrisFound = 0; + QList uris = event->mimeData()->urls(); + foreach(const QUrl &uri, uris) + { + 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 CasinoCoin address or malformed URI parameters.")); + } + + event->acceptProposedAction(); +} + +void BitcoinGUI::handleURI(QString strURI) +{ + // 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 CasinoCoin address or malformed URI parameters.")); +} + +void BitcoinGUI::setEncryptionStatus(int status) +{ + switch(status) + { + case WalletModel::Unencrypted: + labelEncryptionIcon->hide(); + encryptWalletAction->setChecked(false); + changePassphraseAction->setEnabled(false); + encryptWalletAction->setEnabled(true); + break; + case WalletModel::Unlocked: + labelEncryptionIcon->show(); + labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently unlocked")); + encryptWalletAction->setChecked(true); + changePassphraseAction->setEnabled(true); + encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported + break; + case WalletModel::Locked: + labelEncryptionIcon->show(); + labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently locked")); + encryptWalletAction->setChecked(true); + changePassphraseAction->setEnabled(true); + encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported + break; + } +} + +void BitcoinGUI::encryptWallet(bool status) +{ + if(!walletModel) + return; + AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt: + AskPassphraseDialog::Decrypt, this); + dlg.setModel(walletModel); + dlg.exec(); + + setEncryptionStatus(walletModel->getEncryptionStatus()); +} + +void BitcoinGUI::backupWallet() +{ + QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); + QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)")); + if(!filename.isEmpty()) { + if(!walletModel->backupWallet(filename)) { + QMessageBox::warning(this, tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location.")); + } + } +} + +void BitcoinGUI::changePassphrase() +{ + AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this); + dlg.setModel(walletModel); + dlg.exec(); +} + +void BitcoinGUI::unlockWallet() +{ + if(!walletModel) + return; + // Unlock wallet when requested by wallet model + if(walletModel->getEncryptionStatus() == WalletModel::Locked) + { + AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this); + dlg.setModel(walletModel); + dlg.exec(); + } +} + +void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden) +{ + // 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 if(fToggleHidden) + hide(); +} + +void BitcoinGUI::toggleHidden() +{ + showNormalIfMinimized(true); +} diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h new file mode 100644 index 0000000..9e0cd0c --- /dev/null +++ b/src/qt/bitcoingui.h @@ -0,0 +1,180 @@ +#ifndef BITCOINGUI_H +#define BITCOINGUI_H + +#include +#include + +class TransactionTableModel; +class ClientModel; +class WalletModel; +class TransactionView; +class OverviewPage; +class AddressBookPage; +class SendCoinsDialog; +class SignVerifyMessageDialog; +class Notificator; +class RPCConsole; + +QT_BEGIN_NAMESPACE +class QLabel; +class QLineEdit; +class QTableView; +class QAbstractItemModel; +class QModelIndex; +class QProgressBar; +class QStackedWidget; +class QUrl; +QT_END_NAMESPACE + +/** + Bitcoin GUI main class. This class represents the main window of the Bitcoin UI. It communicates with both the client and + wallet models to give the user an up-to-date view of the current core state. +*/ +class BitcoinGUI : public QMainWindow +{ + Q_OBJECT +public: + explicit BitcoinGUI(QWidget *parent = 0); + ~BitcoinGUI(); + + /** Set the client model. + The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic. + */ + void setClientModel(ClientModel *clientModel); + /** Set the wallet model. + The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending + functionality. + */ + void setWalletModel(WalletModel *walletModel); + +protected: + void changeEvent(QEvent *e); + void closeEvent(QCloseEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private: + ClientModel *clientModel; + WalletModel *walletModel; + + QStackedWidget *centralWidget; + + OverviewPage *overviewPage; + QWidget *transactionsPage; + AddressBookPage *addressBookPage; + AddressBookPage *receiveCoinsPage; + SendCoinsDialog *sendCoinsPage; + SignVerifyMessageDialog *signVerifyMessageDialog; + + QLabel *labelEncryptionIcon; + QLabel *labelConnectionsIcon; + QLabel *labelBlocksIcon; + QLabel *progressBarLabel; + QProgressBar *progressBar; + + QMenuBar *appMenuBar; + QAction *overviewAction; + QAction *historyAction; + QAction *quitAction; + QAction *sendCoinsAction; + QAction *addressBookAction; + QAction *signMessageAction; + QAction *verifyMessageAction; + QAction *firstClassMessagingAction; + QAction *aboutAction; + QAction *receiveCoinsAction; + QAction *optionsAction; + QAction *toggleHideAction; + QAction *exportAction; + QAction *encryptWalletAction; + QAction *backupWalletAction; + QAction *changePassphraseAction; + QAction *aboutQtAction; + QAction *openRPCConsoleAction; + + QSystemTrayIcon *trayIcon; + Notificator *notificator; + TransactionView *transactionView; + RPCConsole *rpcConsole; + + QMovie *syncIconMovie; + + /** Create the main UI actions. */ + void createActions(); + /** Create the menu bar and submenus. */ + void createMenuBar(); + /** Create the toolbars */ + void createToolBars(); + /** Create system tray (notification) icon */ + void createTrayIcon(); + +public slots: + /** Set number of connections shown in the UI */ + void setNumConnections(int count); + /** Set number of blocks shown in the UI */ + void setNumBlocks(int count, int countOfPeers); + /** Set the encryption status as shown in the UI. + @param[in] status current encryption status + @see WalletModel::EncryptionStatus + */ + void setEncryptionStatus(int status); + + /** Notify the user of an error in the network or transaction handling code. */ + void error(const QString &title, const QString &message, bool modal); + /** Asks the user whether to pay the transaction fee or to cancel the transaction. + It is currently not possible to pass a return value to another thread through + BlockingQueuedConnection, so an indirected pointer is used. + http://bugreports.qt.nokia.com/browse/QTBUG-10440 + + @param[in] nFeeRequired the required fee + @param[out] payFee true to pay the fee, false to not pay the fee + */ + void askFee(qint64 nFeeRequired, bool *payFee); + void handleURI(QString strURI); + +private slots: + /** Switch to overview (home) page */ + void gotoOverviewPage(); + /** Switch to history (transactions) page */ + void gotoHistoryPage(); + /** Switch to address book page */ + void gotoAddressBookPage(); + /** Switch to receive coins page */ + void gotoReceiveCoinsPage(); + /** Switch to send coins page */ + void gotoSendCoinsPage(); + + /** Show Sign/Verify Message dialog and switch to sign message tab */ + void gotoSignMessageTab(QString addr = ""); + /** Show Sign/Verify Message dialog and switch to verify message tab */ + void gotoVerifyMessageTab(QString addr = ""); + + /** Show configuration dialog */ + void optionsClicked(); + /** Show about dialog */ + void aboutClicked(); +#ifndef Q_WS_MAC + /** Handle tray icon clicked */ + void trayIconActivated(QSystemTrayIcon::ActivationReason reason); +#endif + /** Show incoming transaction notification for new transactions. + + The new items are those between start and end inclusive, under the given parent item. + */ + void incomingTransaction(const QModelIndex & parent, int start, int end); + /** Encrypt the wallet */ + void encryptWallet(bool status); + /** Backup the wallet */ + void backupWallet(); + /** Change encrypted wallet passphrase */ + void changePassphrase(); + /** Ask for pass phrase to unlock wallet temporarily */ + void unlockWallet(); + + /** 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(); +}; + +#endif diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp new file mode 100644 index 0000000..2fe9f8b --- /dev/null +++ b/src/qt/bitcoinstrings.cpp @@ -0,0 +1,148 @@ +#include +// Automatically generated by extract_strings.py +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif +static const char UNUSED *bitcoin_strings[] = { +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" +"rpcuser=casinocoinrpc\n" +"rpcpassword=%s\n" +"(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", "" +"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:" +"@STRENGTH)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Cannot obtain a lock on data directory %s. CasinoCoin 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. CasinoCoin 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 CasinoCoin will not work properly."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"You must set rpcpassword= 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", "" +"\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", "CasinoCoin version"), +QT_TRANSLATE_NOOP("bitcoin-core", "CasinoCoin"), +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 CasinoCoin"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: Transaction creation failed "), +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 unless -connect)"), +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 -tor address: '%s'"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=: '%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 (default: 9332)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on (default: 9333 or testnet: 19333)"), +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 connections to peers (default: 125)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, *1000 bytes (default: 5000)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, *1000 bytes (default: 1000)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network (IPv4, IPv6 or Tor)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Options:"), +QT_TRANSLATE_NOOP("bitcoin-core", "Output extra debugging information. Implies all other -debug* options"), +QT_TRANSLATE_NOOP("bitcoin-core", "Output extra network 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 casinocoind"), +QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on (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 (default: 100)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: casinocoin.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: casinocoind.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 proxy to reach tor hidden services (default: same as -proxy)"), +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 CasinoCoin to complete"), +QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low"), +QT_TRANSLATE_NOOP("bitcoin-core", "Warning: this version is obsolete, upgrade required"), +}; diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp new file mode 100644 index 0000000..9db1f53 --- /dev/null +++ b/src/qt/bitcoinunits.cpp @@ -0,0 +1,181 @@ +#include "bitcoinunits.h" + +#include + +BitcoinUnits::BitcoinUnits(QObject *parent): + QAbstractListModel(parent), + unitlist(availableUnits()) +{ +} + +QList BitcoinUnits::availableUnits() +{ + QList unitlist; + unitlist.append(BTC); + unitlist.append(mBTC); + unitlist.append(uBTC); + return unitlist; +} + +bool BitcoinUnits::valid(int unit) +{ + switch(unit) + { + case BTC: + case mBTC: + case uBTC: + return true; + default: + return false; + } +} + +QString BitcoinUnits::name(int unit) +{ + switch(unit) + { + case BTC: return QString("CSC"); + case mBTC: return QString("mCSC"); + case uBTC: return QString::fromUtf8("μCSC"); + default: return QString("???"); + } +} + +QString BitcoinUnits::description(int unit) +{ + switch(unit) + { + case BTC: return QString("CasinoCoins"); + case mBTC: return QString("Milli-CasinoCoins (1 / 1,000)"); + case uBTC: return QString("Micro-CasinoCoins (1 / 1,000,000)"); + default: return QString("???"); + } +} + +qint64 BitcoinUnits::factor(int unit) +{ + switch(unit) + { + case BTC: return 100000000; + case mBTC: return 100000; + case uBTC: return 100; + default: return 100000000; + } +} + +int BitcoinUnits::amountDigits(int unit) +{ + switch(unit) + { + case BTC: return 8; // 21,000,000 (# digits, without commas) + case mBTC: return 11; // 21,000,000,000 + case uBTC: return 14; // 21,000,000,000,000 + default: return 0; + } +} + +int BitcoinUnits::decimals(int unit) +{ + switch(unit) + { + case BTC: return 8; + case mBTC: return 5; + case uBTC: return 2; + default: return 0; + } +} + +QString BitcoinUnits::format(int unit, qint64 n, bool fPlus) +{ + // Note: not using straight sprintf here because we do NOT want + // localized number formatting. + if(!valid(unit)) + return QString(); // Refuse to format invalid unit + qint64 coin = factor(unit); + int num_decimals = decimals(unit); + qint64 n_abs = (n > 0 ? n : -n); + qint64 quotient = n_abs / coin; + qint64 remainder = n_abs % coin; + QString quotient_str = QString::number(quotient); + QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0'); + + // Right-trim excess 0's after the decimal point + int nTrim = 0; + for (int i = remainder_str.size()-1; i>=2 && (remainder_str.at(i) == '0'); --i) + ++nTrim; + remainder_str.chop(nTrim); + + if (n < 0) + quotient_str.insert(0, '-'); + else if (fPlus && n > 0) + quotient_str.insert(0, '+'); + return quotient_str + QString(".") + remainder_str; +} + +QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign) +{ + return format(unit, amount, plussign) + QString(" ") + name(unit); +} + +bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out) +{ + if(!valid(unit) || value.isEmpty()) + return false; // Refuse to parse invalid unit or empty string + int num_decimals = decimals(unit); + QStringList parts = value.split("."); + + if(parts.size() > 2) + { + return false; // More than one dot + } + QString whole = parts[0]; + QString decimals; + + if(parts.size() > 1) + { + decimals = parts[1]; + } + if(decimals.size() > num_decimals) + { + return false; // Exceeds max precision + } + bool ok = false; + QString str = whole + decimals.leftJustified(num_decimals, '0'); + + if(str.size() > 18) + { + return false; // Longer numbers will exceed 63 bits + } + qint64 retvalue = str.toLongLong(&ok); + if(val_out) + { + *val_out = retvalue; + } + return ok; +} + +int BitcoinUnits::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return unitlist.size(); +} + +QVariant BitcoinUnits::data(const QModelIndex &index, int role) const +{ + int row = index.row(); + if(row >= 0 && row < unitlist.size()) + { + Unit unit = unitlist.at(row); + switch(role) + { + case Qt::EditRole: + case Qt::DisplayRole: + return QVariant(name(unit)); + case Qt::ToolTipRole: + return QVariant(description(unit)); + case UnitRole: + return QVariant(static_cast(unit)); + } + } + return QVariant(); +} diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h new file mode 100644 index 0000000..18fa36a --- /dev/null +++ b/src/qt/bitcoinunits.h @@ -0,0 +1,66 @@ +#ifndef BITCOINUNITS_H +#define BITCOINUNITS_H + +#include +#include + +/** Bitcoin unit definitions. Encapsulates parsing and formatting + and serves as list model for dropdown selection boxes. +*/ +class BitcoinUnits: public QAbstractListModel +{ +public: + explicit BitcoinUnits(QObject *parent); + + /** Bitcoin units. + @note Source: https://en.bitcoin.it/wiki/Units . Please add only sensible ones + */ + enum Unit + { + BTC, + mBTC, + uBTC + }; + + //! @name Static API + //! Unit conversion and formatting + ///@{ + + //! Get list of units, for dropdown box + static QList availableUnits(); + //! Is unit ID valid? + static bool valid(int unit); + //! Short name + static QString name(int unit); + //! Longer description + static QString description(int unit); + //! Number of Satoshis (1e-8) per unit + static qint64 factor(int unit); + //! Number of amount digits (to represent max number of coins) + static int amountDigits(int unit); + //! Number of decimals left + static int decimals(int unit); + //! Format as string + static QString format(int unit, qint64 amount, bool plussign=false); + //! Format as string (with unit) + static QString formatWithUnit(int unit, qint64 amount, bool plussign=false); + //! Parse string to coin amount + static bool parse(int unit, const QString &value, qint64 *val_out); + ///@} + + //! @name AbstractListModel implementation + //! List model for unit dropdown selection box. + ///@{ + enum RoleIndex { + /** Unit identifier */ + UnitRole = Qt::UserRole + }; + int rowCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + ///@} +private: + QList unitlist; +}; +typedef BitcoinUnits::Unit BitcoinUnit; + +#endif // BITCOINUNITS_H diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp new file mode 100644 index 0000000..c86c9a6 --- /dev/null +++ b/src/qt/clientmodel.cpp @@ -0,0 +1,209 @@ +#include "clientmodel.h" +#include "guiconstants.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" +#include "transactiontablemodel.h" + +#include "main.h" +#include "init.h" // for pwalletMain +#include "ui_interface.h" + +#include +#include + +static const int64 nClientStartupTime = GetTime(); + +ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : + QObject(parent), optionsModel(optionsModel), + cachedNumBlocks(0), cachedNumBlocksOfPeers(0), cachedHashrate(0), pollTimer(0) +{ + numBlocksAtStartup = -1; + + pollTimer = new QTimer(this); + pollTimer->setInterval(MODEL_UPDATE_DELAY); + pollTimer->start(); + connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); + + subscribeToCoreSignals(); +} + +ClientModel::~ClientModel() +{ + unsubscribeFromCoreSignals(); +} + +int ClientModel::getNumConnections() const +{ + return vNodes.size(); +} + +int ClientModel::getNumBlocks() const +{ + return nBestHeight; +} + +int ClientModel::getNumBlocksAtStartup() +{ + if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks(); + return numBlocksAtStartup; +} + +int ClientModel::getHashrate() const +{ + if (GetTimeMillis() - nHPSTimerStart > 8000) + return (boost::int64_t)0; + return (boost::int64_t)dHashesPerSec; +} + +// CasinoCoin: copied from bitcoinrpc.cpp. +double ClientModel::GetDifficulty() const +{ + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + + if (pindexBest == NULL) + return 1.0; + int nShift = (pindexBest->nBits >> 24) & 0xff; + + double dDiff = + (double)0x0000ffff / (double)(pindexBest->nBits & 0x00ffffff); + + while (nShift < 29) + { + dDiff *= 256.0; + nShift++; + } + while (nShift > 29) + { + dDiff /= 256.0; + nShift--; + } + + return dDiff; +} + +QDateTime ClientModel::getLastBlockDate() const +{ + return QDateTime::fromTime_t(pindexBest->GetBlockTime()); +} + +void ClientModel::updateTimer() +{ + // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change. + // Periodically check and update with a timer. + int newNumBlocks = getNumBlocks(); + int newNumBlocksOfPeers = getNumBlocksOfPeers(); + + if(cachedNumBlocks != newNumBlocks || cachedNumBlocksOfPeers != newNumBlocksOfPeers) + emit numBlocksChanged(newNumBlocks, newNumBlocksOfPeers); + + cachedNumBlocks = newNumBlocks; + cachedNumBlocksOfPeers = newNumBlocksOfPeers; +} + +void ClientModel::updateNumConnections(int numConnections) +{ + emit numConnectionsChanged(numConnections); +} + +void ClientModel::updateAlert(const QString &hash, int status) +{ + // Show error message notification for new alert + if(status == CT_NEW) + { + uint256 hash_256; + hash_256.SetHex(hash.toStdString()); + CAlert alert = CAlert::getAlertByHash(hash_256); + if(!alert.IsNull()) + { + emit error(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), false); + } + } + + // Emit a numBlocksChanged when the status message changes, + // so that the view recomputes and updates the status bar. + emit numBlocksChanged(getNumBlocks(), getNumBlocksOfPeers()); +} + +bool ClientModel::isTestNet() const +{ + return fTestNet; +} + +bool ClientModel::inInitialBlockDownload() const +{ + return IsInitialBlockDownload(); +} + +int ClientModel::getNumBlocksOfPeers() const +{ + return GetNumBlocksOfPeers(); +} + +QString ClientModel::getStatusBarWarnings() const +{ + return QString::fromStdString(GetWarnings("statusbar")); +} + +OptionsModel *ClientModel::getOptionsModel() +{ + return optionsModel; +} + +QString ClientModel::formatFullVersion() const +{ + return QString::fromStdString(FormatFullVersion()); +} + +QString ClientModel::formatBuildDate() const +{ + return QString::fromStdString(CLIENT_DATE); +} + +QString ClientModel::clientName() const +{ + return QString::fromStdString(CLIENT_NAME); +} + +QString ClientModel::formatClientStartupTime() const +{ + return QDateTime::fromTime_t(nClientStartupTime).toString(); +} + +// Handlers for core signals +static void NotifyBlocksChanged(ClientModel *clientmodel) +{ + // This notification is too frequent. Don't trigger a signal. + // Don't remove it, though, as it might be useful later. +} + +static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections) +{ + // Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections); + QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection, + Q_ARG(int, newNumConnections)); +} + +static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status) +{ + OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status); + QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(hash.GetHex())), + Q_ARG(int, status)); +} + +void ClientModel::subscribeToCoreSignals() +{ + // Connect signals to client + uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this)); + uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); + uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); +} + +void ClientModel::unsubscribeFromCoreSignals() +{ + // Disconnect signals from client + uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this)); + uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); + uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); +} diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h new file mode 100644 index 0000000..fff9634 --- /dev/null +++ b/src/qt/clientmodel.h @@ -0,0 +1,75 @@ +#ifndef CLIENTMODEL_H +#define CLIENTMODEL_H + +#include + +class OptionsModel; +class AddressTableModel; +class TransactionTableModel; +class CWallet; + +QT_BEGIN_NAMESPACE +class QDateTime; +class QTimer; +QT_END_NAMESPACE + +/** Model for Bitcoin network client. */ +class ClientModel : public QObject +{ + Q_OBJECT +public: + explicit ClientModel(OptionsModel *optionsModel, QObject *parent = 0); + ~ClientModel(); + + OptionsModel *getOptionsModel(); + + int getNumConnections() const; + int getNumBlocks() const; + int getNumBlocksAtStartup(); + + int getHashrate() const; + double GetDifficulty() const; + + QDateTime getLastBlockDate() const; + + //! Return true if client connected to testnet + bool isTestNet() const; + //! Return true if core is doing initial block download + bool inInitialBlockDownload() const; + //! Return conservative estimate of total number of blocks, or 0 if unknown + int getNumBlocksOfPeers() const; + //! Return warnings to be displayed in status bar + QString getStatusBarWarnings() const; + + QString formatFullVersion() const; + QString formatBuildDate() const; + QString clientName() const; + QString formatClientStartupTime() const; + +private: + OptionsModel *optionsModel; + + int cachedNumBlocks; + int cachedNumBlocksOfPeers; + int cachedHashrate; + + int numBlocksAtStartup; + + QTimer *pollTimer; + + void subscribeToCoreSignals(); + void unsubscribeFromCoreSignals(); +signals: + void numConnectionsChanged(int count); + void numBlocksChanged(int count, int countOfPeers); + + //! Asynchronous error notification + void error(const QString &title, const QString &message, bool modal); + +public slots: + void updateTimer(); + void updateNumConnections(int numConnections); + void updateAlert(const QString &hash, int status); +}; + +#endif // CLIENTMODEL_H diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp new file mode 100644 index 0000000..8a50bba --- /dev/null +++ b/src/qt/csvmodelwriter.cpp @@ -0,0 +1,88 @@ +#include "csvmodelwriter.h" + +#include +#include +#include + +CSVModelWriter::CSVModelWriter(const QString &filename, QObject *parent) : + QObject(parent), + filename(filename), model(0) +{ +} + +void CSVModelWriter::setModel(const QAbstractItemModel *model) +{ + this->model = model; +} + +void CSVModelWriter::addColumn(const QString &title, int column, int role) +{ + Column col; + col.title = title; + col.column = column; + col.role = role; + + columns.append(col); +} + +static void writeValue(QTextStream &f, const QString &value) +{ + QString escaped = value; + escaped.replace('"', "\"\""); + f << "\"" << escaped << "\""; +} + +static void writeSep(QTextStream &f) +{ + f << ","; +} + +static void writeNewline(QTextStream &f) +{ + f << "\n"; +} + +bool CSVModelWriter::write() +{ + QFile file(filename); + if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) + return false; + QTextStream out(&file); + + int numRows = 0; + if(model) + { + numRows = model->rowCount(); + } + + // Header row + for(int i=0; iindex(j, columns[i].column).data(columns[i].role); + writeValue(out, data.toString()); + } + writeNewline(out); + } + + file.close(); + + return file.error() == QFile::NoError; +} + diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h new file mode 100644 index 0000000..6c9dcba --- /dev/null +++ b/src/qt/csvmodelwriter.h @@ -0,0 +1,46 @@ +#ifndef CSVMODELWRITER_H +#define CSVMODELWRITER_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QAbstractItemModel; +QT_END_NAMESPACE + +/** Export a Qt table model to a CSV file. This is useful for analyzing or post-processing the data in + a spreadsheet. + */ +class CSVModelWriter : public QObject +{ + Q_OBJECT +public: + explicit CSVModelWriter(const QString &filename, QObject *parent = 0); + + void setModel(const QAbstractItemModel *model); + void addColumn(const QString &title, int column, int role=Qt::EditRole); + + /** Perform export of the model to CSV. + @returns true on success, false otherwise + */ + bool write(); + +private: + QString filename; + const QAbstractItemModel *model; + + struct Column + { + QString title; + int column; + int role; + }; + QList columns; + +signals: + +public slots: + +}; + +#endif // CSVMODELWRITER_H diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp new file mode 100644 index 0000000..62cda51 --- /dev/null +++ b/src/qt/editaddressdialog.cpp @@ -0,0 +1,128 @@ +#include "editaddressdialog.h" +#include "ui_editaddressdialog.h" +#include "addresstablemodel.h" +#include "guiutil.h" + +#include +#include + +EditAddressDialog::EditAddressDialog(Mode mode, QWidget *parent) : + QDialog(parent), + ui(new Ui::EditAddressDialog), mapper(0), mode(mode), model(0) +{ + ui->setupUi(this); + + GUIUtil::setupAddressWidget(ui->addressEdit, this); + + switch(mode) + { + case NewReceivingAddress: + setWindowTitle(tr("New receiving address")); + ui->addressEdit->setEnabled(false); + break; + case NewSendingAddress: + setWindowTitle(tr("New sending address")); + break; + case EditReceivingAddress: + setWindowTitle(tr("Edit receiving address")); + ui->addressEdit->setDisabled(true); + break; + case EditSendingAddress: + setWindowTitle(tr("Edit sending address")); + break; + } + + mapper = new QDataWidgetMapper(this); + mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); +} + +EditAddressDialog::~EditAddressDialog() +{ + delete ui; +} + +void EditAddressDialog::setModel(AddressTableModel *model) +{ + this->model = model; + mapper->setModel(model); + mapper->addMapping(ui->labelEdit, AddressTableModel::Label); + mapper->addMapping(ui->addressEdit, AddressTableModel::Address); +} + +void EditAddressDialog::loadRow(int row) +{ + mapper->setCurrentIndex(row); +} + +bool EditAddressDialog::saveCurrentRow() +{ + if(!model) + return false; + switch(mode) + { + case NewReceivingAddress: + case NewSendingAddress: + address = model->addRow( + mode == NewSendingAddress ? AddressTableModel::Send : AddressTableModel::Receive, + ui->labelEdit->text(), + ui->addressEdit->text()); + break; + case EditReceivingAddress: + case EditSendingAddress: + if(mapper->submit()) + { + address = ui->addressEdit->text(); + } + break; + } + return !address.isEmpty(); +} + +void EditAddressDialog::accept() +{ + if(!model) + return; + if(!saveCurrentRow()) + { + switch(model->getEditStatus()) + { + case AddressTableModel::DUPLICATE_ADDRESS: + QMessageBox::warning(this, windowTitle(), + tr("The entered address \"%1\" is already in the address book.").arg(ui->addressEdit->text()), + QMessageBox::Ok, QMessageBox::Ok); + break; + case AddressTableModel::INVALID_ADDRESS: + QMessageBox::warning(this, windowTitle(), + tr("The entered address \"%1\" is not a valid CasinoCoin address.").arg(ui->addressEdit->text()), + QMessageBox::Ok, QMessageBox::Ok); + return; + case AddressTableModel::WALLET_UNLOCK_FAILURE: + QMessageBox::critical(this, windowTitle(), + tr("Could not unlock wallet."), + QMessageBox::Ok, QMessageBox::Ok); + return; + case AddressTableModel::KEY_GENERATION_FAILURE: + QMessageBox::critical(this, windowTitle(), + tr("New key generation failed."), + QMessageBox::Ok, QMessageBox::Ok); + return; + case AddressTableModel::OK: + // Failed with unknown reason. Just reject. + break; + } + + return; + } + QDialog::accept(); +} + +QString EditAddressDialog::getAddress() const +{ + return address; +} + +void EditAddressDialog::setAddress(const QString &address) +{ + this->address = address; + ui->addressEdit->setText(address); +} diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h new file mode 100644 index 0000000..7ec053f --- /dev/null +++ b/src/qt/editaddressdialog.h @@ -0,0 +1,50 @@ +#ifndef EDITADDRESSDIALOG_H +#define EDITADDRESSDIALOG_H + +#include + +QT_BEGIN_NAMESPACE +class QDataWidgetMapper; +QT_END_NAMESPACE + +namespace Ui { + class EditAddressDialog; +} +class AddressTableModel; + +/** Dialog for editing an address and associated information. + */ +class EditAddressDialog : public QDialog +{ + Q_OBJECT + +public: + enum Mode { + NewReceivingAddress, + NewSendingAddress, + EditReceivingAddress, + EditSendingAddress + }; + + explicit EditAddressDialog(Mode mode, QWidget *parent = 0); + ~EditAddressDialog(); + + void setModel(AddressTableModel *model); + void loadRow(int row); + + void accept(); + + QString getAddress() const; + void setAddress(const QString &address); +private: + bool saveCurrentRow(); + + Ui::EditAddressDialog *ui; + QDataWidgetMapper *mapper; + Mode mode; + AddressTableModel *model; + + QString address; +}; + +#endif // EDITADDRESSDIALOG_H diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui new file mode 100644 index 0000000..f920167 --- /dev/null +++ b/src/qt/forms/aboutdialog.ui @@ -0,0 +1,183 @@ + + + AboutDialog + + + + 0 + 0 + 593 + 400 + + + + About CasinoCoin + + + + + + + 0 + 0 + + + + :/images/about + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + IBeamCursor + + + <b>CasinoCoin</b> version + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + IBeamCursor + + + 0.3.666-beta + + + Qt::RichText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + IBeamCursor + + + + Copyright © 2009-2012 Bitcoin Developers + Copyright © 2011-2012 Litecoin Developers + Copyright © 2013 CasinoCoin Developers + + This is experimental software. + + Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php. + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + Official forum: http://forum.casinoco.in + + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + + + + + buttonBox + accepted() + AboutDialog + accept() + + + 360 + 308 + + + 157 + 274 + + + + + buttonBox + rejected() + AboutDialog + reject() + + + 428 + 308 + + + 286 + 274 + + + + + diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui new file mode 100644 index 0000000..b4368e7 --- /dev/null +++ b/src/qt/forms/addressbookpage.ui @@ -0,0 +1,175 @@ + + + AddressBookPage + + + + 0 + 0 + 760 + 380 + + + + Address Book + + + + + + These are your CasinoCoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + + + Qt::PlainText + + + true + + + + + + + Qt::CustomContextMenu + + + Double-click to edit address or label + + + false + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + false + + + + + + + + + Create a new address + + + &New Address + + + + :/icons/add:/icons/add + + + + + + + Copy the currently selected address to the system clipboard + + + &Copy Address + + + + :/icons/editcopy:/icons/editcopy + + + + + + + Show &QR Code + + + + :/icons/qrcode:/icons/qrcode + + + + + + + Sign a message to prove you own a Bitcoin address + + + &Sign Message + + + + :/icons/edit:/icons/edit + + + + + + + Verify a message to ensure it was signed with a specified Bitcoin address + + + &Verify Message + + + + :/icons/transaction_0:/icons/transaction_0 + + + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + + + &Delete + + + + :/icons/remove:/icons/remove + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + QDialogButtonBox::Ok + + + + + + + + + + + + diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui new file mode 100644 index 0000000..2516904 --- /dev/null +++ b/src/qt/forms/askpassphrasedialog.ui @@ -0,0 +1,151 @@ + + + AskPassphraseDialog + + + + 0 + 0 + 598 + 198 + + + + + 0 + 0 + + + + + 550 + 0 + + + + Passphrase Dialog + + + + + + Qt::RichText + + + true + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Enter passphrase + + + + + + + QLineEdit::Password + + + + + + + New passphrase + + + + + + + QLineEdit::Password + + + + + + + Repeat new passphrase + + + + + + + QLineEdit::Password + + + + + + + + 75 + true + + + + + + + Qt::AlignCenter + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AskPassphraseDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AskPassphraseDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/forms/editaddressdialog.ui b/src/qt/forms/editaddressdialog.ui new file mode 100644 index 0000000..b4a4c1b --- /dev/null +++ b/src/qt/forms/editaddressdialog.ui @@ -0,0 +1,105 @@ + + + EditAddressDialog + + + + 0 + 0 + 457 + 126 + + + + Edit Address + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + &Label + + + labelEdit + + + + + + + The label associated with this address book entry + + + + + + + &Address + + + addressEdit + + + + + + + The address associated with this address book entry. This can only be modified for sending addresses. + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + EditAddressDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + EditAddressDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui new file mode 100644 index 0000000..62605b4 --- /dev/null +++ b/src/qt/forms/optionsdialog.ui @@ -0,0 +1,466 @@ + + + OptionsDialog + + + + 0 + 0 + 540 + 380 + + + + Options + + + true + + + + + + QTabWidget::North + + + 1 + + + + &Main + + + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + Qt::PlainText + + + true + + + + + + + + + Pay transaction &fee + + + Qt::PlainText + + + transactionFee + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Automatically start CasinoCoin after logging in to the system. + + + &Start CasinoCoin on system login + + + + + + + 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. + + + &Detach databases at shutdown + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + &Network + + + + + + Automatically open the CasinoCoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + Map port using &UPnP + + + + + + + Connect to the CasinoCoin network through a SOCKS proxy (e.g. when connecting through Tor). + + + &Connect through SOCKS proxy: + + + + + + + + + Proxy &IP: + + + Qt::PlainText + + + proxyIp + + + + + + + + 140 + 16777215 + + + + IP address of the proxy (e.g. 127.0.0.1) + + + + + + + &Port: + + + Qt::PlainText + + + proxyPort + + + + + + + + 55 + 16777215 + + + + Port of the proxy (e.g. 9050) + + + + + + + SOCKS &Version: + + + Qt::PlainText + + + socksVersion + + + + + + + SOCKS version of the proxy (e.g. 5) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + &Window + + + + + + Show only a tray icon after minimizing the window. + + + &Minimize to the tray instead of the taskbar + + + + + + + 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. + + + M&inimize on close + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + &Display + + + + + + + + User Interface &language: + + + Qt::PlainText + + + lang + + + + + + + The user interface language can be set here. This setting will take effect after restarting CasinoCoin. + + + + + + + + + + + &Unit to show amounts in: + + + Qt::PlainText + + + unit + + + + + + + Choose the default subdivision unit to show in the interface and when sending coins. + + + + + + + + + Whether to show CasinoCoin addresses in the transaction list or not. + + + &Display addresses in transaction list + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + 75 + true + + + + + + + Qt::PlainText + + + true + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + &OK + + + + + + + &Cancel + + + false + + + + + + + &Apply + + + false + + + false + + + false + + + + + + + + + + BitcoinAmountField + QSpinBox +
bitcoinamountfield.h
+
+ + QValueComboBox + QComboBox +
qvaluecombobox.h
+
+ + QValidatedLineEdit + QLineEdit +
qvalidatedlineedit.h
+
+
+ + +
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui new file mode 100644 index 0000000..a229e04 --- /dev/null +++ b/src/qt/forms/overviewpage.ui @@ -0,0 +1,320 @@ + + + OverviewPage + + + + 0 + 0 + 573 + 342 + + + + Form + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + 11 + 75 + true + + + + Wallet + + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the CasinoCoin network after a connection is established, but this process has not completed yet. + + + QLabel { color: red; } + + + (out of sync) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + 12 + + + 12 + + + + + Balance: + + + + + + + + 75 + true + + + + IBeamCursor + + + Your current balance + + + 0 CSC + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Unconfirmed: + + + + + + + + 75 + true + + + + IBeamCursor + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + 0 CSC + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Number of transactions: + + + + + + + Total number of transactions in wallet + + + 0 + + + + + + + Immature: + + + + + + + + 75 + true + + + + Mined balance that has not yet matured + + + 0 CSC + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + :/images/backg + + + false + + + Qt::AlignCenter + + + -2 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + <b>Recent transactions</b> + + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the CasinoCoin network after a connection is established, but this process has not completed yet. + + + QLabel { color: red; } + + + (out of sync) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QListView { background: transparent; } + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoSelection + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + diff --git a/src/qt/forms/qrcodedialog.ui b/src/qt/forms/qrcodedialog.ui new file mode 100644 index 0000000..52e9db3 --- /dev/null +++ b/src/qt/forms/qrcodedialog.ui @@ -0,0 +1,212 @@ + + + QRCodeDialog + + + + 0 + 0 + 340 + 530 + + + + QR Code Dialog + + + + + + + 0 + 0 + + + + + 300 + 300 + + + + Qt::PlainText + + + Qt::AlignCenter + + + true + + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + true + + + Request Payment + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Label: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lnLabel + + + + + + + + + + Message: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lnMessage + + + + + + + + + + + 0 + 0 + + + + Amount: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lnReqAmount + + + + + + + false + + + + 80 + 0 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Save As... + + + + + + + + + + + + + BitcoinAmountField + QSpinBox +
bitcoinamountfield.h
+
+
+ + + + chkReqPayment + clicked(bool) + lnReqAmount + setEnabled(bool) + + + 92 + 285 + + + 98 + 311 + + + + +
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui new file mode 100644 index 0000000..3462425 --- /dev/null +++ b/src/qt/forms/rpcconsole.ui @@ -0,0 +1,436 @@ + + + RPCConsole + + + + 0 + 0 + 740 + 450 + + + + CasinoCoin - Debug window + + + + + + 0 + + + + &Information + + + + 12 + + + + + + 75 + true + + + + Bitcoin Core + + + + + + + Client name + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Client version + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Using OpenSSL version + + + 10 + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Startup time + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + 75 + true + + + + Network + + + + + + + Number of connections + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + On testnet + + + + + + + false + + + + + + + + + + + 75 + true + + + + Block chain + + + + + + + Current number of blocks + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Estimated total blocks + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Last block time + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + 75 + true + + + + Debug logfile + + + + + + + Open the CasinoCoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + &Open + + + false + + + + + + + + 75 + true + + + + Command-line options + + + + + + + Show the CasinoCoin-Qt help message to get a list with possible CasinoCoin command-line options. + + + &Show + + + false + + + false + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + &Console + + + + 3 + + + + + + 0 + 100 + + + + true + + + false + + + 2 + + + + + + + 3 + + + + + > + + + + + + + + + + + 24 + 24 + + + + Clear console + + + + + + + :/icons/remove:/icons/remove + + + Ctrl+L + + + false + + + + + + + + + + + + + + + + diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui new file mode 100644 index 0000000..5c333d8 --- /dev/null +++ b/src/qt/forms/sendcoinsdialog.ui @@ -0,0 +1,175 @@ + + + SendCoinsDialog + + + + 0 + 0 + 686 + 217 + + + + Send Coins + + + + + + true + + + + + 0 + 0 + 666 + 165 + + + + + 0 + + + + + 6 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Send to multiple recipients at once + + + &Add Recipient + + + + :/icons/add:/icons/add + + + false + + + + + + + + 0 + 0 + + + + Remove all transaction fields + + + Clear &All + + + + :/icons/remove:/icons/remove + + + 300 + + + false + + + + + + + 3 + + + + + Balance: + + + + + + + IBeamCursor + + + 123.456 CSC + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 150 + 0 + + + + Confirm the send action + + + &Send + + + + :/icons/send:/icons/send + + + true + + + + + + + + + + + + diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui new file mode 100644 index 0000000..22a3f8f --- /dev/null +++ b/src/qt/forms/sendcoinsentry.ui @@ -0,0 +1,169 @@ + + + SendCoinsEntry + + + + 0 + 0 + 729 + 136 + + + + Form + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 12 + + + + + A&mount: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + payAmount + + + + + + + Pay &To: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + payTo + + + + + + + + + + 0 + + + + + true + + + Enter a label for this address to add it to your address book + + + + + + + + + &Label: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + addAsLabel + + + + + + + 0 + + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + 34 + + + + + + + Choose address from address book + + + + + + + :/icons/address-book:/icons/address-book + + + Alt+A + + + + + + + Paste address from clipboard + + + + + + + :/icons/editpaste:/icons/editpaste + + + Alt+P + + + + + + + Remove this recipient + + + + + + + :/icons/remove:/icons/remove + + + + + + + + + + BitcoinAmountField + QLineEdit +
bitcoinamountfield.h
+ 1 +
+ + QValidatedLineEdit + QLineEdit +
qvalidatedlineedit.h
+
+
+ + + + +
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui new file mode 100644 index 0000000..8128bdf --- /dev/null +++ b/src/qt/forms/signverifymessagedialog.ui @@ -0,0 +1,386 @@ + + + SignVerifyMessageDialog + + + + 0 + 0 + 700 + 380 + + + + Signatures - Sign / Verify a Message + + + true + + + + + + 0 + + + + &Sign Message + + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + Qt::PlainText + + + true + + + + + + + 0 + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + 34 + + + + + + + Choose an address from the address book + + + + + + + :/icons/address-book:/icons/address-book + + + Alt+A + + + false + + + + + + + Paste address from clipboard + + + + + + + :/icons/editpaste:/icons/editpaste + + + Alt+P + + + false + + + + + + + + + Enter the message you want to sign here + + + + + + + 0 + + + + + + true + + + + true + + + + + + + Copy the current signature to the system clipboard + + + + + + + :/icons/editcopy:/icons/editcopy + + + false + + + + + + + + + + + Sign the message to prove you own this Bitcoin address + + + &Sign Message + + + + :/icons/edit:/icons/edit + + + false + + + + + + + Reset all sign message fields + + + Clear &All + + + + :/icons/remove:/icons/remove + + + false + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + 75 + true + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + + + &Verify Message + + + + + + Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + + + Qt::PlainText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + 0 + + + + + The address the message was signed with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + 34 + + + + + + + Choose an address from the address book + + + + + + + :/icons/address-book:/icons/address-book + + + Alt+A + + + false + + + + + + + + + + + + + + + + + Verify the message to ensure it was signed with the specified Bitcoin address + + + &Verify Message + + + + :/icons/transaction_0:/icons/transaction_0 + + + false + + + + + + + Reset all verify message fields + + + Clear &All + + + + :/icons/remove:/icons/remove + + + false + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + 75 + true + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 48 + + + + + + + + + + + + + + + QValidatedLineEdit + QLineEdit +
qvalidatedlineedit.h
+
+
+ + + + +
diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/transactiondescdialog.ui new file mode 100644 index 0000000..b38dffc --- /dev/null +++ b/src/qt/forms/transactiondescdialog.ui @@ -0,0 +1,74 @@ + + + TransactionDescDialog + + + + 0 + 0 + 620 + 250 + + + + Transaction details + + + + + + This pane shows a detailed description of the transaction + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + TransactionDescDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + TransactionDescDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h new file mode 100644 index 0000000..405ba39 --- /dev/null +++ b/src/qt/guiconstants.h @@ -0,0 +1,34 @@ +#ifndef GUICONSTANTS_H +#define GUICONSTANTS_H + +/* Milliseconds between model updates */ +static const int MODEL_UPDATE_DELAY = 500; + +/* AskPassphraseDialog -- Maximum passphrase length */ +static const int MAX_PASSPHRASE_SIZE = 1024; + +/* BitcoinGUI -- Size of icons in status bar */ +static const int STATUSBAR_ICONSIZE = 16; + +/* Invalid field background style */ +#define STYLE_INVALID "background:#FF8080" + +/* Transaction list -- unconfirmed transaction */ +#define COLOR_UNCONFIRMED QColor(128, 128, 128) +/* Transaction list -- negative amount */ +#define COLOR_NEGATIVE QColor(255, 0, 0) +/* Transaction list -- bare address (without label) */ +#define COLOR_BAREADDRESS QColor(140, 140, 140) + +/* Tooltips longer than this (in characters) are converted into rich text, + so that they can be word-wrapped. + */ +static const int TOOLTIP_WRAP_THRESHOLD = 80; + +/* Maximum allowed URI length */ +static const int MAX_URI_LENGTH = 255; + +/* QRCodeDialog -- size of exported QR Code image */ +#define EXPORT_IMAGE_SIZE 256 + +#endif // GUICONSTANTS_H diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp new file mode 100644 index 0000000..660234c --- /dev/null +++ b/src/qt/guiutil.cpp @@ -0,0 +1,463 @@ +#include "guiutil.h" +#include "bitcoinaddressvalidator.h" +#include "walletmodel.h" +#include "bitcoinunits.h" +#include "util.h" +#include "init.h" +#include "base58.h" + +#include +#include +#include +#include +#include +#include +#include // For Qt::escape +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef WIN32 +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include "shlwapi.h" +#include "shlobj.h" +#include "shellapi.h" +#endif + +namespace GUIUtil { + +QString dateTimeStr(const QDateTime &date) +{ + return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") + date.toString("hh:mm"); +} + +QString dateTimeStr(qint64 nTime) +{ + return dateTimeStr(QDateTime::fromTime_t((qint32)nTime)); +} + +QFont bitcoinAddressFont() +{ + QFont font("Monospace"); + font.setStyleHint(QFont::TypeWriter); + return font; +} + +void setupAddressWidget(QLineEdit *widget, QWidget *parent) +{ + widget->setMaxLength(BitcoinAddressValidator::MaxAddressLength); + widget->setValidator(new BitcoinAddressValidator(parent)); + widget->setFont(bitcoinAddressFont()); +} + +void setupAmountWidget(QLineEdit *widget, QWidget *parent) +{ + QDoubleValidator *amountValidator = new QDoubleValidator(parent); + amountValidator->setDecimals(8); + amountValidator->setBottom(0.0); + widget->setValidator(amountValidator); + widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter); +} + +bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) +{ + if(uri.scheme() != QString("casinocoin")) + 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; + QList > items = uri.queryItems(); + for (QList >::iterator i = items.begin(); i != items.end(); i++) + { + bool fShouldReturnFalse = false; + if (i->first.startsWith("req-")) + { + i->first.remove(0, 4); + fShouldReturnFalse = true; + } + + if (i->first == "label") + { + rv.label = i->second; + fShouldReturnFalse = false; + } + else if (i->first == "amount") + { + if(!i->second.isEmpty()) + { + if(!BitcoinUnits::parse(BitcoinUnits::BTC, i->second, &rv.amount)) + { + return false; + } + } + fShouldReturnFalse = false; + } + + if (fShouldReturnFalse) + return false; + } + if(out) + { + *out = rv; + } + return true; +} + +bool parseBitcoinURI(QString uri, SendCoinsRecipient *out) +{ + // Convert casinocoin:// to casinocoin: + // + // Cannot handle this later, because casinocoin:// will cause Qt to see the part after // as host, + // which will lowercase it (and thus invalidate the address). + if(uri.startsWith("casinocoin://")) + { + uri.replace(0, 11, "casinocoin:"); + } + QUrl uriInstance(uri); + return parseBitcoinURI(uriInstance, out); +} + +QString HtmlEscape(const QString& str, bool fMultiLine) +{ + QString escaped = Qt::escape(str); + if(fMultiLine) + { + escaped = escaped.replace("\n", "
\n"); + } + return escaped; +} + +QString HtmlEscape(const std::string& str, bool fMultiLine) +{ + return HtmlEscape(QString::fromStdString(str), fMultiLine); +} + +void copyEntryData(QAbstractItemView *view, int column, int role) +{ + if(!view || !view->selectionModel()) + return; + QModelIndexList selection = view->selectionModel()->selectedRows(column); + + if(!selection.isEmpty()) + { + // Copy first item + QApplication::clipboard()->setText(selection.at(0).data(role).toString()); + } +} + +QString getSaveFileName(QWidget *parent, const QString &caption, + const QString &dir, + const QString &filter, + QString *selectedSuffixOut) +{ + QString selectedFilter; + QString myDir; + if(dir.isEmpty()) // Default to user documents location + { + myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); + } + else + { + myDir = dir; + } + QString result = QFileDialog::getSaveFileName(parent, caption, myDir, filter, &selectedFilter); + + /* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */ + QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]"); + QString selectedSuffix; + if(filter_re.exactMatch(selectedFilter)) + { + selectedSuffix = filter_re.cap(1); + } + + /* Add suffix if needed */ + QFileInfo info(result); + if(!result.isEmpty()) + { + if(info.suffix().isEmpty() && !selectedSuffix.isEmpty()) + { + /* No suffix specified, add selected suffix */ + if(!result.endsWith(".")) + result.append("."); + result.append(selectedSuffix); + } + } + + /* Return selected suffix if asked to */ + if(selectedSuffixOut) + { + *selectedSuffixOut = selectedSuffix; + } + return result; +} + +Qt::ConnectionType blockingGUIThreadConnection() +{ + if(QThread::currentThread() != QCoreApplication::instance()->thread()) + { + return Qt::BlockingQueuedConnection; + } + else + { + return Qt::DirectConnection; + } +} + +bool checkPoint(const QPoint &p, const QWidget *w) +{ + QWidget *atW = qApp->widgetAt(w->mapToGlobal(p)); + 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)); +} + +void openDebugLogfile() +{ + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + + /* Open debug.log with the associated application */ + if (boost::filesystem::exists(pathDebug)) + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(pathDebug.string()))); +} + +ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) : + QObject(parent), size_threshold(size_threshold) +{ + +} + +bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt) +{ + if(evt->type() == QEvent::ToolTipChange) + { + QWidget *widget = static_cast(obj); + QString tooltip = widget->toolTip(); + if(tooltip.size() > size_threshold && !tooltip.startsWith("") && !Qt::mightBeRichText(tooltip)) + { + // Prefix to make sure Qt detects this as rich text + // Escape the current message as HTML and replace \n by
+ tooltip = "" + HtmlEscape(tooltip, true); + widget->setToolTip(tooltip); + return true; + } + } + return QObject::eventFilter(obj, evt); +} + +#ifdef WIN32 +boost::filesystem::path static StartupShortcutPath() +{ + return GetSpecialFolderPath(CSIDL_STARTUP) / "CasinoCoin.lnk"; +} + +bool GetStartOnSystemStartup() +{ + // check for CasinoCoin.lnk + return boost::filesystem::exists(StartupShortcutPath()); +} + +bool SetStartOnSystemStartup(bool fAutoStart) +{ + // If the shortcut exists already, remove it for updating + boost::filesystem::remove(StartupShortcutPath()); + + if (fAutoStart) + { + CoInitialize(NULL); + + // Get a pointer to the IShellLink interface. + IShellLink* psl = NULL; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); + + if (SUCCEEDED(hres)) + { + // Get the current executable path + TCHAR pszExePath[MAX_PATH]; + GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); + + TCHAR pszArgs[5] = TEXT("-min"); + + // Set the path to the shortcut target + psl->SetPath(pszExePath); + PathRemoveFileSpec(pszExePath); + psl->SetWorkingDirectory(pszExePath); + psl->SetShowCmd(SW_SHOWMINNOACTIVE); + psl->SetArguments(pszArgs); + + // Query IShellLink for the IPersistFile interface for + // saving the shortcut in persistent storage. + IPersistFile* ppf = NULL; + hres = psl->QueryInterface(IID_IPersistFile, + reinterpret_cast(&ppf)); + if (SUCCEEDED(hres)) + { + WCHAR pwsz[MAX_PATH]; + // Ensure that the string is ANSI. + MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH); + // Save the link by calling IPersistFile::Save. + hres = ppf->Save(pwsz, TRUE); + ppf->Release(); + psl->Release(); + CoUninitialize(); + return true; + } + psl->Release(); + } + CoUninitialize(); + return false; + } + return true; +} + +#elif defined(LINUX) + +// Follow the Desktop Application Autostart Spec: +// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html + +boost::filesystem::path static GetAutostartDir() +{ + namespace fs = boost::filesystem; + + char* pszConfigHome = getenv("XDG_CONFIG_HOME"); + if (pszConfigHome) return fs::path(pszConfigHome) / "autostart"; + char* pszHome = getenv("HOME"); + if (pszHome) return fs::path(pszHome) / ".config" / "autostart"; + return fs::path(); +} + +boost::filesystem::path static GetAutostartFilePath() +{ + return GetAutostartDir() / "casinocoin.desktop"; +} + +bool GetStartOnSystemStartup() +{ + boost::filesystem::ifstream optionFile(GetAutostartFilePath()); + if (!optionFile.good()) + return false; + // Scan through file for "Hidden=true": + std::string line; + while (!optionFile.eof()) + { + getline(optionFile, line); + if (line.find("Hidden") != std::string::npos && + line.find("true") != std::string::npos) + return false; + } + optionFile.close(); + + return true; +} + +bool SetStartOnSystemStartup(bool fAutoStart) +{ + if (!fAutoStart) + boost::filesystem::remove(GetAutostartFilePath()); + else + { + char pszExePath[MAX_PATH+1]; + memset(pszExePath, 0, sizeof(pszExePath)); + if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1) + return false; + + boost::filesystem::create_directories(GetAutostartDir()); + + boost::filesystem::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out|std::ios_base::trunc); + if (!optionFile.good()) + return false; + // Write a casinocoin.desktop file to the autostart directory: + optionFile << "[Desktop Entry]\n"; + optionFile << "Type=Application\n"; + optionFile << "Name=CasinoCoin\n"; + optionFile << "Exec=" << pszExePath << " -min\n"; + optionFile << "Terminal=false\n"; + optionFile << "Hidden=false\n"; + optionFile.close(); + } + return true; +} +#else + +// TODO: OSX startup stuff; see: +// https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html + +bool GetStartOnSystemStartup() { return false; } +bool SetStartOnSystemStartup(bool fAutoStart) { return false; } + +#endif + +HelpMessageBox::HelpMessageBox(QWidget *parent) : + QMessageBox(parent) +{ + header = tr("CasinoCoin-Qt") + " " + tr("version") + " " + + QString::fromStdString(FormatFullVersion()) + "\n\n" + + tr("Usage:") + "\n" + + " casinocoin-qt [" + tr("command-line options") + "] " + "\n"; + + coreOptions = QString::fromStdString(HelpMessage()); + + uiOptions = tr("UI options") + ":\n" + + " -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("CasinoCoin-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::printToConsole() +{ + // 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()); +} + +void HelpMessageBox::showOrPrint() +{ +#if defined(WIN32) + // On windows, show a message box, as there is no stderr/stdout in windowed applications + exec(); +#else + // On other operating systems, print help text to console + printToConsole(); +#endif +} + +} // namespace GUIUtil + diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h new file mode 100644 index 0000000..b07c85c --- /dev/null +++ b/src/qt/guiutil.h @@ -0,0 +1,120 @@ +#ifndef GUIUTIL_H +#define GUIUTIL_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QFont; +class QLineEdit; +class QWidget; +class QDateTime; +class QUrl; +class QAbstractItemView; +QT_END_NAMESPACE +class SendCoinsRecipient; + +/** Utility functions used by the CasinoCoin Qt UI. + */ +namespace GUIUtil +{ + // Create human-readable string from date + QString dateTimeStr(const QDateTime &datetime); + QString dateTimeStr(qint64 nTime); + + // Render CasinoCoin addresses in monospace font + QFont bitcoinAddressFont(); + + // Set up widgets for address and amounts + void setupAddressWidget(QLineEdit *widget, QWidget *parent); + void setupAmountWidget(QLineEdit *widget, QWidget *parent); + + // Parse "casinocoin:" URI into recipient object, return true on succesful parsing + // See Bitcoin URI definition discussion here: https://bitcointalk.org/index.php?topic=33490.0 + bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out); + bool parseBitcoinURI(QString uri, SendCoinsRecipient *out); + + // HTML escaping for rich text controls + QString HtmlEscape(const QString& str, bool fMultiLine=false); + QString HtmlEscape(const std::string& str, bool fMultiLine=false); + + /** Copy a field of the currently selected entry of a view to the clipboard. Does nothing if nothing + is selected. + @param[in] column Data column to extract from the model + @param[in] role Data role to extract from the model + @see TransactionView::copyLabel, TransactionView::copyAmount, TransactionView::copyAddress + */ + void copyEntryData(QAbstractItemView *view, int column, int role=Qt::EditRole); + + /** Get save file name, mimics QFileDialog::getSaveFileName, except that it appends a default suffix + when no suffix is provided by the user. + + @param[in] parent Parent window (or 0) + @param[in] caption Window caption (or empty, for default) + @param[in] dir Starting directory (or empty, to default to documents directory) + @param[in] filter Filter specification such as "Comma Separated Files (*.csv)" + @param[out] selectedSuffixOut Pointer to return the suffix (file type) that was selected (or 0). + Can be useful when choosing the save file format based on suffix. + */ + QString getSaveFileName(QWidget *parent=0, const QString &caption=QString(), + const QString &dir=QString(), const QString &filter=QString(), + QString *selectedSuffixOut=0); + + /** Get connection type to call object slot in GUI thread with invokeMethod. The call will be blocking. + + @returns If called from the GUI thread, return a Qt::DirectConnection. + If called from another thread, return a Qt::BlockingQueuedConnection. + */ + Qt::ConnectionType blockingGUIThreadConnection(); + + // Determine whether a widget is hidden behind other windows + bool isObscured(QWidget *w); + + // Open debug.log + void openDebugLogfile(); + + /** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text + representation if needed. This assures that Qt can word-wrap long tooltip messages. + Tooltips longer than the provided size threshold (in characters) are wrapped. + */ + class ToolTipToRichTextFilter : public QObject + { + Q_OBJECT + + public: + explicit ToolTipToRichTextFilter(int size_threshold, QObject *parent = 0); + + protected: + bool eventFilter(QObject *obj, QEvent *evt); + + private: + int size_threshold; + }; + + bool GetStartOnSystemStartup(); + bool SetStartOnSystemStartup(bool fAutoStart); + + /** Help message for CasinoCoin-Qt, shown with --help. */ + class HelpMessageBox : public QMessageBox + { + Q_OBJECT + + public: + HelpMessageBox(QWidget *parent = 0); + + /** Show message box or print help message to standard output, based on operating system. */ + void showOrPrint(); + + /** Print help message to console */ + void printToConsole(); + + private: + QString header; + QString coreOptions; + QString uiOptions; + }; + +} // namespace GUIUtil + +#endif // GUIUTIL_H diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts new file mode 100644 index 0000000..9006870 --- /dev/null +++ b/src/qt/locale/bitcoin_bg.ts @@ -0,0 +1,2500 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + За Биткоин + + + + <b>Bitcoin</b> version + <b>Биткоин</b> версия + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + Адреси + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Това са входящите адреси (за получаване на плащания). За прегледност може да предоставяте различен адрес за всяко плащане. + + + + Double-click to edit address or label + Двоен клик за редакция на адрес или име + + + + Create a new address + Създава нов адрес + + + + Copy the currently selected address to the system clipboard + Копира избрания адрес + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Изтрива избрания адрес. Не могат да се изтриват входящи адреси. + + + + &Delete + &Изтрий + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Запазване на адреси + + + + Comma separated file (*.csv) + CSV файл (*.csv) + + + + Error exporting + Грешка при записа + + + + Could not write to file %1. + Неуспешен запис в %1. + + + + AddressTableModel + + + Label + Име + + + + Address + Адрес + + + + (no label) + (без име) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Парола + + + + New passphrase + Нова парола + + + + Repeat new passphrase + Още веднъж + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Въведете нова парола за портфейла.<br/>Моля използвайте <b>поне 10 случайни символа</b>, или <b>8 или повече думи</b>. + + + + Encrypt wallet + Криптиране на портфейла + + + + This operation needs your wallet passphrase to unlock the wallet. + Тази операция изисква Вашата парола за отключване на портфейла. + + + + Unlock wallet + Отключване на портфейла + + + + This operation needs your wallet passphrase to decrypt the wallet. + Тази операция изисква Вашата парола за декриптиране на портфейла. + + + + Decrypt wallet + Декриптиране на портфейла + + + + Change passphrase + Промяна на парола + + + + Enter the old and new passphrase to the wallet. + Въведете текущата и новата парола за портфейла. + + + + Confirm wallet encryption + Потвърждаване на криптирането + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ВНИМАНИЕ: Ако криптирате портфейла и забравите паролата <b>ЩЕ ЗАГУБИТЕ ВСИЧКИ КОИНИ</b>! +Сигурни ли сте, че искате да криптирате портфейла? + + + + + Wallet encrypted + Портфейлът е криптиран + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + Криптирането беше неуспешно + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Криптирането на портфейла беше неуспешно поради неизвестен проблем. Портфейлът не е криптиран. + + + + + The supplied passphrases do not match. + Паролите не съвпадат + + + + Wallet unlock failed + Отключването беше неуспешно + + + + + + The passphrase entered for the wallet decryption was incorrect. + Паролата въведена за декриптиране на портфейла е грешна. + + + + Wallet decryption failed + Декриптирането беше неуспешно + + + + Wallet passphrase was succesfully changed. + Паролата за портфейла беше променена успешно. + + + + BitcoinGUI + + + Bitcoin Wallet + Биткоин портфейл + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Синхронизиране с мрежата... + + + + &Overview + &Баланс + + + + Show general overview of wallet + Обобщена информация за портфейла + + + + &Transactions + &Плащания + + + + Browse transaction history + История на входящи и изходящи плащания + + + + &Address Book + &Адреси + + + + Edit the list of stored addresses and labels + Редактиране на адреси + + + + &Receive coins + &Получаване + + + + Show the list of addresses for receiving payments + Списък на адресите за получаване на плащания + + + + &Send coins + &Изпращане + + + + Prove you control an address + + + + + E&xit + + + + + Quit application + Затваря приложението + + + + &About %1 + + + + + Show information about Bitcoin + Показва информация за Биткоин + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + &Опции... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Запазване... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + Криптира или декриптира портфейла + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + Променя паролата за портфейла + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Файл + + + + &Settings + &Настройки + + + + &Help + &Помощ + + + + Tabs toolbar + Раздели + + + + Actions toolbar + Функции + + + + + [testnet] + [testnet] + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + %n връзка към Биткоин мрежата%n връзки към Биткоин мрежата + + + + Downloaded %1 blocks of transaction history. + %1 блока. + + + + %n second(s) ago + %n секунда%n секунди + + + + %n minute(s) ago + %n минута%n минути + + + + %n hour(s) ago + %n час%n часа + + + + %n day(s) ago + %n ден%n дни + + + + Up to date + Синхронизиран + + + + Catching up... + Зарежда блокове... + + + + Last received block was generated %1. + Последният блок е от %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Размерът на плащането ще надвиши максималният размер на безплатно плащане. Можете да платите срещу такса от %1, която ще бъде получена от участниците в мрежата, обработващи плащания. Желаете ли да платите таксата? + + + + Confirm transaction fee + + + + + Sent transaction + Изходящо плащане + + + + Incoming transaction + Входящо плащане + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Портфейлът е <b>криптиран</b> и <b>отключен</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Портфейлът е <b>криптиран</b> и <b>заключен</b> + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Показване + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Изберете мерна единица + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Редактиране на адрес + + + + &Label + &Име + + + + The label associated with this address book entry + Името свързано с този запис в списъка с адреси + + + + &Address + &Адрес + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Адресът свързан с този запис в списъка с адреси. Може да се променя само за изходящи адреси. + + + + New receiving address + Нов адрес за получаване + + + + New sending address + Нов адрес за изпращане + + + + Edit receiving address + Редактиране на входящ адрес + + + + Edit sending address + Редактиране на изходящ адрес + + + + The entered address "%1" is already in the address book. + Вече има адрес "%1" в списъка с адреси. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Отключването на портфейла беше неуспешно. + + + + New key generation failed. + Генерирането на ключ беше неуспешно. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + &Такса за изходящо плащане + + + + Main + Общи + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + + + + + Alt+A + + + + + Paste address from clipboard + Вмъкни от клипборда + + + + Alt+P + + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Въведете Биткоин адрес (например 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Отваряне на входящия порт чрез &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Автоматично отваряне на входящия Bitcoin порт. Работи само с рутери поддържащи UPnP. + + + + &Connect through SOCKS4 proxy: + &Използвай SOCKS4 прокси: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Свързване с Биткоин мрежата чрез SOCKS4 прокси сървър (например за да анонимизирате достъпа си чрез Тор) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + IP адрес на прокси сървъра (например 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Порт на прокси сървъра (например 1234) + + + + OptionsDialog + + + Options + Опции + + + + OverviewPage + + + Form + Форма + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Баланс: + + + + Number of transactions: + Брой плащания: + + + + Unconfirmed: + Непотвърдени: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Последни плащания</b> + + + + Your current balance + Вашият текущ баланс + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Сборът на все още непотвърдените плащания, които не са част от текущия баланс + + + + Total number of transactions in wallet + Общ брой плащания в портфейла + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + Съобщение: + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Изпращане + + + + Send to multiple recipients at once + Изпращане към повече от един получател + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + Баланс: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Потвърдете изпращането + + + + &Send + &Изпращане + + + + <b>%1</b> to %2 (%3) + <b>%1</b> на %2 (%3) + + + + Confirm send coins + Потвърждаване + + + + Are you sure you want to send %1? + Сигурни ли сте, че искате да изпратите %1? + + + + and + и + + + + The recepient address is not valid, please recheck. + Адресът на получателя не е валиден, моля проверете пак. + + + + The amount to pay must be larger than 0. + Сумата трябва да е по-голяма от 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Форма + + + + A&mount: + С&ума: + + + + Pay &To: + Плати &На: + + + + + Enter a label for this address to add it to your address book + Въведете име за този адрес, за да го добавите в списъка с адреси + + + + &Label: + &Име: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Адресът, към който да се направи плащането (например 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Вмъкни от клипборда + + + + Alt+P + Alt+P + + + + Remove this recipient + Махни този получател + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Въведете Биткоин адрес (например 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Подлежи на промяна за %1 блока + + + + Open until %1 + Подлежи на промяна до %1 + + + + %1/offline? + %1/офлайн? + + + + %1/unconfirmed + %1/непотвърдено + + + + %1 confirmations + включено в %1 блока + + + + <b>Status:</b> + <b>Състояние:</b> + + + + , has not been successfully broadcast yet + , все още не е изпратено + + + + , broadcast through %1 node + , изпратено през %1 участник в мрежата + + + + , broadcast through %1 nodes + , изпратено през %1 участници в мрежата + + + + <b>Date:</b> + <b>Дата:</b> + + + + <b>Source:</b> Generated<br> + <b>Източник:</b> Генерирани<br> + + + + + <b>From:</b> + <b>От:</b> + + + + unknown + неизвестен + + + + + + <b>To:</b> + <b>Към:</b> + + + + (yours, label: + (собствен, име: + + + + (yours) + (собствен) + + + + + + + <b>Credit:</b> + <b>Кредит:</b> + + + + (%1 matures in %2 more blocks) + (%1 достъпни след %2 блока) + + + + (not accepted) + (отхвърлен от мрежата) + + + + + + <b>Debit:</b> + <b>Дебит:</b> + + + + <b>Transaction fee:</b> + <b>Такса:</b> + + + + <b>Net amount:</b> + <b>Сума нето:</b> + + + + Message: + Съобщение: + + + + Comment: + Коментар: + + + + Transaction ID: + + + + + 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. + + + + + TransactionDescDialog + + + Transaction details + Подробности за плащане + + + + This pane shows a detailed description of the transaction + + + + + TransactionTableModel + + + Date + Дата + + + + Type + Тип + + + + Address + Адрес + + + + Amount + Сума + + + + Open for %n block(s) + + + + + Open until %1 + Подлежи на промяна до %1 + + + + Offline (%1 confirmations) + + + + + Unconfirmed (%1 of %2 confirmations) + + + + + Confirmed (%1 confirmations) + + + + + Mined balance will be available in %n more blocks + + + + + This block was not received by any other nodes and will probably not be accepted! + + + + + Generated but not accepted + + + + + Received with + Получаване + + + + Received from + + + + + Sent to + Изпращане + + + + Payment to yourself + + + + + Mined + + + + + (n/a) + + + + + Transaction status. Hover over this field to show number of confirmations. + Състояние на плащането. Задръжте върху това поле за брой потвърждения. + + + + Date and time that the transaction was received. + Дата и час на получаване. + + + + Type of transaction. + Тип плащане. + + + + Destination address of transaction. + + + + + Amount removed from or added to balance. + Сума извадена или добавена към баланса. + + + + TransactionView + + + + All + + + + + Today + Днес + + + + This week + Тази седмица + + + + This month + Този месец + + + + Last month + Предния месец + + + + This year + Тази година + + + + Range... + Интервал... + + + + Received with + Получаване + + + + Sent to + Изпращане + + + + To yourself + + + + + Mined + + + + + Other + Други + + + + Enter address or label to search + Търсене по адрес или име + + + + Min amount + Минимална сума + + + + Copy address + Копирай адрес + + + + Copy label + Копирай име + + + + Copy amount + + + + + Edit label + Редактирай име + + + + Show transaction details + + + + + Export Transaction Data + + + + + Comma separated file (*.csv) + CSV файл (*.csv) + + + + Confirmed + + + + + Date + Дата + + + + Type + Тип + + + + Label + Име + + + + Address + Адрес + + + + Amount + Сума + + + + ID + + + + + Error exporting + Грешка при записа + + + + Could not write to file %1. + Неуспешен запис в %1. + + + + Range: + + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Копира избрания адрес + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Изпращане... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Минимизиране в системния трей + + + + Show only a tray icon after minimizing the window + Остава видима само иконата долу вдясно + + + + M&inimize on close + + + + + 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. + При затваряне на прозореца приложението остава минимизирано. Ако изберете тази опция, приложението може да се затвори само чрез Изход в менюто. + + + + bitcoin-core + + + Bitcoin version + + + + + Usage: + + + + + Send command to -server or bitcoind + + + + + List commands + + + + + Get help for a command + + + + + Options: + + + + + Specify configuration file (default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + + + + + Generate coins + + + + + Don't generate coins + + + + + Specify data directory + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + + + + + Run in the background as a daemon and accept commands + + + + + Use the test network + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + + + + + Password for JSON-RPC connections + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + + Use OpenSSL (https) for JSON-RPC connections + + + + + Server certificate file (default: server.cert) + + + + + Server private key (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + + Bitcoin + + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Грешка: създаването на плащане беше неуспешно + + + + Sending... + Изпращане... + + + + 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. + Грешка: плащането беше отхвърлено. Това е възможно ако част от парите в портфейла са вече похарчени, например при паралелно използване на копие на wallet.dat + + + + Invalid amount + + + + + Insufficient funds + + + + + Loading block index... + + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + + + + + Done loading + + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts new file mode 100644 index 0000000..40e95cd --- /dev/null +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -0,0 +1,2499 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Sobre Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> versió + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + llibreta d'adreces + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + + + + + Double-click to edit address or label + Feu doble clic per editar la direcció o l'etiqueta + + + + Create a new address + Crear una nova adreça + + + + Copy the currently selected address to the system clipboard + Copieu l'adreça seleccionada al porta-retalls del sistema + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + + + + + &Delete + &Borrar + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + + + + + Comma separated file (*.csv) + + + + + Error exporting + + + + + Could not write to file %1. + + + + + AddressTableModel + + + Label + Etiqueta + + + + Address + Direcció + + + + (no label) + + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + + + + + New passphrase + + + + + Repeat new passphrase + + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + + + + + Encrypt wallet + Xifrar la cartera + + + + This operation needs your wallet passphrase to unlock the wallet. + + + + + Unlock wallet + + + + + This operation needs your wallet passphrase to decrypt the wallet. + + + + + Decrypt wallet + + + + + Change passphrase + + + + + Enter the old and new passphrase to the wallet. + + + + + Confirm wallet encryption + + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + + + + + + Wallet encrypted + + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + + + + The supplied passphrases do not match. + + + + + Wallet unlock failed + + + + + + + The passphrase entered for the wallet decryption was incorrect. + + + + + Wallet decryption failed + + + + + Wallet passphrase was succesfully changed. + + + + + BitcoinGUI + + + Bitcoin Wallet + + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Sincronització amb la xarxa ... + + + + &Overview + + + + + Show general overview of wallet + Mostra panorama general de la cartera + + + + &Transactions + + + + + Browse transaction history + Cerca a l'historial de transaccions + + + + &Address Book + + + + + Edit the list of stored addresses and labels + Edita la llista d'adreces emmagatzemada i etiquetes + + + + &Receive coins + &Rebre monedes + + + + Show the list of addresses for receiving payments + + + + + &Send coins + + + + + Prove you control an address + + + + + E&xit + + + + + Quit application + Sortir de l'aplicació + + + + &About %1 + + + + + Show information about Bitcoin + Mostra informació sobre Bitcoin + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + &Opcions ... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + + + + + &Settings + + + + + &Help + &Ajuda + + + + Tabs toolbar + + + + + Actions toolbar + Accions de la barra d'eines + + + + + [testnet] + + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + + + + + Downloaded %1 blocks of transaction history. + + + + + %n second(s) ago + + + + + %n minute(s) ago + + + + + %n hour(s) ago + + + + + %n day(s) ago + + + + + Up to date + Al dia + + + + Catching up... + Posar-se al dia ... + + + + Last received block was generated %1. + + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + + + + + Confirm transaction fee + + + + + Sent transaction + Transacció enviada + + + + Incoming transaction + + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Editar Adreça + + + + &Label + + + + + The label associated with this address book entry + + + + + &Address + + + + + The address associated with this address book entry. This can only be modified for sending addresses. + + + + + New receiving address + + + + + New sending address + + + + + Edit receiving address + + + + + Edit sending address + + + + + The entered address "%1" is already in the address book. + + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + + + + + New key generation failed. + + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + + + + + Main + + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Port obert amb &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + + + &Connect through SOCKS4 proxy: + + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + + + + + Port of the proxy (e.g. 1234) + + + + + OptionsDialog + + + Options + + + + + OverviewPage + + + Form + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Balanç: + + + + Number of transactions: + + + + + Unconfirmed: + Sense confirmar: + + + + Wallet + + + + + <b>Recent transactions</b> + + + + + Your current balance + El seu balanç actual + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + + + Total number of transactions in wallet + + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Enviar monedes + + + + Send to multiple recipients at once + + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + Balanç: + + + + 123.456 BTC + + + + + Confirm the send action + + + + + &Send + + + + + <b>%1</b> to %2 (%3) + + + + + Confirm send coins + + + + + Are you sure you want to send %1? + + + + + and + + + + + The recepient address is not valid, please recheck. + + + + + The amount to pay must be larger than 0. + La quantitat a pagar ha de ser major que 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + + + + + A&mount: + + + + + Pay &To: + + + + + + Enter a label for this address to add it to your address book + + + + + &Label: + + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose address from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Remove this recipient + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + TransactionDesc + + + Open for %1 blocks + + + + + Open until %1 + + + + + %1/offline? + + + + + %1/unconfirmed + + + + + %1 confirmations + + + + + <b>Status:</b> + + + + + , has not been successfully broadcast yet + + + + + , broadcast through %1 node + + + + + , broadcast through %1 nodes + + + + + <b>Date:</b> + + + + + <b>Source:</b> Generated<br> + + + + + + <b>From:</b> + + + + + unknown + + + + + + + <b>To:</b> + + + + + (yours, label: + + + + + (yours) + + + + + + + + <b>Credit:</b> + + + + + (%1 matures in %2 more blocks) + + + + + (not accepted) + + + + + + + <b>Debit:</b> + + + + + <b>Transaction fee:</b> + + + + + <b>Net amount:</b> + + + + + Message: + + + + + Comment: + + + + + Transaction ID: + + + + + Generated coins must wait 8 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. + + + + + TransactionDescDialog + + + Transaction details + + + + + This pane shows a detailed description of the transaction + + + + + TransactionTableModel + + + Date + + + + + Type + + + + + Address + Direcció + + + + Amount + + + + + Open for %n block(s) + + + + + Open until %1 + + + + + Offline (%1 confirmations) + + + + + Unconfirmed (%1 of %2 confirmations) + + + + + Confirmed (%1 confirmations) + + + + + Mined balance will be available in %n more blocks + + + + + This block was not received by any other nodes and will probably not be accepted! + + + + + Generated but not accepted + + + + + Received with + + + + + Received from + + + + + Sent to + + + + + Payment to yourself + + + + + Mined + + + + + (n/a) + + + + + Transaction status. Hover over this field to show number of confirmations. + + + + + Date and time that the transaction was received. + + + + + Type of transaction. + + + + + Destination address of transaction. + + + + + Amount removed from or added to balance. + + + + + TransactionView + + + + All + + + + + Today + + + + + This week + + + + + This month + + + + + Last month + + + + + This year + + + + + Range... + + + + + Received with + + + + + Sent to + + + + + To yourself + + + + + Mined + + + + + Other + + + + + Enter address or label to search + + + + + Min amount + + + + + Copy address + + + + + Copy label + + + + + Copy amount + + + + + Edit label + + + + + Show transaction details + + + + + Export Transaction Data + + + + + Comma separated file (*.csv) + + + + + Confirmed + + + + + Date + + + + + Type + + + + + Label + Etiqueta + + + + Address + Direcció + + + + Amount + + + + + ID + + + + + Error exporting + + + + + Could not write to file %1. + + + + + Range: + + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Copieu l'adreça seleccionada al porta-retalls del sistema + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + L'enviament de ... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + + + + + Show only a tray icon after minimizing the window + + + + + M&inimize on close + + + + + 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. + + + + + bitcoin-core + + + Bitcoin version + + + + + Usage: + + + + + Send command to -server or bitcoind + + + + + List commands + + + + + Get help for a command + + + + + Options: + + + + + Specify configuration file (default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + + + + + Generate coins + + + + + Don't generate coins + + + + + Specify data directory + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + + + + + Run in the background as a daemon and accept commands + + + + + Use the test network + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + + + + + Password for JSON-RPC connections + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + + Use OpenSSL (https) for JSON-RPC connections + + + + + Server certificate file (default: server.cert) + + + + + Server private key (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + + Bitcoin + + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + + + + + Sending... + L'enviament de ... + + + + 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. + + + + + Invalid amount + + + + + Insufficient funds + + + + + Loading block index... + + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + + + + + Done loading + + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts new file mode 100644 index 0000000..528e17a --- /dev/null +++ b/src/qt/locale/bitcoin_cs.ts @@ -0,0 +1,2520 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + O Bitcoinu + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> verze + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Vývojáři Bitcoinu + +Tohle je experimentální program. + +Šířen pod licencí MIT/X11, viz přiložený soubor license.txt nebo http://www.opensource.org/licenses/mit-license.php. + +Tento produkt zahrnuje programy vyvinuté OpenSSL Projektem pro použití v OpenSSL Toolkitu (http://www.openssl.org/) a kryptografický program od Erika Younga (eay@cryptsoft.com) a program UPnP od Thomase Bernarda. + + + + AddressBookPage + + + Address Book + Adresář + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Tohle jsou tvé Bitcoinové adresy pro příjem plateb. Můžeš pokaždé dát každému odesílateli jinou adresu, abys věděl, kdo ti kdy kolik platil. + + + + Double-click to edit address or label + Dvojklikem myši začneš upravovat označení adresy + + + + Create a new address + Vytvoř novou adresu + + + + Copy the currently selected address to the system clipboard + Zkopíruj aktuálně vybranou adresu do systémové schránky + + + + &New Address + Nová &adresa + + + + &Copy Address + &Kopíruj adresu + + + + Show &QR Code + Zobraz &QR kód + + + + Sign a message to prove you own this address + Podepiš zprávu, čímž prokážeš, že jsi vlastníkem této adresy + + + + &Sign Message + Po&depiš zprávu + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Smaž aktuálně vybranou adresu ze seznamu. Smazány mohou být pouze adresy příjemců. + + + + &Delete + S&maž + + + + Copy &Label + Kopíruj &označení + + + + &Edit + &Uprav + + + + Export Address Book Data + Exportuj data adresáře + + + + Comma separated file (*.csv) + CSV formát (*.csv) + + + + Error exporting + Chyba při exportu + + + + Could not write to file %1. + Nemohu zapisovat do souboru %1. + + + + AddressTableModel + + + Label + Označení + + + + Address + Adresa + + + + (no label) + (bez označení) + + + + AskPassphraseDialog + + + Passphrase Dialog + Změna hesla + + + + Enter passphrase + Zadej platné heslo + + + + New passphrase + Zadej nové heslo + + + + Repeat new passphrase + Totéž heslo ještě jednou + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Zadej nové heslo k peněžence.<br/>Použij <b>alespoň 10 náhodných znaků</b> nebo <b>alespoň osm slov</b>. + + + + Encrypt wallet + Zašifruj peněženku + + + + This operation needs your wallet passphrase to unlock the wallet. + K provedení této operace musíš zadat heslo k peněžence, aby se mohla odemknout. + + + + Unlock wallet + Odemkni peněženku + + + + This operation needs your wallet passphrase to decrypt the wallet. + K provedení této operace musíš zadat heslo k peněžence, aby se mohla dešifrovat. + + + + Decrypt wallet + Dešifruj peněženku + + + + Change passphrase + Změň heslo + + + + Enter the old and new passphrase to the wallet. + Zadej staré a nové heslo k peněžence. + + + + Confirm wallet encryption + Potvrď zašifrování peněženky + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + VAROVÁNÍ: Pokud zašifruješ peněženku a ztratíš či zapomeneš heslo, <b>PŘIJDEŠ O VŠECHNY BITCOINY</b>! +Jsi si jistý, že chceš peněženku zašifrovat? + + + + + Wallet encrypted + Peněženka je zašifrována + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin se teď ukončí, aby dokončil zašifrování. Pamatuj však, že pouhé zašifrování peněženky úplně nezabraňuje krádeži tvých bitcoinů malwarem, kterým se může počítač nakazit. + + + + + Warning: The Caps Lock key is on. + Upozornění: Caps Lock je zapnutý. + + + + + + + Wallet encryption failed + Zašifrování peněženky selhalo + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Zašifrování peněženky selhalo kvůli vnitřní chybě. Tvá peněženka tedy nebyla zašifrována. + + + + + The supplied passphrases do not match. + Zadaná hesla nejsou shodná. + + + + Wallet unlock failed + Odemčení peněženky selhalo + + + + + + The passphrase entered for the wallet decryption was incorrect. + Nezadal jsi správné heslo pro dešifrování peněženky. + + + + Wallet decryption failed + Dešifrování peněženky selhalo + + + + Wallet passphrase was succesfully changed. + Heslo k peněžence bylo v pořádku změněno. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoinová peněženka + + + + Sign &message... + Po&depiš zprávu... + + + + Show/Hide &Bitcoin + Zobrazit/Skrýt &Bitcoin + + + + Synchronizing with network... + Synchronizuji se sítí... + + + + &Overview + &Přehled + + + + Show general overview of wallet + Zobraz celkový přehled peněženky + + + + &Transactions + &Transakce + + + + Browse transaction history + Procházet historii transakcí + + + + &Address Book + &Adresář + + + + Edit the list of stored addresses and labels + Uprav seznam uložených adres a jejich označení + + + + &Receive coins + Pří&jem mincí + + + + Show the list of addresses for receiving payments + Zobraz seznam adres pro příjem plateb + + + + &Send coins + P&oslání mincí + + + + Prove you control an address + Prokaž vlastnictví adresy + + + + E&xit + &Konec + + + + Quit application + Ukončit aplikaci + + + + &About %1 + &O %1 + + + + Show information about Bitcoin + Zobraz informace o Bitcoinu + + + + About &Qt + O &Qt + + + + Show information about Qt + Zobraz informace o Qt + + + + &Options... + &Možnosti... + + + + &Encrypt Wallet... + Zaši&fruj peněženku... + + + + &Backup Wallet... + &Zazálohovat peněženku... + + + + &Change Passphrase... + Změň &heslo... + + + + ~%n block(s) remaining + zbývá ~%n blokzbývá ~%n blokyzbývá ~%n bloků + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Staženo %1 z %2 bloků transakční historie (%3 % hotovo). + + + + &Export... + &Export... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Zobraz nebo skryj okno Bitcoinu + + + + Export the data in the current tab to a file + Exportovat data z tohoto panelu do souboru + + + + Encrypt or decrypt wallet + Zašifruj nebo dešifruj peněženku + + + + Backup wallet to another location + Zazálohuj peněženku na jiné místo + + + + Change the passphrase used for wallet encryption + Změň heslo k šifrování peněženky + + + + &Debug window + &Ladící okno + + + + Open debugging and diagnostic console + Otevři ladící a diagnostickou konzoli + + + + &Verify message... + &Ověř zprávu... + + + + Verify a message signature + Ověř podpis zprávy + + + + &File + &Soubor + + + + &Settings + &Nastavení + + + + &Help + Ná&pověda + + + + Tabs toolbar + Panel s listy + + + + Actions toolbar + Panel akcí + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Bitcoin klient + + + + %n active connection(s) to Bitcoin network + %n aktivní spojení do Bitcoinové sítě%n aktivní spojení do Bitcoinové sítě%n aktivních spojení do Bitcoinové sítě + + + + Downloaded %1 blocks of transaction history. + Staženo %1 bloků transakční historie. + + + + %n second(s) ago + před vteřinoupřed %n vteřinamipřed %n vteřinami + + + + %n minute(s) ago + před minutoupřed %n minutamipřed %n minutami + + + + %n hour(s) ago + před hodinoupřed %n hodinamipřed %n hodinami + + + + %n day(s) ago + včerapřed %n dnypřed %n dny + + + + Up to date + aktuální + + + + Catching up... + Stahuji... + + + + Last received block was generated %1. + Poslední stažený blok byl vygenerován %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Tahle transakce přesahuje velikostní limit. I tak ji ale můžeš poslat, pokud za ni zaplatíš poplatek %1, který půjde uzlům, které tvou transakci zpracují, a navíc tak podpoříš síť. Chceš zaplatit poplatek? + + + + Confirm transaction fee + Potvrď transakční poplatek + + + + Sent transaction + Odeslané transakce + + + + Incoming transaction + Příchozí transakce + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Datum: %1 +Částka: %2 +Typ: %3 +Adresa: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Peněženka je <b>zašifrovaná</b> a momentálně <b>odemčená</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Peněženka je <b>zašifrovaná</b> a momentálně <b>zamčená</b> + + + + Backup Wallet + Záloha peněženky + + + + Wallet Data (*.dat) + Data peněženky (*.dat) + + + + Backup Failed + Zálohování selhalo + + + + There was an error trying to save the wallet data to the new location. + Při ukládání peněženky na nové místo se přihodila nějaká chyba. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + Stala se fatální chyba. Bitcoin nemůže bezpečně pokračovat v činnosti, a proto skončí. + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Zobrazení + + + + default + výchozí + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + Tady lze nastavit jazyk uživatelského rozhraní. Nastavení se projeví až po restartování Bitcoinu. + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Zvol výchozí podjednotku, která se bude zobrazovat v programu a při posílání mincí + + + + &Display addresses in transaction list + &Ukazovat adresy ve výpisu transakcí + + + + Whether to show Bitcoin addresses in the transaction list + Zda ukazovat bitcoinové adresy ve výpisu transakcí nebo ne + + + + Warning + Upozornění + + + + This setting will take effect after restarting Bitcoin. + Nastavení se projeví až po restartování Bitcoinu. + + + + EditAddressDialog + + + Edit Address + Uprav adresu + + + + &Label + &Označení + + + + The label associated with this address book entry + Označení spojené s tímto záznamem v adresáři + + + + &Address + &Adresa + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Adresa spojená s tímto záznamem v adresáři. Lze upravovat jen pro odesílací adresy. + + + + New receiving address + Nová přijímací adresa + + + + New sending address + Nová odesílací adresa + + + + Edit receiving address + Uprav přijímací adresu + + + + Edit sending address + Uprav odesílací adresu + + + + The entered address "%1" is already in the address book. + Zadaná adresa "%1" už v adresáři je. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Nemohu odemknout peněženku. + + + + New key generation failed. + Nepodařilo se mi vygenerovat nový klíč. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + verze + + + + Usage: + Užití: + + + + options + + + + + UI options + Možnosti UI + + + + Set language, for example "de_DE" (default: system locale) + Nastavit jazyk, například "de_DE" (výchozí: systémové nastavení) + + + + Start minimized + Startovat minimalizovaně + + + + Show splash screen on startup (default: 1) + Zobrazovat startovací obrazovku (výchozí: 1) + + + + MainOptionsPage + + + 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. + Při ukončování odpojit databáze bloků a adres. To znamená, že mohou být přesunuty do jiného adresáře, ale zpomaluje to ukončení. Peněženka je vždy odpojená. + + + + Pay transaction &fee + Platit &transakční poplatek + + + + Main + Hlavní + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Dobrovolný transakční poplatek za každý započatý kB dopomáhá k rychlému zpracování tvých transakcí. Většina transakcí má do 1 kB. Doporučená výše poplatku je 0.01. + + + + &Start Bitcoin on system login + &Spustit Bitcoin po přihlášení do systému + + + + Automatically start Bitcoin after logging in to the system + Automaticky spustí Bitcoin po přihlášení do systému + + + + &Detach databases at shutdown + Při ukončování &odpojit databáze + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Podepsáním zprávy svými adresami můžeš prokázat, že je skutečně vlastníš. Buď opatrný a nepodepisuj nic vágního; například při phishingových útocích můžeš být lákán, abys něco takového podepsal. Podepisuj pouze zcela úplná a detailní prohlášení, se kterými souhlasíš. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adresa, kterou se zpráva podepíše (např. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Vyber adresu z adresáře + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Vlož adresu ze schránky + + + + Alt+P + Alt+V + + + + Enter the message you want to sign here + Sem vepiš zprávu, kterou chceš podepsat + + + + Copy the current signature to the system clipboard + Zkopíruj aktuálně vybraný podpis do systémové schránky + + + + &Copy Signature + &Kopíruj podpis + + + + Reset all sign message fields + Vymaž všechna pole formuláře pro podepsání zrávy + + + + Clear &All + Všechno &smaž + + + + Click "Sign Message" to get signature + Kliknutím na "Podepiš zprávu" získáš podpis + + + + Sign a message to prove you own this address + Podepiš zprávu, čímž prokážeš, že jsi vlastníkem této adresy + + + + &Sign Message + &Podepiš zprávu + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Zadej Bitcoinovou adresu (např. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Chyba při podepisování + + + + %1 is not a valid address. + %1 není platná adresa. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Soukromý klíč pro %1 není dostupný. + + + + Sign failed + Podepisování selhalo + + + + NetworkOptionsPage + + + Network + Síť + + + + Map port using &UPnP + Namapovat port přes &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Automaticky otevře potřebný port na routeru. Tohle funguje jen za předpokladu, že tvůj router podporuje UPnP a že je UPnP povolené. + + + + &Connect through SOCKS4 proxy: + &Připojit přes SOCKS4 proxy: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Připojí se do Bitcoinové sítě přes SOCKS4 proxy (např. když se připojuje přes Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + IP adresa proxy (např. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Port proxy (např. 1234) + + + + OptionsDialog + + + Options + Možnosti + + + + OverviewPage + + + Form + Formulář + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Stav účtu: + + + + Number of transactions: + Počet transakcí: + + + + Unconfirmed: + Nepotvrzeno: + + + + Wallet + Peněženka + + + + <b>Recent transactions</b> + <b>Poslední transakce</b> + + + + Your current balance + Aktuální stav tvého účtu + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Celkem z transakcí, které ještě nejsou potvrzené a které se ještě nezapočítávají do celkového stavu účtu + + + + Total number of transactions in wallet + Celkový počet transakcí v peněžence + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + QR kód + + + + QR Code + QR kód + + + + Request Payment + Požadovat platbu + + + + Amount: + Částka: + + + + BTC + BTC + + + + Label: + Označení: + + + + Message: + Zpráva: + + + + &Save As... + &Ulož jako... + + + + Error encoding URI into QR Code. + Chyba při kódování URI do QR kódu. + + + + Resulting URI too long, try to reduce the text for label / message. + Výsledná URI je příliš dlouhá, zkus zkrátit text označení / zprávy. + + + + Save QR Code + Ulož QR kód + + + + PNG Images (*.png) + PNG obrázky (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + Síť + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Pošli mince + + + + Send to multiple recipients at once + Pošli více příjemcům naráz + + + + &Add Recipient + Při&dej příjemce + + + + Remove all transaction fields + Smaž všechny transakční formuláře + + + + Clear &All + Všechno &smaž + + + + Balance: + Stav účtu: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Potvrď odeslání + + + + &Send + &Pošli + + + + <b>%1</b> to %2 (%3) + <b>%1</b> pro %2 (%3) + + + + Confirm send coins + Potvrď odeslání mincí + + + + Are you sure you want to send %1? + Jsi si jistý, že chceš poslat %1? + + + + and + a + + + + The recepient address is not valid, please recheck. + Adresa příjemce je neplatná, překontroluj ji prosím. + + + + The amount to pay must be larger than 0. + Odesílaná částka musí být větší než 0. + + + + The amount exceeds your balance. + Částka překračuje stav účtu. + + + + The total exceeds your balance when the %1 transaction fee is included. + Celková částka při připočítání poplatku %1 překročí stav účtu. + + + + Duplicate address found, can only send to each address once per send operation. + Zaznamenána duplikovaná adresa; každá adresa může být v odesílané platbě pouze jednou. + + + + Error: Transaction creation failed. + Chyba: Vytvoření transakce selhalo. + + + + 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. + Chyba Transakce byla odmítnuta. Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této. + + + + SendCoinsEntry + + + Form + Formulář + + + + A&mount: + Čá&stka: + + + + Pay &To: + &Komu: + + + + + Enter a label for this address to add it to your address book + Zadej označení této adresy; obojí se ti pak uloží do adresáře + + + + &Label: + &Označení: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adresa příjemce (např. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Vyber adresu z adresáře + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Vlož adresu ze schránky + + + + Alt+P + Alt+P + + + + Remove this recipient + Smaž tohoto příjemce + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Zadej Bitcoinovou adresu (např. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Otevřeno pro %1 bloků + + + + Open until %1 + Otřevřeno dokud %1 + + + + %1/offline? + %1/offline? + + + + %1/unconfirmed + %1/nepotvrzeno + + + + %1 confirmations + %1 potvrzení + + + + <b>Status:</b> + <b>Stav:</b> + + + + , has not been successfully broadcast yet + , ještě nebylo rozesláno + + + + , broadcast through %1 node + , rozesláno přes %1 uzel + + + + , broadcast through %1 nodes + , rozesláno přes %1 uzlů + + + + <b>Date:</b> + <b>Datum:</b> + + + + <b>Source:</b> Generated<br> + <b>Zdroj:</b> Vygenerováno<br> + + + + + <b>From:</b> + <b>Od:</b> + + + + unknown + neznámo + + + + + + <b>To:</b> + <b>Pro:</b> + + + + (yours, label: + (tvoje, označení: + + + + (yours) + (tvoje) + + + + + + + <b>Credit:</b> + <b>Příjem:</b> + + + + (%1 matures in %2 more blocks) + (%1 dozraje po %2 blocích) + + + + (not accepted) + (neakceptováno) + + + + + + <b>Debit:</b> + <b>Výdaj:</b> + + + + <b>Transaction fee:</b> + <b>Transakční poplatek:</b> + + + + <b>Net amount:</b> + <b>Čistá částka:</b> + + + + Message: + Zpráva: + + + + Comment: + Komentář: + + + + Transaction ID: + ID transakce: + + + + 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. + Vygenerované mince musí čekat 120 bloků, než mohou být utraceny. Když jsi vygeneroval tenhle blok, tak byl rozposlán do sítě, aby byl přidán do řetězce bloků. Pokud se mu nepodaří dostat se do řetězce, změní se na "neakceptovaný" a nepůjde utratit. Občas se to může stát, když jiný uzel vygeneruje blok zhruba ve stejném okamžiku jako ty. + + + + TransactionDescDialog + + + Transaction details + Detaily transakce + + + + This pane shows a detailed description of the transaction + Toto okno zobrazuje detailní popis transakce + + + + TransactionTableModel + + + Date + Datum + + + + Type + Typ + + + + Address + Adresa + + + + Amount + Částka + + + + Open for %n block(s) + Otevřeno pro 1 blokOtevřeno pro %n blokyOtevřeno pro %n bloků + + + + Open until %1 + Otřevřeno dokud %1 + + + + Offline (%1 confirmations) + Offline (%1 potvrzení) + + + + Unconfirmed (%1 of %2 confirmations) + Nepotvrzeno (%1 z %2 potvrzení) + + + + Confirmed (%1 confirmations) + Potvrzeno (%1 potvrzení) + + + + Mined balance will be available in %n more blocks + Vytěžené mince budou použitelné po jednom blokuVytěžené mince budou použitelné po %n blocíchVytěžené mince budou použitelné po %n blocích + + + + This block was not received by any other nodes and will probably not be accepted! + Tento blok nedostal žádný jiný uzel a pravděpodobně nebude akceptován! + + + + Generated but not accepted + Vygenerováno, ale neakceptováno + + + + Received with + Přijato do + + + + Received from + Přijato od + + + + Sent to + Posláno na + + + + Payment to yourself + Platba sama sobě + + + + Mined + Vytěženo + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + Stav transakce. Najetím myši na toto políčko si zobrazíš počet potvrzení. + + + + Date and time that the transaction was received. + Datum a čas přijetí transakce. + + + + Type of transaction. + Druh transakce. + + + + Destination address of transaction. + Cílová adresa transakce. + + + + Amount removed from or added to balance. + Částka odečtená z nebo přičtená k účtu. + + + + TransactionView + + + + All + Vše + + + + Today + Dnes + + + + This week + Tento týden + + + + This month + Tento měsíc + + + + Last month + Minulý měsíc + + + + This year + Letos + + + + Range... + Rozsah... + + + + Received with + Přijato + + + + Sent to + Posláno + + + + To yourself + Sám sobě + + + + Mined + Vytěženo + + + + Other + Ostatní + + + + Enter address or label to search + Zadej adresu nebo označení pro její vyhledání + + + + Min amount + Minimální částka + + + + Copy address + Kopíruj adresu + + + + Copy label + Kopíruj její označení + + + + Copy amount + Kopíruj částku + + + + Edit label + Uprav označení + + + + Show transaction details + Zobraz detaily transakce + + + + Export Transaction Data + Exportuj transakční data + + + + Comma separated file (*.csv) + CSV formát (*.csv) + + + + Confirmed + Potvrzeno + + + + Date + Datum + + + + Type + Typ + + + + Label + Označení + + + + Address + Adresa + + + + Amount + Částka + + + + ID + ID + + + + Error exporting + Chyba při exportu + + + + Could not write to file %1. + Nemohu zapisovat do souboru %1. + + + + Range: + Rozsah: + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Kopírovat aktuálně vybrané adresy do schránky + + + + &Copy Address + &Kopíruj adresu + + + + Reset all verify message fields + + + + + Clear &All + Všechno &smaž + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Posílám... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Minimalizovat do systémové lišty namísto do hlavního panelu + + + + Show only a tray icon after minimizing the window + Po minimalizaci okna zobrazovat pouze ikonu v systémové liště + + + + M&inimize on close + + + + + 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. + + + + + bitcoin-core + + + Bitcoin version + Verze Bitcoinu + + + + Usage: + Užití: + + + + Send command to -server or bitcoind + Poslat příkaz pro -server nebo bitcoind + + + + List commands + Výpis příkazů + + + + Get help for a command + Získat nápovědu pro příkaz + + + + Options: + Možnosti: + + + + Specify configuration file (default: bitcoin.conf) + Konfigurační soubor (výchozí: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + PID soubor (výchozí: bitcoind.pid) + + + + Generate coins + Generovat mince + + + + Don't generate coins + Negenerovat mince + + + + Specify data directory + Adresář pro data + + + + Set database cache size in megabytes (default: 25) + Nastavit velikost databázové vyrovnávací paměti v megabajtech (výchozí: 25) + + + + Set database disk log size in megabytes (default: 100) + Nastavit velikost databázového souboru s logy v megabajtech (výchozí: 100) + + + + Specify connection timeout (in milliseconds) + Zadej časový limit spojení (v milisekundách) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Čekat na spojení na <portu> (výchozí: 8333 nebo testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Povol nejvýše <n> připojení k uzlům (výchozí: 125) + + + + Connect only to the specified node + Připojovat se pouze k udanému uzlu + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Práh pro odpojování nesprávně se chovajících uzlů (výchozí: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Doba ve vteřinách, po kterou se nebudou moci nesprávně se chovající uzly znovu připojit (výchozí: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maximální velikost přijímacího bufferu pro každé spojení, <n>*1000 bytů (výchozí: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maximální velikost odesílacího bufferu pro každé spojení, <n>*1000 bytů (výchozí: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Akceptovat příkazy z příkazové řádky a přes JSON-RPC + + + + Run in the background as a daemon and accept commands + Běžet na pozadí jako démon a akceptovat příkazy + + + + Use the test network + Použít testovací síť (testnet) + + + + Output extra debugging information + Tisknout speciální ladící informace + + + + Prepend debug output with timestamp + Připojit před ladící výstup časové razítko + + + + Send trace/debug info to console instead of debug.log file + Posílat stopovací/ladící informace do konzole místo do souboru debug.log + + + + Send trace/debug info to debugger + Posílat stopovací/ladící informace do debuggeru + + + + Username for JSON-RPC connections + Uživatelské jméno pro JSON-RPC spojení + + + + Password for JSON-RPC connections + Heslo pro JSON-RPC spojení + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Čekat na JSON-RPC spojení na <portu> (výchozí: 8332) + + + + Allow JSON-RPC connections from specified IP address + Povolit JSON-RPC spojení ze specifikované IP adresy + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Posílat příkazy uzlu běžícím na <ip> (výchozí: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Spustit příkaz, když se změní nejlepší blok (%s se v příkazu nahradí hashem bloku) + + + + Upgrade wallet to latest format + Převést peněženku na nejnovější formát + + + + Set key pool size to <n> (default: 100) + Nastavit zásobník klíčů na velikost <n> (výchozí: 100) + + + + Rescan the block chain for missing wallet transactions + Přeskenovat řetězec bloků na chybějící transakce tvé pěněženky + + + + How many blocks to check at startup (default: 2500, 0 = all) + Kolik bloků při startu zkontrolovat (výchozí: 2500, 0 = všechny) + + + + How thorough the block verification is (0-6, default: 1) + Jak moc důkladná má verifikace bloků být (0-6, výchozí: 1) + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +Možnosti SSL: (viz instrukce nastavení SSL v Bitcoin Wiki) + + + + Use OpenSSL (https) for JSON-RPC connections + Použít OpenSSL (https) pro JSON-RPC spojení + + + + Server certificate file (default: server.cert) + Soubor se serverovým certifikátem (výchozí: server.cert) + + + + Server private key (default: server.pem) + Soubor se serverovým soukromým klíčem (výchozí: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Akceptovatelné šifry (výchozí: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + Tato nápověda + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Nedaří se mi získat zámek na datový adresář %s. Bitcoin pravděpodobně už jednou běží. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Načítám adresy... + + + + Error loading blkindex.dat + Chyba při načítání blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Chyba při načítání wallet.dat: peněženka je poškozená + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Chyba při načítání wallet.dat: peněženka vyžaduje novější verzi Bitcoinu + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Soubor s peněženkou potřeboval přepsat: restartuj Bitcoin, aby se operace dokončila + + + + Error loading wallet.dat + Chyba při načítání wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + Chyba: Peněženka je zamčená, nemohu vytvořit transakci + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Chyba: Tahle transakce vyžaduje transakční poplatek nejméně %s kvůli velikosti zasílané částky, komplexnosti nebo použití nedávno přijatých mincí + + + + Error: Transaction creation failed + Chyba: Vytvoření transakce selhalo + + + + Sending... + Posílám... + + + + 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. + Chyba Transakce byla odmítnuta. Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této. + + + + Invalid amount + Neplatná částka + + + + Insufficient funds + Nedostatek prostředků + + + + Loading block index... + Načítám index bloků... + + + + Add a node to connect to and attempt to keep the connection open + Přidat uzel, ke kterému se připojit a snažit se spojení udržet + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + Hledat uzly přes IRC (výchozí: 0) + + + + Accept connections from outside (default: 1) + Přijímat spojení zvenčí (výchozí: 1) + + + + Find peers using DNS lookup (default: 1) + Hledat uzly přes DNS (výchozí: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Použít Universal Plug and Play k namapování naslouchacího portu (výchozí: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Použít Universal Plug and Play k namapování naslouchacího portu (výchozí: 0) + + + + Fee per KB to add to transactions you send + Poplatek za KB, který se přidá ke každé odeslané transakci + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Načítám peněženku... + + + + Cannot downgrade wallet + Nemohu převést peněženku do staršího formátu + + + + Cannot initialize keypool + Nemohu inicializovat zásobník klíčů + + + + Cannot write default address + Nemohu napsat výchozí adresu + + + + Rescanning... + Přeskenovávám... + + + + Done loading + Načítání dokončeno + + + + To use the %s option + K použití volby %s + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, musíš nastavit rpcpassword v konfiguračním souboru: + %s +Je vhodné použít následující náhodné heslo: +rpcuser=bitcoinrpc +rpcpassword=%s +(není potřeba si ho pamatovat) +Pokud konfigurační soubor ještě neexistuje, vytvoř ho tak, aby ho mohl číst pouze vlastník. + + + + + Error + Chyba + + + + An error occured while setting up the RPC port %i for listening: %s + Při nastavování naslouchacího RPC portu %i nastala chyba: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Musíš nastavit rpcpassword=<heslo> v konfiguračním souboru: +%s +Pokud konfigurační soubor ještě neexistuje, vytvoř ho tak, aby ho mohl číst pouze vlastník. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Upozornění: Zkontroluj, že máš v počítači správně nastavený datum a čas. Pokud jsou nastaveny špatně, Bitcoin nebude fungovat správně. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts new file mode 100644 index 0000000..66166a7 --- /dev/null +++ b/src/qt/locale/bitcoin_da.ts @@ -0,0 +1,2532 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Om Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> version + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + Adressebog + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Dette er dine Bitcoinadresser til at modtage betalinger med. Du kan give en forskellig adresse til hver afsender, så du kan holde styr på hvem der betaler dig. + + + + Double-click to edit address or label + Dobbeltklik for at redigere adresse eller mærkat + + + + Create a new address + Opret en ny adresse + + + + Copy the currently selected address to the system clipboard + Kopier den valgte adresse til systemets udklipsholder + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Slet den valgte adresse fra listen. Kun adresser brugt til afsendelse kan slettes. + + + + &Delete + &Slet + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Eksporter Adressekartoteketsdata + + + + Comma separated file (*.csv) + Kommasepareret fil (*. csv) + + + + Error exporting + Fejl under eksport + + + + Could not write to file %1. + Kunne ikke skrive til filen %1. + + + + AddressTableModel + + + Label + Etiket + + + + Address + Adresse + + + + (no label) + (ingen etiket) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Indtast adgangskode + + + + New passphrase + Ny adgangskode + + + + Repeat new passphrase + Gentag ny adgangskode + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Indtast den nye adgangskode til tegnebogen.<br/>Brug venligst en adgangskode på <b>10 eller flere tilfældige tegn</b>, eller <b>otte eller flere ord</b>. + + + + Encrypt wallet + Krypter tegnebog + + + + This operation needs your wallet passphrase to unlock the wallet. + Denne funktion har brug for din tegnebogs kodeord for at låse tegnebogen op. + + + + Unlock wallet + Lås tegnebog op + + + + This operation needs your wallet passphrase to decrypt the wallet. + Denne funktion har brug for din tegnebogs kodeord for at dekryptere tegnebogen. + + + + Decrypt wallet + Dekryptér tegnebog + + + + Change passphrase + Skift adgangskode + + + + Enter the old and new passphrase to the wallet. + Indtast den gamle og nye adgangskode til tegnebogen. + + + + Confirm wallet encryption + Bekræft tegnebogskryptering + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ADVARSEL: Hvis du krypterer din tegnebog og mister dit kodeord vil du <b>miste alle dine BITCOINS</b>! +Er du sikker på at du ønsker at kryptere din tegnebog? + + + + + Wallet encrypted + Tegnebog krypteret + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + Tegnebogskryptering mislykkedes + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Tegnebogskryptering mislykkedes på grund af en intern fejl. Din tegnebog blev ikke krypteret. + + + + + The supplied passphrases do not match. + De angivne kodeord stemmer ikke overens. + + + + Wallet unlock failed + Tegnebogsoplåsning mislykkedes + + + + + + The passphrase entered for the wallet decryption was incorrect. + Det angivne kodeord for tegnebogsdekrypteringen er forkert. + + + + Wallet decryption failed + Tegnebogsdekryptering mislykkedes + + + + Wallet passphrase was succesfully changed. + Tegnebogskodeord blev ændret. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin Tegnebog + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Synkroniserer med netværk ... + + + + &Overview + &Oversigt + + + + Show general overview of wallet + Vis generel oversigt over tegnebog + + + + &Transactions + &Transaktioner + + + + Browse transaction history + Gennemse transaktionshistorik + + + + &Address Book + &Adressebog + + + + Edit the list of stored addresses and labels + Rediger listen over gemte adresser og etiketter + + + + &Receive coins + &Modtag coins + + + + Show the list of addresses for receiving payments + Vis listen over adresser for at modtage betalinger + + + + &Send coins + &Send coins + + + + Prove you control an address + + + + + E&xit + &Luk + + + + Quit application + Afslut program + + + + &About %1 + &Om %1 + + + + Show information about Bitcoin + Vis oplysninger om Bitcoin + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + &Indstillinger ... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Eksporter... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + Kryptér eller dekryptér tegnebog + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + Skift kodeord anvendt til tegnebogskryptering + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Fil + + + + &Settings + &Indstillinger + + + + &Help + &Hjælp + + + + Tabs toolbar + Faneværktøjslinje + + + + Actions toolbar + Handlingsværktøjslinje + + + + + [testnet] + [testnet] + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + %n aktiv(e) forbindelse(r) til Bitcoinnetværket%n aktiv(e) forbindelse(r) til Bitcoinnetværket + + + + Downloaded %1 blocks of transaction history. + Downloadet %1 blokke af transaktionshistorie. + + + + %n second(s) ago + %n sekund(er) siden%n sekund(er) siden + + + + %n minute(s) ago + %n minut(ter) siden%n minut(ter) siden + + + + %n hour(s) ago + %n time(r) siden%n time(r) siden + + + + %n day(s) ago + %n dag(e) siden%n dag(e) siden + + + + Up to date + Opdateret + + + + Catching up... + Indhenter... + + + + Last received block was generated %1. + Sidst modtagne blok blev genereret %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Denne transaktion er over størrelsesbegrænsningen. Du kan stadig sende den for et gebyr på %1 som går til de noder der behandler din transaktion, og som hjælper med at støtte netværket. Ønsker du at betale gebyret? + + + + Confirm transaction fee + + + + + Sent transaction + Afsendt transaktion + + + + Incoming transaction + Indgående transaktion + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Dato: %1 +Beløb: %2 +Type: %3 +Adresse: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Tegnebog er <b>krypteret</b> og i øjeblikket <b>ulåst</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Tegnebog er <b>krypteret</b> og i øjeblikket <b>låst</b> + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Visning + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Vælg den standard underopdelingsenhed som skal vises i brugergrænsefladen, og når du sender coins + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Rediger Adresse + + + + &Label + &Etiket + + + + The label associated with this address book entry + Etiketten forbundet med denne post i adressekartoteket + + + + &Address + &Adresse + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Adressen tilknyttet til denne post i adressekartoteket. Dette kan kun ændres for afsendelsesadresser. + + + + New receiving address + Ny modtagelsesadresse + + + + New sending address + Ny afsendelsesadresse + + + + Edit receiving address + Rediger modtagelsesadresse + + + + Edit sending address + Rediger afsendelsesadresse + + + + The entered address "%1" is already in the address book. + Den indtastede adresse "%1" er allerede i adressebogen. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Kunne ikke låse tegnebog op. + + + + New key generation failed. + Ny nøglegenerering mislykkedes. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Anvendelse: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + Start minimeret + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Betal transaktions&gebyr + + + + Main + Generelt + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + Vælg adresse fra adressebog + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Indsæt adresse fra udklipsholderen + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Indtast en Bitcoinadresse (f.eks. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Konfigurer port vha. &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Åbn Bitcoinklient-porten på routeren automatisk. Dette virker kun når din router understøtter UPnP og UPnP er aktiveret. + + + + &Connect through SOCKS4 proxy: + &Forbind gennem SOCKS4 proxy: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Opret forbindelse til Bitconnetværket via en SOCKS4 proxy (f.eks. ved tilslutning gennem Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + IP-adressen på proxyen (f.eks. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Porten på proxyen (f.eks. 1234) + + + + OptionsDialog + + + Options + Indstillinger + + + + OverviewPage + + + Form + Formular + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Saldo: + + + + Number of transactions: + Antal transaktioner: + + + + Unconfirmed: + Ubekræftede: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Nyeste transaktioner</b> + + + + Your current balance + Din nuværende saldo + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Summen af ​​transaktioner, der endnu ikke er bekræftet, og endnu ikke er inkluderet i den nuværende saldo + + + + Total number of transactions in wallet + Samlede antal transaktioner i tegnebogen + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + Besked: + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Send Coins + + + + Send to multiple recipients at once + Send til flere modtagere på én gang + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + Saldo: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Bekræft afsendelsen + + + + &Send + &Afsend + + + + <b>%1</b> to %2 (%3) + <b>%1</b> til %2 (%3) + + + + Confirm send coins + Bekræft afsendelse af coins + + + + Are you sure you want to send %1? + Er du sikker på at du vil sende %1? + + + + and + og + + + + The recepient address is not valid, please recheck. + Modtagerens adresse er ikke gyldig. Tjek venligst adressen igen. + + + + The amount to pay must be larger than 0. + Beløbet til betaling skal være større end 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Formular + + + + A&mount: + B&eløb: + + + + Pay &To: + Betal &Til: + + + + + Enter a label for this address to add it to your address book + Indtast en etiket for denne adresse for at føje den til din adressebog + + + + &Label: + &Etiket: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adresse som betalingen skal sendes til (f.eks. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Vælg adresse fra adressebog + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Indsæt adresse fra udklipsholderen + + + + Alt+P + Alt+P + + + + Remove this recipient + Fjern denne modtager + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Indtast en Bitcoinadresse (f.eks. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Åben for %1 blokke + + + + Open until %1 + Åben indtil %1 + + + + %1/offline? + %1/offline? + + + + %1/unconfirmed + %1/ubekræftet + + + + %1 confirmations + %1 bekræftelser + + + + <b>Status:</b> + <b>Status:</b> + + + + , has not been successfully broadcast yet + , er ikke blevet transmitteret endnu + + + + , broadcast through %1 node + , transmitteret via %1 node + + + + , broadcast through %1 nodes + , transmitteret via %1 noder + + + + <b>Date:</b> + <b>Dato:</b> + + + + <b>Source:</b> Generated<br> + <b>Kilde:</b> Genereret<br> + + + + + <b>From:</b> + <b>Fra:</b> + + + + unknown + ukendt + + + + + + <b>To:</b> + <b>Til:</b> + + + + (yours, label: + (din, etiket: + + + + (yours) + (din) + + + + + + + <b>Credit:</b> + <b>Kredit:</b> + + + + (%1 matures in %2 more blocks) + (%1 modnes i %2 blokke mere) + + + + (not accepted) + (ikke accepteret) + + + + + + <b>Debit:</b> + <b>Debet:</b> + + + + <b>Transaction fee:</b> + <b>Transaktionsgebyr:</b> + + + + <b>Net amount:</b> + <b>Nettobeløb:</b> + + + + Message: + Besked: + + + + Comment: + Kommentar: + + + + Transaction ID: + + + + + 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. + Genererede coins skal vente 120 blokke, før de kan blive brugt. Da du genererede denne blok blev det transmitteret til netværket, for at blive føjet til blokkæden. Hvis det mislykkes at komme ind i kæden, vil den skifte til "ikke godkendt", og ikke blive kunne bruges. Dette kan lejlighedsvis ske, hvis en anden node genererer en blok inden for få sekunder af din. + + + + TransactionDescDialog + + + Transaction details + Transaktionsdetaljer + + + + This pane shows a detailed description of the transaction + Denne rude viser en detaljeret beskrivelse af transaktionen + + + + TransactionTableModel + + + Date + Dato + + + + Type + Type + + + + Address + Adresse + + + + Amount + Beløb + + + + Open for %n block(s) + Åben for %n blok(ke)Åben for %n blok(ke) + + + + Open until %1 + Åben indtil %1 + + + + Offline (%1 confirmations) + Offline (%1 bekræftelser) + + + + Unconfirmed (%1 of %2 confirmations) + Ubekræftet (%1 af %2 bekræftelser) + + + + Confirmed (%1 confirmations) + Bekræftet (%1 bekræftelser) + + + + Mined balance will be available in %n more blocks + Minerede balance vil være tilgængelig om %n blok(ke)Minerede balance vil være tilgængelig om %n blok(ke) + + + + This block was not received by any other nodes and will probably not be accepted! + Denne blok blev ikke modtaget af nogen andre noder, og vil formentlig ikke blive accepteret! + + + + Generated but not accepted + Genereret, men ikke accepteret + + + + Received with + Modtaget med + + + + Received from + + + + + Sent to + Sendt til + + + + Payment to yourself + Betaling til dig selv + + + + Mined + Minerede + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + Transactionsstatus. Hold musen over dette felt for at vise antallet af bekræftelser. + + + + Date and time that the transaction was received. + Dato og tid for at transaktionen blev modtaget. + + + + Type of transaction. + Type af transaktion. + + + + Destination address of transaction. + Destinationsadresse for transaktion. + + + + Amount removed from or added to balance. + Beløb fjernet eller tilføjet balance. + + + + TransactionView + + + + All + Alle + + + + Today + I dag + + + + This week + Denne uge + + + + This month + Denne måned + + + + Last month + Sidste måned + + + + This year + Dette år + + + + Range... + Interval... + + + + Received with + Modtaget med + + + + Sent to + Sendt til + + + + To yourself + Til dig selv + + + + Mined + Minerede + + + + Other + Andet + + + + Enter address or label to search + Indtast adresse eller etiket for at søge + + + + Min amount + Min. beløb + + + + Copy address + Kopier adresse + + + + Copy label + Kopier etiket + + + + Copy amount + + + + + Edit label + Rediger etiket + + + + Show transaction details + + + + + Export Transaction Data + Eksportér Transaktionsdata + + + + Comma separated file (*.csv) + Kommasepareret fil (*.csv) + + + + Confirmed + Bekræftet + + + + Date + Dato + + + + Type + Type + + + + Label + Etiket + + + + Address + Adresse + + + + Amount + Beløb + + + + ID + ID + + + + Error exporting + Fejl under eksport + + + + Could not write to file %1. + Kunne ikke skrive til filen %1. + + + + Range: + Interval: + + + + to + til + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Kopier den valgte adresse til systemets udklipsholder + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Sender... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Minimer til systembakken i stedet for proceslinjen + + + + Show only a tray icon after minimizing the window + Vis kun et systembakkeikon efter minimering af vinduet + + + + M&inimize on close + + + + + 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. + Minimer i stedet for at afslutte programmet når vinduet lukkes. Når denne indstilling er valgt vil programmet kun blive lukket når du har valgt Afslut i menuen. + + + + bitcoin-core + + + Bitcoin version + Bitcoinversion + + + + Usage: + Anvendelse: + + + + Send command to -server or bitcoind + Send kommando til -server eller bitcoind + + + + + List commands + Liste over kommandoer + + + + + Get help for a command + Få hjælp til en kommando + + + + + Options: + Indstillinger: + + + + + Specify configuration file (default: bitcoin.conf) + Angiv konfigurationsfil (standard: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + Angiv pid-fil (default: bitcoind.pid) + + + + + Generate coins + Generér coins + + + + + Don't generate coins + Generér ikke coins + + + + + Specify data directory + Angiv databibliotek + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Angiv tilslutningstimeout (i millisekunder) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + Tilslut kun til den angivne node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Accepter kommandolinje- og JSON-RPC-kommandoer + + + + + Run in the background as a daemon and accept commands + Kør i baggrunden som en service, og acceptér kommandoer + + + + + Use the test network + Brug test-netværket + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + Brugernavn til JSON-RPC-forbindelser + + + + + Password for JSON-RPC connections + Password til JSON-RPC-forbindelser + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Lyt til JSON-RPC-forbindelser på <port> (standard: 8332) + + + + + Allow JSON-RPC connections from specified IP address + Tillad JSON-RPC-forbindelser fra bestemt IP-adresse + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Send kommandoer til node, der kører på <ip> (standard: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + Sæt nøglepoolstørrelse til <n> (standard: 100) + + + + + Rescan the block chain for missing wallet transactions + Gennemsøg blokkæden for manglende tegnebogstransaktioner + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL-indstillinger: (se Bitcoin Wiki for SSL opsætningsinstruktioner) + + + + Use OpenSSL (https) for JSON-RPC connections + Brug OpenSSL (https) for JSON-RPC-forbindelser + + + + + Server certificate file (default: server.cert) + Servercertifikat-fil (standard: server.cert) + + + + + Server private key (default: server.pem) + Server private nøgle (standard: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Acceptabele ciphers (standard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + Denne hjælpebesked + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Kan låse data-biblioteket %s. Bitcoin kører sikkert allerede. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Indlæser adresser... + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Fejl: Oprettelse af transaktionen mislykkedes + + + + Sending... + Sender... + + + + 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. + Fejl: Transaktionen blev afvist. Dette kan ske hvis nogle af dine coins i din tegnebog allerede var brugt, som hvis du brugte en kopi af wallet.dat og dine coins er blevet brugt i kopien, men ikke er markeret som brugt her. + + + + Invalid amount + + + + + Insufficient funds + Du har ikke penge nok + + + + Loading block index... + Indlæser blok-indeks... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Indlæser tegnebog... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Genindlæser... + + + + Done loading + Indlæsning gennemført + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Advarsel: Undersøg venligst at din computers dato og klokkeslet er korrekt indstillet. Hvis der er fejl i disse vil Bitcoin ikke fungere korrekt. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts new file mode 100644 index 0000000..2b9aaf3 --- /dev/null +++ b/src/qt/locale/bitcoin_de.ts @@ -0,0 +1,2518 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Über Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> Version + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Bitcoin Entwickler + +Dies ist experimentelle Software. + +Veröffentlicht unter der MIT/X11 Software-Lizenz, siehe beiligende Datei license.txt oder http://www.opensource.org/licenses/mit-license.php. + +Dieses Produkt enthält Software, die vom OpenSSL Projekt zur Verwendung im OpenSSL Toolkit (http://www.openssl.org/) entwickelt wurde, sowie kryptographische Software geschrieben von Eric Young (eay@cryptsoft.com) und UPnP Software geschrieben von Thomas Bernard. + + + + AddressBookPage + + + Address Book + Adressbuch + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Dies sind Ihre Bitcoin-Adressen zum Empfangen von Zahlungen. Es steht Ihnen frei, jedem Absender eine andere mitzuteilen, um einen besseren Überblick über eingehende Zahlungen zu erhalten. + + + + Double-click to edit address or label + Doppelklicken, um die Adresse oder die Bezeichnung zu bearbeiten + + + + Create a new address + Eine neue Adresse erstellen + + + + Copy the currently selected address to the system clipboard + Ausgewählte Adresse in die Zwischenablage kopieren + + + + &New Address + &Neue Adresse + + + + &Copy Address + Adresse &kopieren + + + + Show &QR Code + &QR-Code anzeigen + + + + Sign a message to prove you own this address + Eine Nachricht signieren, um den Besitz einer Adresse zu beweisen + + + + &Sign Message + Nachricht &signieren + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Die ausgewählte Adresse aus der Liste entfernen. Sie können nur Zahlungsadressen entfernen. + + + + &Delete + &Löschen + + + + Copy &Label + &Bezeichnung kopieren + + + + &Edit + &Editieren + + + + Export Address Book Data + Adressbuch exportieren + + + + Comma separated file (*.csv) + Kommagetrennte Datei (*.csv) + + + + Error exporting + Fehler beim Exportieren + + + + Could not write to file %1. + Konnte nicht in Datei %1 schreiben. + + + + AddressTableModel + + + Label + Bezeichnung + + + + Address + Adresse + + + + (no label) + (keine Bezeichnung) + + + + AskPassphraseDialog + + + Passphrase Dialog + Passphrasen Dialog + + + + Enter passphrase + Passphrase eingeben + + + + New passphrase + Neue Passphrase + + + + Repeat new passphrase + Neue Passphrase wiederholen + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Geben Sie die neue Passphrase für die Brieftasche ein.<br>Bitte benutzen Sie eine Passphrase bestehend aus <b>10 oder mehr zufälligen Zeichen</b> oder <b>8 oder mehr Wörtern</b>. + + + + Encrypt wallet + Brieftasche verschlüsseln + + + + This operation needs your wallet passphrase to unlock the wallet. + Dieser Vorgang benötigt Ihre Passphrase um die Brieftasche zu entsperren. + + + + Unlock wallet + Brieftasche entsperren + + + + This operation needs your wallet passphrase to decrypt the wallet. + Dieser Vorgang benötigt Ihre Passphrase um die Brieftasche zu entschlüsseln. + + + + Decrypt wallet + Brieftasche entschlüsseln + + + + Change passphrase + Passphrase ändern + + + + Enter the old and new passphrase to the wallet. + Geben Sie die alte und die neue Passphrase der Brieftasche ein. + + + + Confirm wallet encryption + Verschlüsselung der Brieftasche bestätigen + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + WARNUNG: Wenn Sie Ihre Brieftasche verschlüsseln und Ihre Passphrase verlieren, werden Sie <b>ALLE IHRE BITCOINS VERLIEREN</b>!<br><br>Sind Sie sich sicher, dass Sie Ihre Brieftasche verschlüsseln möchten? + + + + + Wallet encrypted + Brieftasche verschlüsselt + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin wird jetzt beendet, um den Verschlüsselungsprozess abzuschließen. Bitte beachten Sie, dass die Verschlüsselung Ihrer Brieftasche nicht vollständig vor Diebstahl Ihrer Bitcoins durch Schadsoftware schützt, die Ihren Computer befällt. + + + + + Warning: The Caps Lock key is on. + Warnung: Die Feststelltaste ist aktiviert. + + + + + + + Wallet encryption failed + Verschlüsselung der Brieftasche fehlgeschlagen + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Die Verschlüsselung der Brieftasche ist aufgrund eines internen Fehlers fehlgeschlagen. Ihre Brieftasche wurde nicht verschlüsselt. + + + + + The supplied passphrases do not match. + Die eingegebenen Passphrasen stimmen nicht überein. + + + + Wallet unlock failed + Entsperrung der Brieftasche fehlgeschlagen + + + + + + The passphrase entered for the wallet decryption was incorrect. + Die eingegebene Passphrase zum Entschlüsseln der Brieftasche war nicht korrekt. + + + + Wallet decryption failed + Entschlüsselung der Brieftasche fehlgeschlagen + + + + Wallet passphrase was succesfully changed. + Die Passphrase der Brieftasche wurde erfolgreich geändert. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin-Brieftasche + + + + Sign &message... + Nachricht s&ignieren... + + + + Show/Hide &Bitcoin + Zeige/Verstecke &Bitcoin + + + + Synchronizing with network... + Synchronisiere mit Netzwerk... + + + + &Overview + &Übersicht + + + + Show general overview of wallet + Allgemeine Übersicht der Brieftasche anzeigen + + + + &Transactions + &Transaktionen + + + + Browse transaction history + Transaktionsverlauf durchsehen + + + + &Address Book + &Adressbuch + + + + Edit the list of stored addresses and labels + Liste der gespeicherten Zahlungsadressen und Bezeichnungen bearbeiten + + + + &Receive coins + Bitcoins &empfangen + + + + Show the list of addresses for receiving payments + Liste der Empfangsadressen anzeigen + + + + &Send coins + Bitcoins &überweisen + + + + Prove you control an address + Beweisen Sie die Kontrolle einer Adresse + + + + E&xit + &Beenden + + + + Quit application + Anwendung beenden + + + + &About %1 + &Über %1 + + + + Show information about Bitcoin + Informationen über Bitcoin anzeigen + + + + About &Qt + Über &Qt + + + + Show information about Qt + Informationen über Qt anzeigen + + + + &Options... + &Erweiterte Einstellungen... + + + + &Encrypt Wallet... + Brieftasche &verschlüsseln... + + + + &Backup Wallet... + Brieftasche &sichern... + + + + &Change Passphrase... + Passphrase &ändern... + + + + ~%n block(s) remaining + ~%n Block verbleibend~%n Blöcke verbleibend + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + %1 von %2 Blöcken des Transaktionsverlaufs heruntergeladen (%3% fertig). + + + + &Export... + &Exportieren nach... + + + + Send coins to a Bitcoin address + Bitcoins an eine Bitcoin-Adresse überweisen + + + + Modify configuration options for Bitcoin + Erweiterte Bitcoin-Einstellungen ändern + + + + Show or hide the Bitcoin window + Zeige oder verstecke das Bitcoin Fenster + + + + Export the data in the current tab to a file + Daten der aktuellen Ansicht in eine Datei exportieren + + + + Encrypt or decrypt wallet + Brieftasche ent- oder verschlüsseln + + + + Backup wallet to another location + Eine Sicherungskopie der Brieftasche erstellen und abspeichern + + + + Change the passphrase used for wallet encryption + Ändert die Passphrase, die für die Verschlüsselung der Brieftasche benutzt wird + + + + &Debug window + &Debug-Fenster + + + + Open debugging and diagnostic console + Debugging- und Diagnose-Konsole öffnen + + + + &Verify message... + Nachricht &verifizieren... + + + + Verify a message signature + Eine Nachrichten-Signatur verifizieren + + + + &File + &Datei + + + + &Settings + &Einstellungen + + + + &Help + &Hilfe + + + + Tabs toolbar + Registerkarten-Leiste + + + + Actions toolbar + Aktionen-Werkzeugleiste + + + + + [testnet] + [Testnetz] + + + + + Bitcoin client + Bitcoin Client + + + + %n active connection(s) to Bitcoin network + %n aktive Verbindung zum Bitcoin-Netzwerk%n aktive Verbindungen zum Bitcoin-Netzwerk + + + + Downloaded %1 blocks of transaction history. + %1 Blöcke des Transaktionsverlaufs heruntergeladen. + + + + %n second(s) ago + vor %n Sekundevor %n Sekunden + + + + %n minute(s) ago + vor %n Minutevor %n Minuten + + + + %n hour(s) ago + vor %n Stundevor %n Stunden + + + + %n day(s) ago + vor %n Tagvor %n Tagen + + + + Up to date + Auf aktuellem Stand + + + + Catching up... + Hole auf... + + + + Last received block was generated %1. + Der letzte empfangene Block wurde %1 generiert. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Die Transaktion übersteigt das Größenlimit. Sie können sie trotzdem senden, wenn Sie eine zusätzliche Transaktionsgebühr in Höhe von %1 zahlen. Diese wird an die Knoten verteilt, die Ihre Transaktion bearbeiten und unterstützt damit das Bitcoin-Netzwerk.<br><br>Möchten Sie die Gebühr bezahlen? + + + + Confirm transaction fee + Transaktionsgebühr bestätigen + + + + Sent transaction + Gesendete Transaktion + + + + Incoming transaction + Eingehende Transaktion + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Datum: %1 +Betrag: %2 +Typ: %3 +Adresse: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Brieftasche ist <b>verschlüsselt</b> und aktuell <b>entsperrt</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Brieftasche ist <b>verschlüsselt</b> und aktuell <b>gesperrt</b> + + + + Backup Wallet + Brieftasche sichern + + + + Wallet Data (*.dat) + Brieftaschen-Datei (*.dat) + + + + Backup Failed + Sicherung der Brieftasche fehlgeschlagen + + + + There was an error trying to save the wallet data to the new location. + Fehler beim Abspeichern der Sicherungskopie der Brieftasche. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + Ein schwerer Fehler ist aufgetreten. Bitcoin kann nicht stabil weiter ausgeführt werden und wird beendet. + + + + ClientModel + + + Network Alert + Netzwerk-Alarm + + + + DisplayOptionsPage + + + Display + Anzeige + + + + default + Standard + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + Legt die Sprache der Benutzeroberfläche fest. Diese Einstellung wird erst nach einem Neustart von Bitcoin aktiv. + + + + User Interface &Language: + &Sprache der Benutzeroberfläche: + + + + &Unit to show amounts in: + &Einheit der Beträge: + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Wählen Sie die Standard-Untereinheit, die in der Benutzeroberfläche und beim Überweisen von Bitcoins angezeigt werden soll + + + + &Display addresses in transaction list + Adressen in der Transaktionsliste &anzeigen + + + + Whether to show Bitcoin addresses in the transaction list + Legt fest, ob Bitcoin-Addressen in der Transaktionsliste angezeigt werden + + + + Warning + Warnung + + + + This setting will take effect after restarting Bitcoin. + Diese Einstellung wird erst nach einem Neustart von Bitcoin aktiv. + + + + EditAddressDialog + + + Edit Address + Adresse bearbeiten + + + + &Label + &Bezeichnung + + + + The label associated with this address book entry + Die Bezeichnung dieses Adressbuchseintrags + + + + &Address + &Adresse + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Die Adresse des Adressbucheintrags. Diese kann nur für Zahlungsadressen bearbeitet werden. + + + + New receiving address + Neue Empfangsadresse + + + + New sending address + Neue Zahlungsadresse + + + + Edit receiving address + Empfangsadresse bearbeiten + + + + Edit sending address + Zahlungsadresse bearbeiten + + + + The entered address "%1" is already in the address book. + Die eingegebene Adresse "%1" befindet sich bereits im Adressbuch. + + + + The entered address "%1" is not a valid Bitcoin address. + Die eingegebene Adresse "%1" ist keine gültige Bitcoin-Adresse. + + + + Could not unlock wallet. + Die Brieftasche konnte nicht entsperrt werden. + + + + New key generation failed. + Generierung eines neuen Schlüssels fehlgeschlagen. + + + + HelpMessageBox + + + + Bitcoin-Qt + Bitcoin-Qt + + + + version + Version + + + + Usage: + Benutzung: + + + + options + Kommandozeilen-Optionen + + + + UI options + UI Optionen + + + + Set language, for example "de_DE" (default: system locale) + Sprache festlegen, z.B. "de_DE" (Standard: System Locale) + + + + Start minimized + Minimiert starten + + + + Show splash screen on startup (default: 1) + Startbildschirm beim Starten anzeigen (Standard: 1) + + + + MainOptionsPage + + + 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. + Block- und Adressdatenbank beim Beenden trennen. Diese können so in ein anderes Datenverzeichnis verschoben werden, die zum Beenden benötigte Zeit wird aber verlängert. Die Datenbank der Brieftasche wird immer getrennt. + + + + Pay transaction &fee + Transaktions&gebühr bezahlen + + + + Main + Allgemein + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Optionale Transaktionsgebühr pro kB, die sicherstellt, dass Ihre Transaktionen schnell bearbeitet werden. Die meisten Transaktionen sind 1 kB groß. Eine Gebühr von 0.01 BTC wird empfohlen. + + + + &Start Bitcoin on system login + &Starte Bitcoin nach Systemanmeldung + + + + Automatically start Bitcoin after logging in to the system + Bitcoin nach der Anmeldung am System automatisch ausführen + + + + &Detach databases at shutdown + Datenbanken beim Beenden &trennen + + + + MessagePage + + + Sign Message + Nachricht signieren + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Sie können Nachrichten mit Ihren Adressen signieren, um den Besitz dieser Adressen zu beweisen. Bitte nutzen Sie diese Funktion mit Vorsicht und nehmen Sie sich vor Phishing-Angriffen in Acht. Signieren Sie nur Nachrichten, mit denen Sie vollständig einverstanden sind. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Die Adresse mit der die Nachricht signiert wird (z.B. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Adresse aus dem Adressbuch auswählen + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Adresse aus der Zwischenablage einfügen + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Zu signierende Nachricht hier eingeben + + + + Copy the current signature to the system clipboard + Aktuelle Signatur in die Zwischenablage kopieren + + + + &Copy Signature + Signatur &kopieren + + + + Reset all sign message fields + Alle Nachricht signieren Felder zurücksetzen + + + + Clear &All + &Zurücksetzen + + + + Click "Sign Message" to get signature + Auf "Nachricht signieren" klicken, um die Signatur zu erhalten + + + + Sign a message to prove you own this address + Die Nachricht signieren, um den Besitz der angegebenen Adresse nachzuweisen + + + + &Sign Message + Nachricht &signieren + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Bitcoin-Adresse eingeben (z.B. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Fehler beim Erzeugen der Signatur + + + + %1 is not a valid address. + %1 ist keine gültige Adresse. + + + + %1 does not refer to a key. + "%1" verweist nicht auf einen Schlüssel. + + + + Private key for %1 is not available. + Privater Schlüssel für %1 ist nicht verfügbar. + + + + Sign failed + Signierung der Nachricht fehlgeschlagen + + + + NetworkOptionsPage + + + Network + Netzwerk + + + + Map port using &UPnP + Portweiterleitung via &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Automatisch den Bitcoin Client-Port auf dem Router öffnen. Dies funktioniert nur, wenn Ihr Router UPnP unterstützt und dies aktiviert ist. + + + + &Connect through SOCKS4 proxy: + Über einen SOCKS4-Proxy &verbinden: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Über einen SOCKS4-Proxy mit dem Bitcoin-Netzwerk verbinden (z.B. bei einer Verbindung über Tor) + + + + Proxy &IP: + Proxy-&IP: + + + + &Port: + &Port: + + + + IP address of the proxy (e.g. 127.0.0.1) + IP-Adresse des Proxy-Servers (z.B. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Port des Proxy-Servers (z.B. 1234) + + + + OptionsDialog + + + Options + Erweiterte Einstellungen + + + + OverviewPage + + + Form + Formular + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + Die angezeigten Informationen sind möglicherweise nicht mehr aktuell. Ihre Brieftasche wird synchronisiert nachdem eine Verbindung zum Netzwerk hergestellt wurde, dieser Prozess ist aber derzeit noch nicht abgeschlossen. + + + + Balance: + Kontostand: + + + + Number of transactions: + Anzahl der Transaktionen: + + + + Unconfirmed: + Unbestätigt: + + + + Wallet + Brieftasche + + + + <b>Recent transactions</b> + <b>Letzte Transaktionen</b> + + + + Your current balance + Ihr aktueller Kontostand + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Betrag aus unbestätigten Transaktionen, der noch nicht im aktuellen Kontostand enthalten ist + + + + Total number of transactions in wallet + Anzahl aller Transaktionen in der Brieftasche + + + + + out of sync + nicht synchron + + + + QRCodeDialog + + + QR Code Dialog + QR-Code Dialog + + + + QR Code + QR-Code + + + + Request Payment + Zahlung anfordern + + + + Amount: + Betrag: + + + + BTC + BTC + + + + Label: + Bezeichnung: + + + + Message: + Nachricht: + + + + &Save As... + &Speichern unter... + + + + Error encoding URI into QR Code. + Fehler beim Kodieren der URI in den QR-Code. + + + + Resulting URI too long, try to reduce the text for label / message. + Resultierende URI zu lang, bitte den Text für Bezeichnung / Nachricht kürzen. + + + + Save QR Code + QR-Code abspeichern + + + + PNG Images (*.png) + PNG Bild (*.png) + + + + RPCConsole + + + Bitcoin debug window + Bitcoin Debug-Fenster + + + + Client name + Client Name + + + + + + + + + + + + N/A + n.v. + + + + Client version + Client Version + + + + &Information + &Information + + + + Client + Client + + + + Startup time + Startzeit + + + + Network + Netzwerk + + + + Number of connections + Anzahl Verbindungen + + + + On testnet + Im Testnetz + + + + Block chain + Blockkette + + + + Current number of blocks + Aktuelle Anzahl Blöcke + + + + Estimated total blocks + Geschätzte Gesamtzahl Blöcke + + + + Last block time + Letzte Block-Zeit + + + + Debug logfile + Debug-Protokolldatei + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + Öffnet die Bitcoin Debug-Protokolldatei aus dem aktuellen Datenverzeichnis. Dies kann bei großen Protokolldateien einige Sekunden dauern. + + + + &Open + &Öffnen + + + + &Console + &Konsole + + + + Build date + Erstellungsdatum + + + + Clear console + Konsole zurücksetzen + + + + Welcome to the Bitcoin RPC console. + Willkommen in der Bitcoin RPC-Konsole. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Pfeiltaste hoch und runter, um die Historie durchzublättern und <b>Strg-L</b>, um die Konsole zurückzusetzen. + + + + Type <b>help</b> for an overview of available commands. + Bitte <b>help</b> eingeben, um eine Übersicht verfügbarer Befehle zu erhalten. + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Bitcoins überweisen + + + + Send to multiple recipients at once + In einer Transaktion an mehrere Empfänger auf einmal überweisen + + + + &Add Recipient + Empfänger &hinzufügen + + + + Remove all transaction fields + Alle Überweisungsfelder zurücksetzen + + + + Clear &All + &Zurücksetzen + + + + Balance: + Kontostand: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Überweisung bestätigen + + + + &Send + &Überweisen + + + + <b>%1</b> to %2 (%3) + <b>%1</b> an %2 (%3) + + + + Confirm send coins + Überweisung bestätigen + + + + Are you sure you want to send %1? + Sind Sie sich sicher, dass Sie die folgende Überweisung ausführen möchten?<br>%1 + + + + and + und + + + + The recepient address is not valid, please recheck. + Die Zahlungsadresse ist ungültig, bitte nochmals überprüfen. + + + + The amount to pay must be larger than 0. + Der zu zahlende Betrag muss größer als 0 sein. + + + + The amount exceeds your balance. + Der angegebene Betrag übersteigt Ihren Kontostand. + + + + The total exceeds your balance when the %1 transaction fee is included. + Der angegebene Betrag übersteigt aufgrund der Transaktionsgebühr in Höhe von %1 Ihren Kontostand. + + + + Duplicate address found, can only send to each address once per send operation. + Doppelte Adresse gefunden, pro Überweisung kann an jede Adresse nur einmalig etwas überwiesen werden. + + + + Error: Transaction creation failed. + Fehler: Transaktionserstellung fehlgeschlagen. + + + + 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. + Fehler: Die Transaktion wurde abgelehnt. Dies kann passieren, wenn einige Bitcoins aus Ihrer Brieftasche bereits ausgegeben wurden. Beispielsweise weil Sie eine Kopie Ihrer wallet.dat genutzt, die Bitcoins dort ausgegeben haben und dies daher in der derzeit aktiven Brieftasche nicht vermerkt ist. + + + + SendCoinsEntry + + + Form + Formular + + + + A&mount: + &Betrag: + + + + Pay &To: + &Empfänger: + + + + + Enter a label for this address to add it to your address book + Adressbezeichnung eingeben (diese wird zusammen mit der Adresse dem Adressbuch hinzugefügt) + + + + &Label: + &Bezeichnung: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Die Zahlungsadresse der Überweisung (z.B. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Adresse aus Adressbuch wählen + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Adresse aus der Zwischenablage einfügen + + + + Alt+P + Alt+P + + + + Remove this recipient + Diesen Empfänger entfernen + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Bitcoin-Adresse eingeben (z.B. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Offen für %1 Blöcke + + + + Open until %1 + Offen bis %1 + + + + %1/offline? + %1/offline? + + + + %1/unconfirmed + %1/unbestätigt + + + + %1 confirmations + %1 Bestätigungen + + + + <b>Status:</b> + <b>Status:</b> + + + + , has not been successfully broadcast yet + , wurde noch nicht erfolgreich übertragen + + + + , broadcast through %1 node + , über %1 Knoten übertragen + + + + , broadcast through %1 nodes + , über %1 Knoten übertragen + + + + <b>Date:</b> + <b>Datum:</b> + + + + <b>Source:</b> Generated<br> + <b>Quelle:</b> Generiert<br> + + + + + <b>From:</b> + <b>Von:</b> + + + + unknown + unbekannt + + + + + + <b>To:</b> + <b>An:</b> + + + + (yours, label: + (Eigene Adresse, Bezeichnung: + + + + (yours) + (Eigene Adresse) + + + + + + + <b>Credit:</b> + <b>Gutschrift:</b> + + + + (%1 matures in %2 more blocks) + %1 (reift noch %2 weitere Blöcke) + + + + (not accepted) + (nicht angenommen) + + + + + + <b>Debit:</b> + <b>Belastung:</b> + + + + <b>Transaction fee:</b> + <b>Transaktionsgebühr:</b> + + + + <b>Net amount:</b> + <b>Nettobetrag:</b> + + + + Message: + Nachricht: + + + + Comment: + Kommentar: + + + + Transaction ID: + Transaktions-ID: + + + + 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. + Generierte Bitcoins müssen 120 Blöcke lang warten, bevor sie ausgegeben werden können. Als Sie diesen Block generierten, wurde er an das Netzwerk übertragen, um ihn der Blockkette hinzuzufügen. Falls dies fehlschlägt wird der Status in "nicht angenommen" geändert und der Betrag wird nicht verfügbar werden. Das kann gelegentlich passieren, wenn ein anderer Knoten einen Block zur selben Zeit wie Sie generierte. + + + + TransactionDescDialog + + + Transaction details + Transaktionsdetails + + + + This pane shows a detailed description of the transaction + Dieser Bereich zeigt eine detaillierte Beschreibung der Transaktion an + + + + TransactionTableModel + + + Date + Datum + + + + Type + Typ + + + + Address + Adresse + + + + Amount + Betrag + + + + Open for %n block(s) + Offen für %n BlockOffen für %n Blöcke + + + + Open until %1 + Offen bis %1 + + + + Offline (%1 confirmations) + Nicht verbunden (%1 Bestätigungen) + + + + Unconfirmed (%1 of %2 confirmations) + Unbestätigt (%1 von %2 Bestätigungen) + + + + Confirmed (%1 confirmations) + Bestätigt (%1 Bestätigungen) + + + + Mined balance will be available in %n more blocks + Der erarbeitete Betrag wird in %n Block verfügbar seinDer erarbeitete Betrag wird in %n Blöcken verfügbar sein + + + + This block was not received by any other nodes and will probably not be accepted! + Dieser Block wurde von keinem anderen Knoten empfangen und wird wahrscheinlich nicht angenommen werden! + + + + Generated but not accepted + Generiert, jedoch nicht angenommen + + + + Received with + Empfangen über + + + + Received from + Empfangen von + + + + Sent to + Überwiesen an + + + + Payment to yourself + Eigenüberweisung + + + + Mined + Erarbeitet + + + + (n/a) + (k.A.) + + + + Transaction status. Hover over this field to show number of confirmations. + Transaktionsstatus. Fahren Sie mit der Maus über dieses Feld, um die Anzahl der Bestätigungen zu sehen. + + + + Date and time that the transaction was received. + Datum und Uhrzeit als die Transaktion empfangen wurde. + + + + Type of transaction. + Art der Transaktion + + + + Destination address of transaction. + Zieladresse der Transaktion. + + + + Amount removed from or added to balance. + Der Betrag, der dem Kontostand abgezogen oder hinzugefügt wurde. + + + + TransactionView + + + + All + Alle + + + + Today + Heute + + + + This week + Diese Woche + + + + This month + Diesen Monat + + + + Last month + Letzten Monat + + + + This year + Dieses Jahr + + + + Range... + Zeitraum... + + + + Received with + Empfangen über + + + + Sent to + Überwiesen an + + + + To yourself + Eigenüberweisung + + + + Mined + Erarbeitet + + + + Other + Andere + + + + Enter address or label to search + Zu suchende Adresse oder Bezeichnung eingeben + + + + Min amount + Minimaler Betrag + + + + Copy address + Adresse kopieren + + + + Copy label + Bezeichnung kopieren + + + + Copy amount + Betrag kopieren + + + + Edit label + Bezeichnung bearbeiten + + + + Show transaction details + Transaktionsdetails anzeigen + + + + Export Transaction Data + Transaktionen exportieren + + + + Comma separated file (*.csv) + Kommagetrennte Datei (*.csv) + + + + Confirmed + Bestätigt + + + + Date + Datum + + + + Type + Typ + + + + Label + Bezeichnung + + + + Address + Adresse + + + + Amount + Betrag + + + + ID + ID + + + + Error exporting + Fehler beim Exportieren + + + + Could not write to file %1. + Konnte nicht in Datei %1 schreiben. + + + + Range: + Zeitraum: + + + + to + bis + + + + VerifyMessageDialog + + + Verify Signed Message + Signierte Nachricht verifizieren + + + + 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. + Geben Sie die Nachricht und Signatur unten ein (achten Sie besonders darauf Zeilenumbrüche, Leerzeichen, Tabulatoren und andere unsichtbare Zeichen mit zu kopieren), um die Bitcoin-Adresse zu erhalten, die zum signieren der Nachricht verwendet wurde. + + + + Verify a message and obtain the Bitcoin address used to sign the message + Eine Nachricht verifizieren und die Bitcoin-Addresse erhalten, die zum Signieren der Nachricht verwendet wurde + + + + &Verify Message + Nachricht &verifizieren + + + + Copy the currently selected address to the system clipboard + Ausgewählte Adresse in die Zwischenablage kopieren + + + + &Copy Address + Adresse &kopieren + + + + Reset all verify message fields + Alle Nachricht verifizieren Felder zurücksetzen + + + + Clear &All + &Zurücksetzen + + + + Enter Bitcoin signature + Bitcoin-Signatur eingeben + + + + Click "Verify Message" to obtain address + Auf "Nachricht verifizieren" klicken, um die Adresse zu erhalten + + + + + Invalid Signature + Signatur fehlerhaft + + + + The signature could not be decoded. Please check the signature and try again. + Die Signatur konnte nicht dekodiert werden. Bitte überprüfen Sie die Signatur und versuchen Sie es erneut. + + + + The signature did not match the message digest. Please check the signature and try again. + Die Signatur entspricht nicht dem Message Digest. Bitte überprüfen Sie die Signatur und versuchen Sie es erneut. + + + + Address not found in address book. + Adresse nicht im Adressbuch gefunden. + + + + Address found in address book: %1 + Adresse im Adressbuch gefunden: %1 + + + + WalletModel + + + Sending... + Überweise... + + + + WindowOptionsPage + + + Window + Programmfenster + + + + &Minimize to the tray instead of the taskbar + In den Infobereich anstatt in die Taskleiste &minimieren + + + + Show only a tray icon after minimizing the window + Nur ein Symbol im Infobereich anzeigen, nachdem das Fenster minimiert wurde + + + + M&inimize on close + Beim Schließen m&inimieren + + + + 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. + Minimiert die Anwendung anstatt sie zu beenden wenn das Fenster geschlossen wird. Wenn dies aktiviert ist, müssen Sie das Programm über "Beenden" im Menü schließen. + + + + bitcoin-core + + + Bitcoin version + Bitcoin Version + + + + Usage: + Benutzung: + + + + Send command to -server or bitcoind + Befehl an -server oder bitcoind senden + + + + List commands + Befehle auflisten + + + + Get help for a command + Hilfe zu einem Befehl erhalten + + + + Options: + Optionen: + + + + Specify configuration file (default: bitcoin.conf) + Konfigurationsdatei angeben (Standard: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + PID-Datei angeben (Standard: bitcoind.pid) + + + + Generate coins + Bitcoins generieren + + + + Don't generate coins + Keine Bitcoins generieren + + + + Specify data directory + Datenverzeichnis angeben + + + + Set database cache size in megabytes (default: 25) + Größe des Datenbank-Caches in MB festlegen (Standard: 25) + + + + Set database disk log size in megabytes (default: 100) + Größe der Datenbank-Logs auf der Festplatte in MB festlegen (Standard: 100) + + + + Specify connection timeout (in milliseconds) + Verbindungs-Zeitüberschreitung angeben (in Millisekunden) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + <port> nach Verbindunden abhören (Standard: 8333 oder Testnetz: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Maximal <n> Verbindungen zu Gegenstellen aufrechterhalten (Standard: 125) + + + + Connect only to the specified node + Nur mit dem angegebenem Knoten verbinden + + + + Connect to a node to retrieve peer addresses, and disconnect + Mit dem Knoten verbinden um Peer-Adressen abzufragen, danach trennen + + + + Specify your own public address + Die eigene öffentliche Addresse angeben + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + Verbinde nur zu Knoten im Netzwerk <net> (IPv4 oder IPv6) + + + + Try to discover public IP address (default: 1) + Versuche die öffentliche IP-Adresse zu erkennen (Standard: 1) + + + + Bind to given address. Use [host]:port notation for IPv6 + An die angegebene Adresse binden. Benutze [Host]:Port Schreibweise für IPv6 + + + + Threshold for disconnecting misbehaving peers (default: 100) + Schwellenwert, um Verbindungen zu sich nicht konform verhaltenden Gegenstellen zu beenden (Standard: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Anzahl Sekunden, während denen sich nicht konform verhaltenden Gegenstellen die Wiederverbindung verweigert wird (Standard: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maximale Größe, <n> * 1000 Byte, des Empfangspuffers pro Verbindung (Standard: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maximale Größe, <n> * 1000 Byte, des Sendepuffers pro Verbindung (Standard: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + Block- und Adressdatenbank beim Beenden trennen.Verlängert, die zum Beenden benötigte Zeit (Standard: 0) + + + + Accept command line and JSON-RPC commands + Kommandozeilenbefehle und JSON-RPC Befehle annehmen + + + + Run in the background as a daemon and accept commands + Als Hintergrunddienst starten und Befehle annehmen + + + + Use the test network + Das test-Netzwerk verwenden + + + + Output extra debugging information + Ausgabe zusätzlicher Debugging-Informationen + + + + Prepend debug output with timestamp + Der Debug-Ausgabe einen Zeitstempel voranstellen + + + + Send trace/debug info to console instead of debug.log file + Rückverfolgungs- und Debug-Informationen an die Konsole senden anstatt sie in die debug.log Datei zu schreiben + + + + Send trace/debug info to debugger + Rückverfolgungs- und Debug-Informationen an den Debugger senden + + + + Username for JSON-RPC connections + Benutzername für JSON-RPC Verbindungen + + + + Password for JSON-RPC connections + Passwort für JSON-RPC Verbindungen + + + + Listen for JSON-RPC connections on <port> (default: 8332) + <port> nach JSON-RPC Verbindungen abhören (Standard: 8332) + + + + Allow JSON-RPC connections from specified IP address + JSON-RPC Verbindungen von der angegebenen IP-Adresse erlauben + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Sende Befehle an Knoten <ip> (Standard: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Kommando ausführen wenn der beste Block wechselt (%s im Kommando wird durch den Hash des Blocks ersetzt) + + + + Upgrade wallet to latest format + Brieftasche auf das neueste Format aktualisieren + + + + Set key pool size to <n> (default: 100) + Größe des Schlüsselpools festlegen auf <n> (Standard: 100) + + + + Rescan the block chain for missing wallet transactions + Blockkette erneut nach fehlenden Transaktionen der Brieftasche durchsuchen + + + + How many blocks to check at startup (default: 2500, 0 = all) + Wieviele Blöcke sollen beim Starten geprüft werden (Standard: 2500, 0 = alle) + + + + How thorough the block verification is (0-6, default: 1) + Wie gründlich soll die Blockprüfung sein (0-6, Standard: 1) + + + + Imports blocks from external blk000?.dat file + Blöcke aus einer externen blk000?.dat Datei importieren + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL Optionen: (siehe Bitcoin-Wiki für SSL Installationsanweisungen) + + + + Use OpenSSL (https) for JSON-RPC connections + OpenSSL (https) für JSON-RPC Verbindungen verwenden + + + + Server certificate file (default: server.cert) + Serverzertifikat (Standard: server.cert) + + + + Server private key (default: server.pem) + Privater Serverschlüssel (Standard: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Akzeptierte Chiffren (Standard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + Warnung: Nicht mehr genügend Festplattenplatz verfügbar + + + + This help message + Dieser Hilfetext + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Datenverzeichnis %s kann nicht gesperrt werden. Evtl. wurde Bitcoin bereits gestartet. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + Kann auf diesem Computer nicht an %s binden (von bind zurückgegebener Fehler %d, %s) + + + + Connect through socks proxy + Über einen SOCKS-Proxy verbinden + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + Wählen, welche Version des SOCKS-Proxys genutzt werden soll (4 oder 5, 5 ist Standard) + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + Keinen Proxy verwenden für Verbindungen zum Netzwerk <net> (IPv4 oder IPv6) + + + + Allow DNS lookups for -addnode, -seednode and -connect + Erlaube DNS-Namensauflösung für -addnode, -seednode und -connect + + + + Pass DNS requests to (SOCKS5) proxy + DNS-Anfragen an (SOCKS5-) Proxy weiterleiten + + + + Loading addresses... + Lade Adressen... + + + + Error loading blkindex.dat + Fehler beim Laden von blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Fehler beim Laden von wallet.dat: Brieftasche beschädigt + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Fehler beim Laden von wallet.dat: Brieftasche benötigt neuere Version von Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Brieftasche muss neu geschrieben werden: Starten Sie Bitcoin zur Fertigstellung neu + + + + Error loading wallet.dat + Fehler beim Laden von wallet.dat (Brieftasche) + + + + Invalid -proxy address: '%s' + Ungültige -proxy Addresse: '%s' + + + + Unknown network specified in -noproxy: '%s' + Unbekanntes Netzwerk in -noproxy angegeben: '%s' + + + + Unknown network specified in -onlynet: '%s' + Unbekanntes Netzwerk in -onlynet angegeben: '%s' + + + + Unknown -socks proxy version requested: %i + Unbekannte -socks Proxy Version angefordert: %i + + + + Cannot resolve -bind address: '%s' + Kann -bind Adresse nicht auflösen: '%s' + + + + Not listening on any port + Es wird kein Port nach Verbindungen abgehört + + + + Cannot resolve -externalip address: '%s' + Kann -externalip Adresse nicht auflösen: '%s' + + + + Invalid amount for -paytxfee=<amount>: '%s' + Falscher Betrag für -paytxfee=<Betrag>: '%s' + + + + Error: could not start node + Fehler: Knoten konnte nicht gestartet weden + + + + Error: Wallet locked, unable to create transaction + Fehler: Brieftasche gesperrt, Transaktion kann nicht erstellt werden + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Fehler: Diese Transaktion benötigt aufgrund ihres Betrags, ihrer Komplexität oder der Nutzung kürzlich erhaltener Zahlungen eine Transaktionsgebühr in Höhe von mindestens %s. + + + + Error: Transaction creation failed + Fehler: Transaktionserstellung fehlgeschlagen + + + + Sending... + Senden... + + + + 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. + Fehler: Die Transaktion wurde abgelehnt. Dies kann passieren, wenn einige Bitcoins aus Ihrer Brieftasche bereits ausgegeben wurden. Beispielsweise weil Sie eine Kopie Ihrer wallet.dat genutzt, die Bitcoins dort ausgegeben haben und dies daher in der derzeit aktiven Brieftasche nicht vermerkt ist. + + + + Invalid amount + Ungültige Angabe + + + + Insufficient funds + Unzureichender Kontostand + + + + Loading block index... + Lade Blockindex... + + + + Add a node to connect to and attempt to keep the connection open + Mit dem Knoten verbinden und versuchen die Verbindung aufrecht zu halten + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + Kann auf diesem Computer nicht an %s binden. Evtl. wurde Bitcoin bereits gestartet. + + + + Find peers using internet relay chat (default: 0) + Gegenstellen via Internet Relay Chat finden (Standard: 0) + + + + Accept connections from outside (default: 1) + Eingehende Verbindungen annehmen (Standard: 1) + + + + Find peers using DNS lookup (default: 1) + Gegenstellen via DNS Namensauflösung finden (Standard: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + UPnP verwenden, um die Portweiterleitung einzurichten (Standard: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + UPnP verwenden, um die Portweiterleitung einzurichten (Standard: 0) + + + + Fee per KB to add to transactions you send + Gebühr pro KB, die gesendeten Transaktionen hinzugefügt wird + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + Warnung: -paytxfee ist auf einen sehr hohen Wert festgelegt. Dies ist die Gebühr die beim Senden einer Transaktion fällig wird. + + + + Loading wallet... + Lade Geldbörse... + + + + Cannot downgrade wallet + Brieftasche kann nicht auf eine ältere Version herabgestuft werden + + + + Cannot initialize keypool + Schlüsselpool kann nicht initialisiert werden + + + + Cannot write default address + Standardadresse kann nicht geschrieben werden + + + + Rescanning... + Durchsuche erneut... + + + + Done loading + Laden abgeschlossen + + + + To use the %s option + Zur Nutzung der %s Option + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, Sie müssen den Wert rpcpasswort in der Konfigurationsdatei angeben +%s +Es wird empfohlen das folgende Zufallspasswort zu verwenden: +rpcuser=bitcoinrpc +rpcpassword=%s +(Sie müssen sich dieses Passwort nicht merken!) +Falls die Konfigurationsdatei nicht existiert, erzeugen Sie diese bitte mit Leserechten nur für den Dateibesitzer. + + + + + Error + Fehler + + + + An error occured while setting up the RPC port %i for listening: %s + Fehler beim Einrichten des RPC-Ports %i: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Sie müssen den Wert rpcpassword=<passwort> in der Konfigurationsdatei angeben: +%s +Falls die Konfigurationsdatei nicht existiert, erzeugen Sie diese bitte mit Leserechten nur für den Dateibesitzer. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Warnung: Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin ansonsten nicht ordnungsgemäß funktionieren wird. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts new file mode 100644 index 0000000..2058e1a --- /dev/null +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -0,0 +1,2521 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Σχετικα:Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b>έκδοση + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Προγραμματιστές του Bitcoin + +Αυτό ειναι πειραματικο λογισμικο. + +Διανέμεται κατω από άδεια MIT/X11 , δες το συνοδεύων αρχειο license.txt ή http://www.opensource.org/licenses/mit-license.php. + +Αυτό προϊόν περιλαμβάνει λογισμικο ανεπτυγμενο από το OpenSSL Project για χρήση στο OpenSSL Toolkit (http://www.openssl.org/) και κρυπτογραφικο κωδικα γραμένο από τον by Eric Young (eay@cryptsoft.com) και λογισμικο UPnP γραμένο από τον Thomas Bernard. + + + + AddressBookPage + + + Address Book + Βιβλίο Διευθύνσεων + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Αυτές είναι οι διευθύνσεις Bitcoin για την παραλαβή πληρωμών. Μπορεί να θέλετε να δίνετε διαφορετική διεύθυνση σε κάθε αποστολέα έτσι ώστε να μπορείτε να παρακολουθείτε ποιος σας πληρώνει. + + + + Double-click to edit address or label + Διπλό-κλικ για επεξεργασία της διεύθυνσης ή της ετικέτας + + + + Create a new address + Δημιούργησε νέα διεύθυνση + + + + Copy the currently selected address to the system clipboard + Αντέγραψε την επιλεγμένη διεύθυνση στο πρόχειρο του συστήματος + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Δείξε &QR κωδικα + + + + Sign a message to prove you own this address + Υπέγραψε ένα μήνυμα για να αποδείξεις ότι σου ανήκει η διεύθυνση + + + + &Sign Message + &Υπέγραψε το μήνυμα + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Διέγραψε την επιλεγμένη διεύθυνση από την λίστα. Μόνο διευθύνσεις αποστολής μπορούν να διαγραφούν. + + + + &Delete + &Διαγραφή + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Εξαγωγή Δεδομενων Βιβλίου Διευθύνσεων + + + + Comma separated file (*.csv) + Αρχείο οριοθετημένο με κόμματα (*.csv) + + + + Error exporting + Εξαγωγή λαθών + + + + Could not write to file %1. + Δεν μπόρεσα να γράψω στο αρχείο %1. + + + + AddressTableModel + + + Label + Ετικέτα + + + + Address + Διεύθυνση + + + + (no label) + (χωρίς ετικέτα) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Βάλτε κωδικό πρόσβασης + + + + New passphrase + Νέος κωδικός πρόσβασης + + + + Repeat new passphrase + Επανέλαβε τον νέο κωδικό πρόσβασης + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Εισάγετε τον νέο κωδικό πρόσβασης στον πορτοφόλι <br/> Παρακαλώ χρησιμοποιείστε ένα κωδικό με <b> 10 ή περισσότερους τυχαίους χαρακτήρες</b> ή <b> οχτώ ή παραπάνω λέξεις</b>. + + + + Encrypt wallet + Κρυπτογράφησε το πορτοφόλι + + + + This operation needs your wallet passphrase to unlock the wallet. + Αυτη η ενεργεία χρειάζεται τον κωδικό του πορτοφολιού για να ξεκλειδώσει το πορτοφόλι. + + + + Unlock wallet + Ξεκλειδωσε το πορτοφολι + + + + This operation needs your wallet passphrase to decrypt the wallet. + Αυτη η ενεργεια χρειάζεται τον κωδικο του πορτοφολιου για να αποκρυπτογραφησειι το πορτοφολι. + + + + Decrypt wallet + Αποκρυπτογράφησε το πορτοφολι + + + + Change passphrase + Άλλαξε κωδικο πρόσβασης + + + + Enter the old and new passphrase to the wallet. + Εισάγετε τον παλιό και τον νεο κωδικο στο πορτοφολι. + + + + Confirm wallet encryption + Επιβεβαίωσε την κρυπτογραφηση του πορτοφολιού + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + Προσοχη: Εαν κρυπτογραφησεις το πορτοφολι σου και χάσεις τον κωδικο σου θα χάσεις <b> ΟΛΑ ΣΟΥ ΤΑ BITCOINS</b>! +Είσαι σίγουρος ότι θέλεις να κρυπτογραφησεις το πορτοφολι; + + + + + Wallet encrypted + Κρυπτογραφημενο πορτοφολι + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Το Bitcoin θα κλεισει τώρα για να τελειώσει την διαδικασία κρυπτογραφησης. Θυμησου ότι κρυπτογραφώντας το πορτοφολι σου δεν μπορείς να προστατέψεις πλήρως τα bitcoins σου από κλοπή στην περίπτωση όπου μολυνθεί ο υπολογιστής σου με κακόβουλο λογισμικο. + + + + + Warning: The Caps Lock key is on. + Προσοχη: το πλήκτρο Caps Lock είναι ενεργο. + + + + + + + Wallet encryption failed + Η κρυπτογραφηση του πορτοφολιού απέτυχε + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Η κρυπτογράφηση του πορτοφολιού απέτυχε λογω εσωτερικού σφάλματος. Το πορτοφολι δεν κρυπτογραφηθηκε. + + + + + The supplied passphrases do not match. + Οι εισαχθέντες κωδικοί δεν ταιριάζουν. + + + + Wallet unlock failed + το ξεκλείδωμα του πορτοφολιού απέτυχε + + + + + + The passphrase entered for the wallet decryption was incorrect. + Ο κωδικος που εισήχθη για την αποκρυπτογραφηση του πορτοφολιού ήταν λαθος. + + + + Wallet decryption failed + Η αποκρυπτογραφηση του πορτοφολιού απέτυχε + + + + Wallet passphrase was succesfully changed. + Ο κωδικος του πορτοφολιού άλλαξε με επιτυχία. + + + + BitcoinGUI + + + Bitcoin Wallet + Πορτοφολι Bitcoin + + + + Sign &message... + + + + + Show/Hide &Bitcoin + Εμφάνισε/Κρύψε &Bitcoin + + + + Synchronizing with network... + Συγχρονισμός με το δίκτυο... + + + + &Overview + &Επισκόπηση + + + + Show general overview of wallet + Εμφάνισε γενική εικονα του πορτοφολιού + + + + &Transactions + &Συναλλαγές + + + + Browse transaction history + Περιήγηση στο ιστορικο συνναλαγων + + + + &Address Book + &Βιβλίο Διευθύνσεων + + + + Edit the list of stored addresses and labels + Εξεργασια της λιστας των αποθηκευμενων διευθύνσεων και ετικετων + + + + &Receive coins + &Παραλαβή νομισματων + + + + Show the list of addresses for receiving payments + Εμφάνισε την λίστα των διευθύνσεων για την παραλαβή πληρωμων + + + + &Send coins + &Αποστολη νομισματων + + + + Prove you control an address + Απέδειξε ότι ελέγχεις μια διεύθυνση + + + + E&xit + Έ&ξοδος + + + + Quit application + Εξοδος από την εφαρμογή + + + + &About %1 + &Περί %1 + + + + Show information about Bitcoin + Εμφάνισε πληροφορίες σχετικά με το Bitcoin + + + + About &Qt + Σχετικά με &Qt + + + + Show information about Qt + Εμφάνισε πληροφορίες σχετικά με Qt + + + + &Options... + &Επιλογές... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + ~%n μπλοκ απέμεινε~%n μπλοκ απέμειναν + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Κατέβηκαν %1 από %2 μπλοκ του ιστορικού συναλλαγών (%3% ολοκληρώθηκαν) + + + + &Export... + &Εξαγωγή + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Εμφάνισε ή κρύψε το παράθυρο Bitcoin + + + + Export the data in the current tab to a file + Εξαγωγή δεδομένων καρτέλας σε αρχείο + + + + Encrypt or decrypt wallet + Κρυπτογράφηση ή αποκρυπτογράφηση πορτοφολιού + + + + Backup wallet to another location + Δημιουργία αντιγράφου ασφαλείας πορτοφολιού σε άλλη τοποθεσία + + + + Change the passphrase used for wallet encryption + Αλλαγή του κωδικού κρυπτογράφησης του πορτοφολιού + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Αρχείο + + + + &Settings + &Ρυθμίσεις + + + + &Help + &Βοήθεια + + + + Tabs toolbar + Εργαλειοθήκη καρτελών + + + + Actions toolbar + Εργαλειοθήκη ενεργειών + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Πελάτης Bitcoin + + + + %n active connection(s) to Bitcoin network + %n ενεργή σύνδεση στο δίκτυο Bitcoin%n ενεργές συνδέσεις στο δίκτυο Βitcoin + + + + Downloaded %1 blocks of transaction history. + Έγινε λήψη %1 μπλοκ ιστορικού συναλλαγών + + + + %n second(s) ago + %n δευτερόλεπτο πριν%n δευτερόλεπτα πριν + + + + %n minute(s) ago + %n λεπτό πριν%n λεπτά πριν + + + + %n hour(s) ago + %n ώρα πριν%n ώρες πριν + + + + %n day(s) ago + %n ημέρα πριν%n ημέρες πριν + + + + Up to date + Ενημερωμένο + + + + Catching up... + Ενημέρωση... + + + + Last received block was generated %1. + Το τελευταίο μπλοκ που ελήφθη %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Η συναλλαγή ξεπερνάει το όριο. +Μπορεί να ολοκληρωθεί με μια αμοιβή των %1, η οποία αποδίδεται στους κόμβους που επεξεργάζονται τις συναλλαγές και βοηθούν στην υποστήριξη του δικτύου. +Θέλετε να συνεχίσετε; + + + + Confirm transaction fee + + + + + Sent transaction + Η συναλλαγή απεστάλη + + + + Incoming transaction + Εισερχόμενη συναλλαγή + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Ημερομηνία: %1 +Ποσό: %2 +Τύπος: %3 +Διεύθυνση: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Το πορτοφόλι είναι <b>κρυπτογραφημένο</b> και <b>ξεκλείδωτο</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Το πορτοφόλι είναι <b>κρυπτογραφημένο</b> και <b>κλειδωμένο</b> + + + + Backup Wallet + Αντίγραφο ασφαλείας του πορτοφολιού + + + + Wallet Data (*.dat) + Αρχεία δεδομένων πορτοφολιού (*.dat) + + + + Backup Failed + Αποτυχία κατά τη δημιουργία αντιγράφου + + + + There was an error trying to save the wallet data to the new location. + Παρουσιάστηκε σφάλμα κατά την αποθήκευση των δεδομένων πορτοφολιού στη νέα τοποθεσία. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Απεικόνισης + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Επιλέξτε τη μονάδα υποδιαίρεσης που θα εμφανίζεται + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Επεξεργασία Διεύθυνσης + + + + &Label + &Επιγραφή + + + + The label associated with this address book entry + Η επιγραφή που σχετίζεται με αυτή την καταχώρηση του βιβλίου διευθύνσεων + + + + &Address + &Διεύθυνση + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Η διεύθυνση που σχετίζεται με αυτή την καταχώρηση του βιβλίου διευθύνσεων. Μπορεί να τροποποιηθεί μόνο για τις διευθύνσεις αποστολής. + + + + New receiving address + Νέα διεύθυνση λήψης + + + + New sending address + Νέα διεύθυνση αποστολής + + + + Edit receiving address + Επεξεργασία διεύθυνσης λήψης + + + + Edit sending address + Επεξεργασία διεύθυνσης αποστολής + + + + The entered address "%1" is already in the address book. + Η διεύθυνση "%1" βρίσκεται ήδη στο βιβλίο διευθύνσεων. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Δεν είναι δυνατό το ξεκλείδωμα του πορτοφολιού. + + + + New key generation failed. + Η δημιουργία νέου κλειδιού απέτυχε. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Χρήση: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + Όρισε γλώσσα, για παράδειγμα "de_DE"(προεπιλογή:τοπικές ρυθμίσεις) + + + + Start minimized + Έναρξη ελαχιστοποιημένο + + + + Show splash screen on startup (default: 1) + Εμφάνισε την οθόνη εκκίνησης κατά την εκκίνηση(προεπιλογή:1) + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Αμοιβή &συναλλαγής + + + + Main + Βασικές + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Η προαιρετική αμοιβή για κάθε kB επισπεύδει την επεξεργασία των συναλλαγών σας. Οι περισσότερες συναλλαγές είναι 1 kB. Προτείνεται αμοιβή 0.01. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Μπορείτε να υπογράφετε μηνύματα με τις διευθύνσεις σας, ώστε ν' αποδεικνύετε πως αυτές σας ανήκουν. Αποφεύγετε να υπογράφετε κάτι αόριστο καθώς ενδέχεται να εξαπατηθείτε. Υπογράφετε μόνο πλήρης δηλώσεις με τις οποίες συμφωνείτε. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Η διεύθυνση που θα υπογραφεί μαζί με το μήνυμα (π.χ. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Αντιγραφή διεύθυνσης από το βιβλίο διευθύνσεων + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Επικόλληση διεύθυνσης από το βιβλίο διευθύνσεων + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Εισάγετε εδώ το μήνυμα που θέλετε να υπογράψετε + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Κάντε κλικ στο "Υπογραφή Μηνύματος" για να λάβετε την υπογραφή + + + + Sign a message to prove you own this address + Υπογράψτε ένα μήνυμα για να βεβαιώσετε πως είστε ο κάτοχος αυτής της διεύθυνσης + + + + &Sign Message + &Υπογραφή Μηνύματος + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Εισάγετε μια διεύθυνση Bitcoin (π.χ. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Σφάλμα υπογραφής + + + + %1 is not a valid address. + Η %1 δεν είναι έγκυρη διεύθυνση. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Το προσωπικό κλειδί της %1 δεν είναι διαθέσιμο. + + + + Sign failed + Αποτυχία υπογραφής + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Απόδοση θυρών με χρήστη &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Αυτόματο άνοιγμα των θυρών Bitcoin στον δρομολογητή. Λειτουργεί μόνο αν ο δρομολογητής σας υποστηρίζει τη λειτουργία UPnP. + + + + &Connect through SOCKS4 proxy: + &Σύνδεση μέσω SOCKS4 διαμεσολαβητή + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Σύνδεση στο Bitcoin δίκτυο μέσω διαμεσολαβητή SOCKS4 (π.χ. για σύνδεση μέσω Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + Διεύθυνση IP του διαμεσολαβητή (π.χ. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Η θύρα του διαμεσολαβητή (π.χ. 1234) + + + + OptionsDialog + + + Options + Ρυθμίσεις + + + + OverviewPage + + + Form + Φόρμα + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Υπόλοιπο + + + + Number of transactions: + Αριθμός συναλλαγών + + + + Unconfirmed: + Ανεπιβεβαίωτες + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Πρόσφατες συναλλαγές</b> + + + + Your current balance + Το τρέχον υπόλοιπο + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Το άθροισμα των συναλλαγών που δεν έχουν ακόμα επιβεβαιωθεί και δεν προσμετρώνται στο τρέχον υπόλοιπό σας + + + + Total number of transactions in wallet + Σύνολο συναλλαγών στο πορτοφόλι + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + Κώδικας QR + + + + Request Payment + Αίτηση πληρωμής + + + + Amount: + Ποσό: + + + + BTC + BTC + + + + Label: + Επιγραφή: + + + + Message: + Μήνυμα: + + + + &Save As... + &Αποθήκευση ως... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + Το αποτέλεσμα της διεύθυνσης είναι πολύ μεγάλο. Μειώστε το μέγεθος για το κείμενο της ετικέτας/ μηνύματος. + + + + Save QR Code + + + + + PNG Images (*.png) + Εικόνες PNG (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Αποστολή νομισμάτων + + + + Send to multiple recipients at once + Αποστολή σε πολλούς αποδέκτες ταυτόχρονα + + + + &Add Recipient + + + + + Remove all transaction fields + Διαγραφή όλων των πεδίων συναλλαγής + + + + Clear &All + + + + + Balance: + Υπόλοιπο: + + + + 123.456 BTC + 123,456 BTC + + + + Confirm the send action + Επιβεβαίωση αποστολής + + + + &Send + &Αποστολή + + + + <b>%1</b> to %2 (%3) + <b>%1</b> σε %2 (%3) + + + + Confirm send coins + Επιβεβαίωση αποστολής νομισμάτων + + + + Are you sure you want to send %1? + Είστε βέβαιοι για την αποστολή %1; + + + + and + και + + + + The recepient address is not valid, please recheck. + Η διεύθυνση του αποδέκτη δεν είναι σωστή. Παρακαλώ ελέγξτε ξανά. + + + + The amount to pay must be larger than 0. + Το ποσό πληρωμής πρέπει να είναι μεγαλύτερο από 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Φόρμα + + + + A&mount: + &Ποσό: + + + + Pay &To: + Πληρωμή &σε: + + + + + Enter a label for this address to add it to your address book + Εισάγετε μια επιγραφή για αυτή τη διεύθυνση ώστε να καταχωρηθεί στο βιβλίο διευθύνσεων + + + + &Label: + &Επιγραφή + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Η διεύθυνση γι' αποστολή πληρωμής +(π.χ. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Επιλογή διεύθυνσης από το βιβλίο διευθύνσεων + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Επικόλληση διεύθυνσης από το πρόχειρο + + + + Alt+P + Alt+P + + + + Remove this recipient + Αφαίρεση αποδέκτη + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Εισάγετε μια διεύθυνση Bitcoin (π.χ. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Ανοιχτό για %1 μπλοκ + + + + Open until %1 + Ανοιχτό μέχρι %1 + + + + %1/offline? + %1/χωρίς σύνδεση; + + + + %1/unconfirmed + %1/χωρίς επιβεβαίωση + + + + %1 confirmations + %1 επιβεβαιώσεις + + + + <b>Status:</b> + <b>Κατάσταση:</b> + + + + , has not been successfully broadcast yet + , δεν έχει ακόμα μεταδοθεί μ' επιτυχία + + + + , broadcast through %1 node + , έχει μεταδοθεί μέσω %1 κόμβου + + + + , broadcast through %1 nodes + , έχει μεταδοθεί μέσω %1 κόμβων + + + + <b>Date:</b> + <b>Ημερομηνία:</b> + + + + <b>Source:</b> Generated<br> + <b>Προέλευση:</b> Δημιουργία<br> + + + + + <b>From:</b> + <b>Από:</b> + + + + unknown + άγνωστο + + + + + + <b>To:</b> + <b>Προς:</b> + + + + (yours, label: + (δικές σας, επιγραφή: + + + + (yours) + (δικές σας) + + + + + + + <b>Credit:</b> + <b>Πίστωση:</b> + + + + (%1 matures in %2 more blocks) + (%1 ωρίμανση σε %2 επιπλέον μπλοκ) + + + + (not accepted) + (μη αποδεκτό) + + + + + + <b>Debit:</b> + <b>Χρέωση:</b> + + + + <b>Transaction fee:</b> + <b>Αμοιβή συναλλαγής:</b> + + + + <b>Net amount:</b> + <b>Καθαρό ποσό:</b> + + + + Message: + Μήνυμα: + + + + Comment: + Σχόλιο: + + + + Transaction ID: + ID Συναλλαγής: + + + + 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. + Πρέπει να περιμένετε 120 μπλοκ πριν μπορέσετε να χρησιμοποιήσετε τα νομίσματα που έχετε δημιουργήσει. Το μπλοκ που δημιουργήσατε μεταδόθηκε στο δίκτυο για να συμπεριληφθεί στην αλυσίδα των μπλοκ. Αν δεν μπει σε αυτή θα μετατραπεί σε "μη αποδεκτό" και δε θα μπορεί να καταναλωθεί. Αυτό συμβαίνει σπάνια όταν κάποιος άλλος κόμβος δημιουργήσει ένα μπλοκ λίγα δευτερόλεπτα πριν από εσάς. + + + + TransactionDescDialog + + + Transaction details + Λεπτομέρειες συναλλαγής + + + + This pane shows a detailed description of the transaction + Αυτό το παράθυρο δείχνει μια λεπτομερή περιγραφή της συναλλαγής + + + + TransactionTableModel + + + Date + Ημερομηνία + + + + Type + Τύπος + + + + Address + Διεύθυνση + + + + Amount + Ποσό + + + + Open for %n block(s) + Ανοιχτό για %n μπλοκΑνοιχτό για %n μπλοκ + + + + Open until %1 + Ανοιχτό μέχρι %1 + + + + Offline (%1 confirmations) + Χωρίς σύνδεση (%1 επικυρώσεις) + + + + Unconfirmed (%1 of %2 confirmations) + Χωρίς επιβεβαίωση (%1 από %2 επικυρώσεις) + + + + Confirmed (%1 confirmations) + Επικυρωμένη (%1 επικυρώσεις) + + + + Mined balance will be available in %n more blocks + Το υπόλοιπο από την εξόρυξη θα είναι διαθέσιμο μετά από %n μπλοκΤο υπόλοιπο από την εξόρυξη θα είναι διαθέσιμο μετά από %n μπλοκ + + + + This block was not received by any other nodes and will probably not be accepted! + Αυτό το μπλοκ δεν έχει παραληφθεί από κανέναν άλλο κόμβο και κατά πάσα πιθανότητα θα απορριφθεί! + + + + Generated but not accepted + Δημιουργήθηκε αλλά απορρίφθηκε + + + + Received with + Παραλαβή με + + + + Received from + Ελήφθη από + + + + Sent to + Αποστολή προς + + + + Payment to yourself + Πληρωμή προς εσάς + + + + Mined + Εξόρυξη + + + + (n/a) + (δ/α) + + + + Transaction status. Hover over this field to show number of confirmations. + Κατάσταση συναλλαγής. Πηγαίνετε το ποντίκι πάνω από αυτό το πεδίο για να δείτε τον αριθμό των επικυρώσεων + + + + Date and time that the transaction was received. + Ημερομηνία κι ώρα λήψης της συναλλαγής. + + + + Type of transaction. + Είδος συναλλαγής. + + + + Destination address of transaction. + Διεύθυνση αποστολής της συναλλαγής. + + + + Amount removed from or added to balance. + Ποσό που αφαιρέθηκε ή προστέθηκε στο υπόλοιπο. + + + + TransactionView + + + + All + Όλα + + + + Today + Σήμερα + + + + This week + Αυτή την εβδομάδα + + + + This month + Αυτόν τον μήνα + + + + Last month + Τον προηγούμενο μήνα + + + + This year + Αυτό το έτος + + + + Range... + Έκταση... + + + + Received with + Ελήφθη με + + + + Sent to + Απεστάλη προς + + + + To yourself + Προς εσάς + + + + Mined + Εξόρυξη + + + + Other + Άλλο + + + + Enter address or label to search + Αναζήτηση με βάση τη διεύθυνση ή την επιγραφή + + + + Min amount + Ελάχιστο ποσό + + + + Copy address + Αντιγραφή διεύθυνσης + + + + Copy label + Αντιγραφή επιγραφής + + + + Copy amount + Αντιγραφή ποσού + + + + Edit label + Επεξεργασία επιγραφής + + + + Show transaction details + + + + + Export Transaction Data + Εξαγωγή Στοιχείων Συναλλαγών + + + + Comma separated file (*.csv) + Αρχείο οριοθετημένο με κόμματα (*.csv) + + + + Confirmed + Επικυρωμένες + + + + Date + Ημερομηνία + + + + Type + Τύπος + + + + Label + Επιγραφή + + + + Address + Διεύθυνση + + + + Amount + Ποσό + + + + ID + ID + + + + Error exporting + Σφάλμα εξαγωγής + + + + Could not write to file %1. + Αδυναμία εγγραφής στο αρχείο %1. + + + + Range: + Έκταση: + + + + to + έως + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Αντιγραφή της επιλεγμένης διεύθυνσης στο πρόχειρο + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Αποστολή... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Ελαχιστοποίηση στην περιοχή ειδοποιήσεων αντί της γραμμής εργασιών + + + + Show only a tray icon after minimizing the window + Εμφάνιση εικονιδίου στην περιοχή ειδοποιήσεων μόνο κατά την ελαχιστοποίηση + + + + M&inimize on close + + + + + 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. + Ελαχιστοποίηση αντί για έξοδο κατά το κλείσιμο του παραθύρου + + + + bitcoin-core + + + Bitcoin version + Έκδοση Bitcoin + + + + Usage: + Χρήση: + + + + Send command to -server or bitcoind + Αποστολή εντολής στον εξυπηρετητή ή στο bitcoind + + + + List commands + Λίστα εντολών + + + + Get help for a command + Επεξήγηση εντολής + + + + Options: + Επιλογές: + + + + Specify configuration file (default: bitcoin.conf) + Ορίστε αρχείο ρυθμίσεων (προεπιλογή: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Ορίστε αρχείο pid (προεπιλογή: bitcoind.pid) + + + + Generate coins + Δημιουργία νομισμάτων + + + + Don't generate coins + Άρνηση δημιουργίας νομισμάτων + + + + Specify data directory + Ορισμός φακέλου δεδομένων + + + + Set database cache size in megabytes (default: 25) + Όρισε το μέγεθος της βάσης προσωρινής αποθήκευσης σε megabytes(προεπιλογή:25) + + + + Set database disk log size in megabytes (default: 100) + Όρισε το μέγεθος της βάσης ιστορικού σε megabytes (προεπιλογή:100) + + + + Specify connection timeout (in milliseconds) + Ορισμός λήξης χρονικού ορίου (σε χιλιοστά του δευτερολέπτου) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Εισερχόμενες συνδέσεις στη θύρα <port> (προεπιλογή: 8333 ή στο testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Μέγιστες αριθμός συνδέσεων με τους peers <n> (προεπιλογή: 125) + + + + Connect only to the specified node + Σύνδεση μόνο με ορισμένο κόμβο + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Όριο αποσύνδεσης προβληματικών peers (προεπιλογή: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Δευτερόλεπτα πριν επιτραπεί ξανά η σύνδεση των προβληματικών peers (προεπιλογή: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Μέγιστος buffer λήψης ανά σύνδεση, <n>*1000 bytes (προεπιλογή: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Μέγιστος buffer αποστολής ανά σύνδεση, <n>*1000 bytes (προεπιλογή: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Αποδοχή εντολών κονσόλας και JSON-RPC + + + + Run in the background as a daemon and accept commands + Εκτέλεση στο παρασκήνιο κι αποδοχή εντολών + + + + Use the test network + Χρήση του δοκιμαστικού δικτύου + + + + Output extra debugging information + Έξοδος επιπλέον πληροφοριών εντοπισμού σφαλμάτων + + + + Prepend debug output with timestamp + Χρονοσφραγίδα πληροφοριών εντοπισμού σφαλμάτων + + + + Send trace/debug info to console instead of debug.log file + Αποστολή πληροφοριών εντοπισμού σφαλμάτων στην κονσόλα αντί του αρχείου debug.log + + + + Send trace/debug info to debugger + Αποστολή πληροφοριών εντοπισμού σφαλμάτων στον debugger + + + + Username for JSON-RPC connections + Όνομα χρήστη για τις συνδέσεις JSON-RPC + + + + Password for JSON-RPC connections + Κωδικός για τις συνδέσεις JSON-RPC + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Εισερχόμενες συνδέσεις JSON-RPC στη θύρα <port> (προεπιλογή: 8332) + + + + Allow JSON-RPC connections from specified IP address + Αποδοχή συνδέσεων JSON-RPC από συγκεκριμένη διεύθυνση IP + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Αποστολή εντολών στον κόμβο <ip> (προεπιλογή: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Εκτέλεσε την εντολή όταν το καλύτερο μπλοκ αλλάξει(%s στην εντολή αντικαθίσταται από το hash του μπλοκ) + + + + Upgrade wallet to latest format + Αναβάθμισε το πορτοφόλι στην τελευταία έκδοση + + + + Set key pool size to <n> (default: 100) + Όριο πλήθους κλειδιών pool <n> (προεπιλογή: 100) + + + + Rescan the block chain for missing wallet transactions + Επανέλεγχος της αλυσίδας μπλοκ για απούσες συναλλαγές + + + + How many blocks to check at startup (default: 2500, 0 = all) + Πόσα μπλοκ να ελέγχω κατά την εκκίνηση (προεπιλογή:2500,0=όλα) + + + + How thorough the block verification is (0-6, default: 1) + Πόσο εξονυχιστική να είναι η επιβεβαίωση του μπλοκ(0-6, προεπιλογή:1) + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +Ρυθμίσεις SSL: (ανατρέξτε στο Bitcoin Wiki για οδηγίες ρυθμίσεων SSL) + + + + Use OpenSSL (https) for JSON-RPC connections + Χρήση του OpenSSL (https) για συνδέσεις JSON-RPC + + + + Server certificate file (default: server.cert) + Αρχείο πιστοποιητικού του διακομιστή (προεπιλογή: server.cert) + + + + Server private key (default: server.pem) + Προσωπικό κλειδί του διακομιστή (προεπιλογή: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Αποδεκτά κρυπτογραφήματα (προεπιλογή: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + Αυτό το κείμενο βοήθειας + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Αδυναμία κλειδώματος του φακέλου δεδομένων %s. Πιθανώς το Bitcoin να είναι ήδη ενεργό. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Φόρτωση διευθύνσεων... + + + + Error loading blkindex.dat + Σφάλμα φόρτωσης blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Σφάλμα φόρτωσης wallet.dat: Κατεστραμμένο Πορτοφόλι + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Σφάλμα φόρτωσης wallet.dat: Το Πορτοφόλι απαιτεί μια νεότερη έκδοση του Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Απαιτείται η επανεγγραφή του Πορτοφολιού, η οποία θα ολοκληρωθεί στην επανεκκίνηση του Bitcoin + + + + Error loading wallet.dat + Σφάλμα φόρτωσης αρχείου wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + Σφάλμα: το πορτοφόλι είναι κλειδωμένο, δεν μπορεί να δημιουργηθεί συναλλαγή + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Σφάλμα: Αυτή η συναλλαγή απαιτεί αμοιβή συναλλαγής τουλάχιστον %s λόγω του μεγέθους, πολυπλοκότητας ή της χρήσης πρόσφατης παραλαβής κεφαλαίου + + + + Error: Transaction creation failed + Σφάλμα: Η δημιουργία της συναλλαγής απέτυχε + + + + Sending... + Αποστολή... + + + + 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. + Σφάλμα: Η συναλλαγή απορρίφθηκε. +Αυτό ίσως οφείλεται στο ότι τα νομίσματά σας έχουν ήδη ξοδευτεί, π.χ. με την αντιγραφή του wallet.dat σε άλλο σύστημα και την χρήση τους εκεί, χωρίς η συναλλαγή να έχει καταγραφεί στο παρόν σύστημα. + + + + Invalid amount + Λάθος ποσότητα + + + + Insufficient funds + Ανεπαρκές κεφάλαιο + + + + Loading block index... + Φόρτωση ευρετηρίου μπλοκ... + + + + Add a node to connect to and attempt to keep the connection open + Προσέθεσε ένα κόμβο για σύνδεση και προσπάθησε να κρατήσεις την σύνδεση ανοιχτή + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + Βρες ομότιμους υπολογιστές χρησιμοποιώντας internet relay chat(Προεπιλογή:0) + + + + Accept connections from outside (default: 1) + Να δέχεσαι συνδέσεις από έξω(προεπιλογή:1) + + + + Find peers using DNS lookup (default: 1) + Βρες ομότιμους υπολογιστές χρησιμοποιώντας αναζήτηση DNS(προεπιλογή:1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Χρησιμοποίησε Universal Plug and Play για την χρήση της πόρτας αναμονής (προεπιλογή:1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Χρησιμοποίησε Universal Plug and Play για την χρήση της πόρτας αναμονής (προεπιλογή:0) + + + + Fee per KB to add to transactions you send + Αμοιβή ανά KB που θα προστίθεται στις συναλλαγές που στέλνεις + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Φόρτωση πορτοφολιού... + + + + Cannot downgrade wallet + Δεν μπορώ να υποβαθμίσω το πορτοφόλι + + + + Cannot initialize keypool + Δεν μπορώ αν αρχικοποιήσω την λίστα κλειδιών + + + + Cannot write default address + Δεν μπορώ να γράψω την προεπιλεγμένη διεύθυνση + + + + Rescanning... + Ανίχνευση... + + + + Done loading + Η φόρτωση ολοκληρώθηκε + + + + To use the %s option + Χρήση της %s επιλογής + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, πρέπει να βάλεις ένα κωδικό στο αρχείο παραμέτρων: %s +Προτείνεται να χρησιμοποιήσεις τον παρακάτω τυχαίο κωδικό: +rpcuser=bitcoinrpc +rpcpassword=%s +(δεν χρειάζεται να θυμάσαι αυτόν τον κωδικό) +Εάν το αρχείο δεν υπάρχει, δημιούργησε το με δικαιώματα μόνο για ανάγνωση από τον δημιουργό. + + + + Error + Σφάλμα + + + + An error occured while setting up the RPC port %i for listening: %s + Ένα σφάλμα συνέβη καθώς προετοιμαζόταν η πόρτα RPC %i για αναμονή:%s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Πρέπει να βάλεις ένα κωδικό στο αρχείο παραμέτρων: %s +Εάν το αρχείο δεν υπάρχει, δημιούργησε το με δικαιώματα μόνο για ανάγνωση από τον δημιουργό + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Προειδοποίηση: Παρακαλώ βεβαιωθείτε πως η ημερομηνία κι ώρα του συστήματός σας είναι σωστές. Αν το ρολόι του υπολογιστή σας πάει λάθος, ενδέχεται να μη λειτουργεί σωστά το Bitcoin. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts new file mode 100644 index 0000000..bb806b8 --- /dev/null +++ b/src/qt/locale/bitcoin_en.ts @@ -0,0 +1,2086 @@ + + + +UTF-8 + + AboutDialog + + About Bitcoin + + + + <b>Bitcoin</b> version + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + Address Book + + + + Double-click to edit address or label + + + + Create a new address + + + + Copy the currently selected address to the system clipboard + + + + &New Address + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + + + + &Copy Address + + + + Show &QR Code + + + + Sign a message to prove you own a Bitcoin address + + + + &Sign Message + + + + Verify a message to ensure it was signed with a specified Bitcoin address + + + + &Verify Message + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + + + + &Delete + + + + Copy &Label + + + + &Edit + + + + Export Address Book Data + + + + Comma separated file (*.csv) + + + + Error exporting + + + + Could not write to file %1. + + + + + AddressTableModel + + Label + + + + Address + + + + (no label) + + + + + AskPassphraseDialog + + Passphrase Dialog + + + + Enter passphrase + + + + New passphrase + + + + Repeat new passphrase + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + + + + Encrypt wallet + + + + This operation needs your wallet passphrase to unlock the wallet. + + + + Unlock wallet + + + + This operation needs your wallet passphrase to decrypt the wallet. + + + + Decrypt wallet + + + + Change passphrase + + + + Enter the old and new passphrase to the wallet. + + + + Confirm wallet encryption + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + + + + Wallet encrypted + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + Warning: The Caps Lock key is on. + + + + Wallet encryption failed + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + + The supplied passphrases do not match. + + + + Wallet unlock failed + + + + The passphrase entered for the wallet decryption was incorrect. + + + + Wallet decryption failed + + + + Wallet passphrase was successfully changed. + + + + + BitcoinGUI + + Bitcoin Wallet + + + + Sign &message... + + + + Show/Hide &Bitcoin + + + + Synchronizing with network... + + + + &Overview + + + + Show general overview of wallet + + + + &Transactions + + + + Browse transaction history + + + + &Address Book + + + + Edit the list of stored addresses and labels + + + + &Receive coins + + + + Show the list of addresses for receiving payments + + + + &Send coins + + + + E&xit + + + + Quit application + + + + &About %1 + + + + Show information about Bitcoin + + + + About &Qt + + + + Show information about Qt + + + + &Options... + + + + &Encrypt Wallet... + + + + &Backup Wallet... + + + + &Change Passphrase... + + + + ~%n block(s) remaining + + ~%n block remaining + ~%n blocks remaining + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + &Export... + + + + Send coins to a Bitcoin address + + + + Sign a message to prove you own a Bitcoin address + + + + Verify a message to ensure it was signed with a specified Bitcoin address + + + + S&ignatures + + + + Modify configuration options for Bitcoin + + + + Show or hide the Bitcoin window + + + + Export the data in the current tab to a file + + + + Encrypt or decrypt wallet + + + + Backup wallet to another location + + + + Change the passphrase used for wallet encryption + + + + &Debug window + + + + Open debugging and diagnostic console + + + + &Verify message... + + + + &File + + + + &Settings + + + + &Help + + + + Tabs toolbar + + + + Actions toolbar + + + + [testnet] + + + + Bitcoin client + + + + %n active connection(s) to Bitcoin network + + %n active connection to Bitcoin network + %n active connections to Bitcoin network + + + + Downloaded %1 blocks of transaction history. + + + + %n second(s) ago + + %n second ago + %n seconds ago + + + + %n minute(s) ago + + %n minute ago + %n minutes ago + + + + %n hour(s) ago + + %n hour ago + %n hours ago + + + + %n day(s) ago + + %n day ago + %n days ago + + + + Up to date + + + + Catching up... + + + + Last received block was generated %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + + + + Confirm transaction fee + + + + Sent transaction + + + + Incoming transaction + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + URI handling + + + + URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + + + + Backup Wallet + + + + Wallet Data (*.dat) + + + + Backup Failed + + + + There was an error trying to save the wallet data to the new location. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + Network Alert + + + + + EditAddressDialog + + Edit Address + + + + &Label + + + + The label associated with this address book entry + + + + &Address + + + + The address associated with this address book entry. This can only be modified for sending addresses. + + + + New receiving address + + + + New sending address + + + + Edit receiving address + + + + Edit sending address + + + + The entered address "%1" is already in the address book. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + Could not unlock wallet. + + + + New key generation failed. + + + + + GUIUtil::HelpMessageBox + + Bitcoin-Qt + + + + version + + + + Usage: + + + + command-line options + + + + UI options + + + + Set language, for example "de_DE" (default: system locale) + + + + Start minimized + + + + Show splash screen on startup (default: 1) + + + + + OptionsDialog + + Options + + + + &Main + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + Pay transaction &fee + + + + Automatically start Bitcoin after logging in to the system. + + + + &Start Bitcoin on system login + + + + 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. + + + + &Detach databases at shutdown + + + + &Network + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + + Map port using &UPnP + + + + Connect to the Bitcoin network through a SOCKS proxy (e.g. when connecting through Tor). + + + + &Connect through SOCKS proxy: + + + + Proxy &IP: + + + + IP address of the proxy (e.g. 127.0.0.1) + + + + &Port: + + + + Port of the proxy (e.g. 9050) + + + + SOCKS &Version: + + + + SOCKS version of the proxy (e.g. 5) + + + + &Window + + + + Show only a tray icon after minimizing the window. + + + + &Minimize to the tray instead of the taskbar + + + + 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. + + + + M&inimize on close + + + + &Display + + + + User Interface &language: + + + + The user interface language can be set here. This setting will take effect after restarting Bitcoin. + + + + &Unit to show amounts in: + + + + Choose the default subdivision unit to show in the interface and when sending coins. + + + + Whether to show Bitcoin addresses in the transaction list or not. + + + + &Display addresses in transaction list + + + + &OK + + + + &Cancel + + + + &Apply + + + + default + + + + Warning + + + + This setting will take effect after restarting Bitcoin. + + + + The supplied proxy address is invalid. + + + + + OverviewPage + + Form + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + Balance: + + + + Number of transactions: + + + + Unconfirmed: + + + + Wallet + + + + Immature: + + + + Mined balance that has not yet matured + + + + <b>Recent transactions</b> + + + + Your current balance + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + + Total number of transactions in wallet + + + + out of sync + + + + + QRCodeDialog + + QR Code Dialog + + + + Request Payment + + + + Amount: + + + + Label: + + + + Message: + + + + &Save As... + + + + Error encoding URI into QR Code. + + + + The entered amount is invalid, please check. + + + + Resulting URI too long, try to reduce the text for label / message. + + + + Save QR Code + + + + PNG Images (*.png) + + + + + RPCConsole + + Bitcoin debug window + + + + Client name + + + + N/A + + + + Client version + + + + &Information + + + + Client + + + + Using OpenSSL version + + + + Startup time + + + + Network + + + + Number of connections + + + + On testnet + + + + Block chain + + + + Current number of blocks + + + + Estimated total blocks + + + + Last block time + + + + Debug logfile + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + &Open + + + + Command-line options + + + + Show the Bitcoin-Qt help message to get a list with possible Bitcoin command-line options. + + + + &Show + + + + &Console + + + + Build date + + + + Clear console + + + + Welcome to the Bitcoin RPC console. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + Send Coins + + + + Send to multiple recipients at once + + + + &Add Recipient + + + + Remove all transaction fields + + + + Clear &All + + + + Balance: + + + + 123.456 BTC + + + + Confirm the send action + + + + &Send + + + + <b>%1</b> to %2 (%3) + + + + Confirm send coins + + + + Are you sure you want to send %1? + + + + and + + + + The recepient address is not valid, please recheck. + + + + The amount to pay must be larger than 0. + + + + The amount exceeds your balance. + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + Duplicate address found, can only send to each address once per send operation. + + + + Error: Transaction creation failed. + + + + 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. + + + + + SendCoinsEntry + + Form + + + + A&mount: + + + + Pay &To: + + + + Enter a label for this address to add it to your address book + + + + &Label: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + + + + Alt+A + + + + Paste address from clipboard + + + + Alt+P + + + + Remove this recipient + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + SignVerifyMessageDialog + + Messaging - Sign / Verify a Message + + + + &Sign Message + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose an address from the address book + + + + Alt+A + + + + Paste address from clipboard + + + + Alt+P + + + + Enter the message you want to sign here + + + + Copy the current signature to the system clipboard + + + + Sign the message to prove you own this Bitcoin address + + + + Reset all sign message fields + + + + Clear &All + + + + &Verify Message + + + + Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + + + + The address the message was signed with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Verify the message to ensure it was signed with the specified Bitcoin address + + + + Reset all verify message fields + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Click "Sign Message" to generate signature + + + + Enter Bitcoin signature + + + + The entered address is invalid. + + + + Please check the address and try again. + + + + The entered address does not refer to a key. + + + + Wallet unlock was canceled. + + + + Private key for the entered address is not available. + + + + Message signing failed. + + + + Message signed. + + + + The signature could not be decoded. + + + + Please check the signature and try again. + + + + The signature did not match the message digest. + + + + Message verification failed. + + + + Message verified. + + + + + TransactionDesc + + Open until %1 + + + + Open for %n block(s) + + Open for %n block + Open for %n blocks + + + + %1/offline + + + + %1/unconfirmed + + + + %1 confirmations + + + + Status + + + + , broadcast through %n node(s) + + , broadcast through %n node + , broadcast through %n nodes + + + + Date + + + + Source + + + + Generated + + + + From + + + + To + + + + own address + + + + label + + + + Credit + + + + matures in %n more block(s) + + matures in %n more block + matures in %n more blocks + + + + not accepted + + + + Debit + + + + Transaction fee + + + + Net amount + + + + Message + + + + Comment + + + + Transaction ID + + + + Generated coins must mature 8 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, its 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. + + + + Debug information + + + + Transaction + + + + Inputs + + + + Amount + + + + true + + + + false + + + + , has not been successfully broadcast yet + + + + unknown + + + + + TransactionDescDialog + + Transaction details + + + + This pane shows a detailed description of the transaction + + + + + TransactionTableModel + + Date + + + + Type + + + + Address + + + + Amount + + + + Open for %n block(s) + + Open for %n block + Open for %n blocks + + + + Open until %1 + + + + Offline (%1 confirmations) + + + + Unconfirmed (%1 of %2 confirmations) + + + + Confirmed (%1 confirmations) + + + + Mined balance will be available when it matures in %n more block(s) + + Mined balance will be available when it matures in %n more block + Mined balance will be available when it matures in %n more blocks + + + + This block was not received by any other nodes and will probably not be accepted! + + + + Generated but not accepted + + + + Received with + + + + Received from + + + + Sent to + + + + Payment to yourself + + + + Mined + + + + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + + + + Date and time that the transaction was received. + + + + Type of transaction. + + + + Destination address of transaction. + + + + Amount removed from or added to balance. + + + + + TransactionView + + All + + + + Today + + + + This week + + + + This month + + + + Last month + + + + This year + + + + Range... + + + + Received with + + + + Sent to + + + + To yourself + + + + Mined + + + + Other + + + + Enter address or label to search + + + + Min amount + + + + Copy address + + + + Copy label + + + + Copy amount + + + + Edit label + + + + Show transaction details + + + + Export Transaction Data + + + + Comma separated file (*.csv) + + + + Confirmed + + + + Date + + + + Type + + + + Label + + + + Address + + + + Amount + + + + ID + + + + Error exporting + + + + Could not write to file %1. + + + + Range: + + + + to + + + + + WalletModel + + Sending... + + + + + bitcoin-core + + Bitcoin version + + + + Usage: + + + + Send command to -server or bitcoind + + + + List commands + + + + Get help for a command + + + + Options: + + + + Specify configuration file (default: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + + + + Generate coins + + + + Don't generate coins + + + + Specify data directory + + + + Set database cache size in megabytes (default: 25) + + + + Set database disk log size in megabytes (default: 100) + + + + Specify connection timeout (in milliseconds) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + Specify your own public address + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + Accept command line and JSON-RPC commands + + + + Run in the background as a daemon and accept commands + + + + Use the test network + + + + Accept connections from outside (default: 1 if no -proxy or -connect) + + + + Connect only to the specified node(s) + + + + Discover own IP address (default: 1 when listening and no -externalip) + + + + Failed to listen on any port. Use -listen=0 if you want this. + + + + Find peers using DNS lookup (default: 1 unless -connect) + + + + Invalid -tor address: '%s' + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 1000) + + + + Only connect to nodes in network <net> (IPv4, IPv6 or Tor) + + + + Output extra debugging information. Implies all other -debug* options + + + + Output extra network debugging information + + + + Prepend debug output with timestamp + + + + Select the version of socks proxy to use (4-5, default: 5) + + + + Send trace/debug info to console instead of debug.log file + + + + Send trace/debug info to debugger + + + + Use UPnP to map the listening port (default: 0) + + + + Use UPnP to map the listening port (default: 1 when listening) + + + + Use proxy to reach tor hidden services (default: same as -proxy) + + + + Username for JSON-RPC connections + + + + Warning: this version is obsolete, upgrade required + + + + Password for JSON-RPC connections + + + + Listen for JSON-RPC connections on <port> (default: 8332) + + + + Allow JSON-RPC connections from specified IP address + + + + Send commands to node running on <ip> (default: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + Upgrade wallet to latest format + + + + Set key pool size to <n> (default: 100) + + + + Rescan the block chain for missing wallet transactions + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + How thorough the block verification is (0-6, default: 1) + + + + Imports blocks from external blk000?.dat file + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + Use OpenSSL (https) for JSON-RPC connections + + + + Server certificate file (default: server.cert) + + + + Server private key (default: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + This help message + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + Connect through socks proxy + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + Loading addresses... + + + + Error loading blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + Error loading wallet.dat + + + + Invalid -proxy address: '%s' + + + + Unknown network specified in -onlynet: '%s' + + + + Unknown -socks proxy version requested: %i + + + + Cannot resolve -bind address: '%s' + + + + Cannot resolve -externalip address: '%s' + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + Error: could not start node + + + + Error: Wallet locked, unable to create transaction + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + Error: Transaction creation failed + + + + Sending... + + + + 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. + + + + Invalid amount + + + + Insufficient funds + + + + Loading block index... + + + + Add a node to connect to and attempt to keep the connection open + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + Find peers using internet relay chat (default: 0) + + + + Fee per KB to add to transactions you send + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + Loading wallet... + + + + Cannot downgrade wallet + + + + Cannot initialize keypool + + + + Cannot write default address + + + + Rescanning... + + + + Done loading + + + + To use the %s option + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Error + + + + An error occured while setting up the RPC port %i for listening: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + + diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts new file mode 100644 index 0000000..2636d19 --- /dev/null +++ b/src/qt/locale/bitcoin_es.ts @@ -0,0 +1,2540 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Acerca de Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> versión + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Desarrolladores de Bitcoin ⏎ +⏎ +Este software es experimental. ⏎ +⏎ +Se distribuye bajo la licencia de software MIT/X11, consulte el archivo adjunto o license.txt http://www.opensource.org/licenses/mit-license.php. ⏎ +⏎ +Este producto incluye software desarrollado por el OpenSSL Project para su uso en el OpenSSL Toolkit (http://www.openssl.org/~~V) y software de criptografía escrito por Eric Young (eay@cryptsoft.com) y el software UPnP escrito por Thomas Bernard. + + + + AddressBookPage + + + Address Book + Libreta de direcciones + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Éstas son sus direcciones Bitcoin para recibir pagos. Puede usar una diferente para cada persona emisora para saber quién le está pagando. + + + + Double-click to edit address or label + Haga doble clic para editar una dirección o etiqueta + + + + Create a new address + Crear una nueva dirección + + + + Copy the currently selected address to the system clipboard + Copiar la dirección seleccionada al portapapeles + + + + &New Address + &Añadir dirección + + + + &Copy Address + &Copiar dirección + + + + Show &QR Code + Mostrar código &QR + + + + Sign a message to prove you own this address + Firmar un mensaje para demostrar que posee esta dirección + + + + &Sign Message + &Firmar mensaje + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Borrar de la lista la dirección seleccionada . Sólo se pueden borrar las direcciones de envío. + + + + &Delete + &Borrar + + + + Copy &Label + Copiar &etiqueta + + + + &Edit + &Editar + + + + Export Address Book Data + Exportar datos de la libreta de direcciones + + + + Comma separated file (*.csv) + Archivos de columnas separadas por coma (*.csv) + + + + Error exporting + Error al exportar + + + + Could not write to file %1. + No se pudo escribir en el archivo %1. + + + + AddressTableModel + + + Label + Etiqueta + + + + Address + Dirección + + + + (no label) + (sin etiqueta) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Contraseña actual + + + + New passphrase + Nueva contraseña + + + + Repeat new passphrase + Repita la nueva contraseña + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Introduzca la nueva contraseña del monedero.<br/>Por favor elija una con <b>10 o más caracteres aleatorios</b> u <b>ocho o más palabras</b>. + + + + Encrypt wallet + Cifrar el monedero + + + + This operation needs your wallet passphrase to unlock the wallet. + Para desbloquear el monedero esta operación necesita de su contraseña. + + + + Unlock wallet + Desbloquear monedero + + + + This operation needs your wallet passphrase to decrypt the wallet. + Para descifrar el monedero esta operación necesita de su contraseña. + + + + Decrypt wallet + Descifrar monedero + + + + Change passphrase + Cambiar contraseña + + + + Enter the old and new passphrase to the wallet. + Introduzca la contraseña anterior del monedero y la nueva. + + + + Confirm wallet encryption + Confirmar cifrado del monedero + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ATENCIÓN: ¡Si cifra el monedero y pierde la contraseña perderá <b>TODOS SUS BITCOINS</b>!" +¿Está seguro de querer cifrarlo? + + + + + Wallet encrypted + Monedero cifrado + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin cerrará al finalizar el proceso de cifrado. Recuerde que el cifrado de su monedero no puede proteger totalmente sus bitcoin de ser robados por el malware que infecte su sistema. + + + + + Warning: The Caps Lock key is on. + Aviso: el bloqueo de mayúsculas está activado. + + + + + + + Wallet encryption failed + Ha fallado el cifrado del monedero + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Ha fallado el cifrado del monedero debido a un error interno. El monedero no ha sido cifrado. + + + + + The supplied passphrases do not match. + Las contraseñas no coinciden. + + + + Wallet unlock failed + Ha fallado el desbloqueo del monedero + + + + + + The passphrase entered for the wallet decryption was incorrect. + La contraseña introducida para descifrar el monedero es incorrecta. + + + + Wallet decryption failed + Ha fallado el descifrado del monedero + + + + Wallet passphrase was succesfully changed. + La contraseña del monedero ha sido cambiada correctamente. + + + + BitcoinGUI + + + Bitcoin Wallet + Monedero Bitcoin + + + + Sign &message... + Firmar &mensaje... + + + + Show/Hide &Bitcoin + Mostrar/ocultar &Bitcoin + + + + Synchronizing with network... + Sincronizando con la red… + + + + &Overview + &Vista general + + + + Show general overview of wallet + Mostrar vista general del monedero + + + + &Transactions + &Transacciones + + + + Browse transaction history + Examinar el historial de transacciones + + + + &Address Book + &Libreta de direcciones + + + + Edit the list of stored addresses and labels + Editar la lista de las direcciones y etiquetas almacenadas + + + + &Receive coins + &Recibir monedas + + + + Show the list of addresses for receiving payments + Mostrar la lista de direcciones utilizadas para recibir pagos + + + + &Send coins + &Enviar monedas + + + + Prove you control an address + Demuestre que controla una dirección + + + + E&xit + &Salir + + + + Quit application + Salir de la aplicación + + + + &About %1 + &Acerca de %1 + + + + Show information about Bitcoin + Mostrar información acerca de Bitcoin + + + + About &Qt + Acerca de &Qt + + + + Show information about Qt + Mostrar información acerca de Qt + + + + &Options... + &Opciones... + + + + &Encrypt Wallet... + &Cifrar monedero… + + + + &Backup Wallet... + Copia de &respaldo del monedero... + + + + &Change Passphrase... + &Cambiar la contraseña… + + + + ~%n block(s) remaining + ~%n bloque restante~%n bloques restantes + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Descargado %1 de %2 bloques del historial de transacciones (%3% hecho). + + + + &Export... + &Exportar… + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Mostrar u ocultar la ventana Bitcoin + + + + Export the data in the current tab to a file + Exportar a un archivo los datos de esta pestaña + + + + Encrypt or decrypt wallet + Cifrar o descifrar el monedero + + + + Backup wallet to another location + Copia de seguridad del monedero en otra ubicación + + + + Change the passphrase used for wallet encryption + Cambiar la contraseña utilizada para el cifrado del monedero + + + + &Debug window + Ventana de &depuración + + + + Open debugging and diagnostic console + Abrir la consola de depuración y diagnóstico + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Archivo + + + + &Settings + &Configuración + + + + &Help + A&yuda + + + + Tabs toolbar + Barra de pestañas + + + + Actions toolbar + Barra de acciones + + + + + [testnet] + [testnet] + + + + + Bitcoin client + cliente Bitcoin + + + + %n active connection(s) to Bitcoin network + %n conexión activa hacia la red Bitcoin%n conexiones activas hacia la red Bitcoin + + + + Downloaded %1 blocks of transaction history. + Se han bajado %1 bloques de historial. + + + + %n second(s) ago + hace %n segundohace %n segundos + + + + %n minute(s) ago + hace %n minutohace %n minutos + + + + %n hour(s) ago + hace %n horahace %n horas + + + + %n day(s) ago + hace %n díahace %n días + + + + Up to date + Actualizado + + + + Catching up... + Recuperando... + + + + Last received block was generated %1. + El último bloque recibido fue generado %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Esta transacción supera el límite. Puede seguir enviándola incluyendo una comisión de %1 que se va a repartir entre los nodos que procesan su transacción y ayudan a mantener la red. ¿Desea pagar esa tarifa? + + + + Confirm transaction fee + Confirme la tarifa de la transacción + + + + Sent transaction + Transacción enviada + + + + Incoming transaction + Transacción entrante + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Fecha: %1 +Cantidad: %2 +Tipo: %3 +Dirección: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + El monedero está <b>cifrado</b> y actualmente <b>desbloqueado</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + El monedero está <b>cifrado</b> y actualmente <b>bloqueado</b> + + + + Backup Wallet + Copia de seguridad del monedero + + + + Wallet Data (*.dat) + Datos del monedero (*.dat) + + + + Backup Failed + La copia de seguridad ha fallado + + + + There was an error trying to save the wallet data to the new location. + Ha habido un error al intentar guardar los datos del monedero a la nueva ubicación. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + Ha ocurrido un error fatal. Bitcoin no puede continuar con seguridad y se cerrará. + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Mostrado + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Elige la subdivisión por defecto para mostrar cantidaded en la interfaz cuando se envien monedas + + + + &Display addresses in transaction list + &Mostrar las direcciones en la lista de transsaciones + + + + Whether to show Bitcoin addresses in the transaction list + Mostrar las direcciones bitcoin en la lista de transacciones + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Editar Dirección + + + + &Label + &Etiqueta + + + + The label associated with this address book entry + La etiqueta asociada con esta entrada en la libreta + + + + &Address + &Dirección + + + + The address associated with this address book entry. This can only be modified for sending addresses. + La dirección asociada con esta entrada en la guia. Solo puede ser modificada para direcciones de envío. + + + + New receiving address + Nueva dirección para recibir + + + + New sending address + Nueva dirección para enviar + + + + Edit receiving address + Editar dirección de recepción + + + + Edit sending address + Editar dirección de envio + + + + The entered address "%1" is already in the address book. + La dirección introducida "%1" ya está presente en la libreta de direcciones. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + No se pudo desbloquear el monedero. + + + + New key generation failed. + Ha fallado la generación de la nueva clave. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Uso: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + Establecer el idioma, por ejemplo, "es_ES" (por defecto: configuración regional del sistema) + + + + Start minimized + Arrancar minimizado + + + + Show splash screen on startup (default: 1) + Mostrar pantalla de bienvenida en el inicio (por defecto: 1) + + + + MainOptionsPage + + + 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. + Desconectar las bases de datos de bloques y direcciones al cerrar la aplicación. Implica que pueden moverse a otros directorios de datos pero ralentiza el cierre. El monedero siempre queda desconectado. + + + + Pay transaction &fee + Comisión de &transacciones + + + + Main + Principal + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Tarifa de transacción por KB opcional que ayuda a asegurarse de que sus transacciones se procesan rápidamente. La mayoría de las transacciones son de 1 KB. Tarifa de 0,01 recomendado. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Usted puede firmar los mensajes con sus direcciones para demostrar que las posee. Tenga cuidado de no firmar cualquier cosa vaga, ya que los ataques de phishing pueden tratar de engañarle firmando su identidad a través de ellos. Solo firme declaraciones totalmente detalladas con las que usted esté de acuerdo. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + La dirección para firmar el mensaje con (por ejemplo, 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Elige la dirección de la libreta + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Pega dirección desde portapapeles + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Introduzca el mensaje que desea firmar aquí + + + + Copy the current signature to the system clipboard + Copiar la firma actual al portapapeles del sistema + + + + &Copy Signature + &Copiar firma + + + + Reset all sign message fields + Limpiar todos los campos de mensaje de la firma + + + + Clear &All + Limpiar &todo + + + + Click "Sign Message" to get signature + Haga clic en "Firma Mensaje" para obtener la firma + + + + Sign a message to prove you own this address + Firmar un mensaje a demostrar que posee esta dirección + + + + &Sign Message + &Firme mensaje + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Introduce una dirección Bitcoin (ej. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Error en firmado + + + + %1 is not a valid address. + %1 no es una dirección válida. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + La clave privada de %1 no está disponible. + + + + Sign failed + Firma falló + + + + NetworkOptionsPage + + + Network + Red + + + + Map port using &UPnP + Mapea el puerto usando &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Intenta abrir el puerto adecuado en el router automáticamente. Esta opción solo funciona si el router soporta UPnP y está activado. + + + + &Connect through SOCKS4 proxy: + &Conecta atraves de un proxy SOCKS4: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Conecta a la red Bitcoin a través de un proxy SOCKS4 (ej. para conectar con la red Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + Dirección IP del proxy (ej. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Puerto del servidor proxy (ej. 1234) + + + + OptionsDialog + + + Options + Opciones + + + + OverviewPage + + + Form + Desde + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Balance: + + + + Number of transactions: + Número de movimientos: + + + + Unconfirmed: + No confirmado(s): + + + + Wallet + Monedero + + + + <b>Recent transactions</b> + <b>Movimientos recientes</b> + + + + Your current balance + Tu balance actual + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Total de las transacciones que faltan por confirmar y que no se cuentan para el total general + + + + Total number of transactions in wallet + Número total de movimientos en el monedero + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + Código QR + + + + Request Payment + Solicitud de pago + + + + Amount: + Cuantía: + + + + BTC + BTC + + + + Label: + Label: + + + + Message: + Mensaje: + + + + &Save As... + &Guardar Como ... + + + + Error encoding URI into QR Code. + Error al codificar la URI en el código QR. + + + + Resulting URI too long, try to reduce the text for label / message. + URI demasiado larga, trata de reducir el texto de la etiqueta / mensaje. + + + + Save QR Code + Guardar código QR + + + + PNG Images (*.png) + Imágenes PNG (*.png) + + + + RPCConsole + + + Bitcoin debug window + Ventana de depuración + + + + Client name + Nombre del cliente + + + + + + + + + + + + N/A + N/D + + + + Client version + Versión del cliente + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + Red + + + + Number of connections + Número de conexiones + + + + On testnet + En la red de pruebas + + + + Block chain + Cadena de bloques + + + + Current number of blocks + Número actual de bloques + + + + Estimated total blocks + Bloques totales estimados + + + + Last block time + Hora del último bloque + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + Fecha de compilación + + + + Clear console + Borrar consola + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Envía monedas + + + + Send to multiple recipients at once + Envía a multiples destinatarios de una vez + + + + &Add Recipient + &Añadir destinatario + + + + Remove all transaction fields + Eliminar todos los campos de las transacciones + + + + Clear &All + Limpiar &todo + + + + Balance: + Balance: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Confirma el envío + + + + &Send + &Envía + + + + <b>%1</b> to %2 (%3) + <b>%1</b> to %2 (%3) + + + + Confirm send coins + Confirmar el envío de monedas + + + + Are you sure you want to send %1? + Estas seguro que quieres enviar %1? + + + + and + y + + + + The recepient address is not valid, please recheck. + La dirección de destinatario no es válida, comprueba otra vez. + + + + The amount to pay must be larger than 0. + La cantidad por pagar tiene que ser mayor 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Envio + + + + A&mount: + Ca&ntidad: + + + + Pay &To: + &Pagar a: + + + + + Enter a label for this address to add it to your address book + Etiquete esta dirección para añadirla a la libreta + + + + &Label: + &Etiqueta: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + La dirección donde enviar el pago (ej. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Elija una dirección de la libreta de direcciones + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Pega dirección desde portapapeles + + + + Alt+P + Alt+P + + + + Remove this recipient + Elimina destinatario + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Introduce una dirección Bitcoin (ej. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Abierto hasta %1 bloques + + + + Open until %1 + Abierto hasta %1 + + + + %1/offline? + %1/fuera de linea? + + + + %1/unconfirmed + %1/no confirmado + + + + %1 confirmations + %1 confirmaciones + + + + <b>Status:</b> + <b>Estado:</b> + + + + , has not been successfully broadcast yet + , no ha sido emitido satisfactoriamente todavía + + + + , broadcast through %1 node + , emitido mediante %1 nodo + + + + , broadcast through %1 nodes + , emitido mediante %1 nodos + + + + <b>Date:</b> + <b>Fecha:</b> + + + + <b>Source:</b> Generated<br> + <b>Fuente:</b> Generado<br> + + + + + <b>From:</b> + <b>De:</b> + + + + unknown + desconocido + + + + + + <b>To:</b> + <b>Para:</b> + + + + (yours, label: + (tuya, etiqueta: + + + + (yours) + (tuya) + + + + + + + <b>Credit:</b> + <b>Crédito:</b> + + + + (%1 matures in %2 more blocks) + (%1 madura en %1 bloques más) + + + + (not accepted) + (no aceptada) + + + + + + <b>Debit:</b> + <b>Débito:</b> + + + + <b>Transaction fee:</b> + <b>Comisión de transacción:</b> + + + + <b>Net amount:</b> + <b>Cantidad total:</b> + + + + Message: + Mensaje: + + + + Comment: + Comentario: + + + + Transaction ID: + Id. de transacción: + + + + 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. + Las monedas generadas deben esperar 120 bloques antes de ser gastadas. Cuando has generado este bloque se emitió a la red para ser agregado en la cadena de bloques. Si falla al incluirse en la cadena, cambiará a "no aceptado" y las monedas no se podrán gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque casi al mismo tiempo que el tuyo. + + + + TransactionDescDialog + + + Transaction details + Detalles de transacción + + + + This pane shows a detailed description of the transaction + Esta ventana muestra información detallada sobre la transacción + + + + TransactionTableModel + + + Date + Fecha + + + + Type + Tipo + + + + Address + Dirección + + + + Amount + Cantidad + + + + Open for %n block(s) + Abierto por %n bloqueAbierto por %n bloques + + + + Open until %1 + Abierto hasta %1 + + + + Offline (%1 confirmations) + Fuera de linea (%1 confirmaciones) + + + + Unconfirmed (%1 of %2 confirmations) + No confirmado (%1 de %2 confirmaciones) + + + + Confirmed (%1 confirmations) + Confirmado (%1 confirmaciones) + + + + Mined balance will be available in %n more blocks + El balance minado estará disponible en %n bloque másEl balance minado estará disponible en %n bloques más + + + + This block was not received by any other nodes and will probably not be accepted! + Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado ! + + + + Generated but not accepted + Generado pero no aceptado + + + + Received with + Recibido con + + + + Received from + Recibidos de + + + + Sent to + Enviado a + + + + Payment to yourself + Pago propio + + + + Mined + Minado + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + Estado de transacción. Pasa el ratón sobre este campo para ver el número de confirmaciones. + + + + Date and time that the transaction was received. + Fecha y hora de cuando se recibió la transacción. + + + + Type of transaction. + Tipo de transacción. + + + + Destination address of transaction. + Dirección de destino de la transacción. + + + + Amount removed from or added to balance. + Cantidad retirada o añadida al balance. + + + + TransactionView + + + + All + Todo + + + + Today + Hoy + + + + This week + Esta semana + + + + This month + Este mes + + + + Last month + Mes pasado + + + + This year + Este año + + + + Range... + Rango... + + + + Received with + Recibido con + + + + Sent to + Enviado a + + + + To yourself + A ti mismo + + + + Mined + Minado + + + + Other + Otra + + + + Enter address or label to search + Introduzca una dirección o etiqueta que buscar + + + + Min amount + Cantidad mínima + + + + Copy address + Copiar dirección + + + + Copy label + Copiar etiqueta + + + + Copy amount + Copiar cuantía + + + + Edit label + Editar etiqueta + + + + Show transaction details + Mostrar detalles de la transacción + + + + Export Transaction Data + Exportar datos de la transacción + + + + Comma separated file (*.csv) + Archivos de columnas separadas por coma (*.csv) + + + + Confirmed + Confirmado + + + + Date + Fecha + + + + Type + Tipo + + + + Label + Etiqueta + + + + Address + Dirección + + + + Amount + Cantidad + + + + ID + ID + + + + Error exporting + Error exportando + + + + Could not write to file %1. + No se pudo escribir en el archivo %1. + + + + Range: + Rango: + + + + to + para + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Copia la dirección seleccionada al portapapeles + + + + &Copy Address + &Copiar dirección + + + + Reset all verify message fields + + + + + Clear &All + Limpiar &todo + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Enviando... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Minimiza a la bandeja en vez de la barra de tareas + + + + Show only a tray icon after minimizing the window + Muestra solo el icono de sistema cuando se minimice la ventana + + + + M&inimize on close + + + + + 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. + Minimiza la ventana en lugar de salir de la aplicación.Cuando esta opcion está activa la aplicación solo se puede cerrar seleccionando Salir desde el menú. + + + + bitcoin-core + + + Bitcoin version + Versión de Bitcoin + + + + Usage: + Uso: + + + + Send command to -server or bitcoind + Envíar comando a -server o bitcoind + + + + List commands + Muestra comandos + + + + + Get help for a command + Recibir ayuda para un comando + + + + + Options: + Opciones: + + + + + Specify configuration file (default: bitcoin.conf) + Especifica archivo de configuración (predeterminado: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + Especifica archivo pid (predeterminado: bitcoin.pid) + + + + + Generate coins + Generar monedas + + + + Don't generate coins + No generar monedas + + + + Specify data directory + Especificar directorio para los datos + + + + Set database cache size in megabytes (default: 25) + Establecer el tamaño del caché de la base de datos en megabytes (por defecto: 25) + + + + Set database disk log size in megabytes (default: 100) + Base de datos de conjunto de discos de registro de tamaño en megabytes (por defecto: 100) + + + + Specify connection timeout (in milliseconds) + Especifica tiempo de espera para conexion (en milisegundos) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Preste atención a las conexiones en <puerto> (por defecto: 8333 o testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Mantener en la mayoría de las conexiones <n> a sus compañeros (por defecto: 125) + + + + Connect only to the specified node + Conecta solo al nodo especificado + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Umbral para la desconexión de los compañeros se portan mal (por defecto: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Número de segundos que se mantienen los compañeros se portan mal en volver a conectarse (por defecto: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Máximo por-conexión búfer de recepción, <n>*1000 bytes (por defecto: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Máximo por conexión buffer de envío, <n>*1000 bytes (por defecto: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Aceptar comandos consola y JSON-RPC + + + + + Run in the background as a daemon and accept commands + Correr como demonio y acepta comandos + + + + + Use the test network + Usa la red de pruebas + + + + + Output extra debugging information + Salida de información de depuración extra + + + + Prepend debug output with timestamp + Anteponer la salida de depuración, con indicación de la hora + + + + Send trace/debug info to console instead of debug.log file + Enviar rastrear/debug info a la consola en lugar de debug.log archivo + + + + Send trace/debug info to debugger + Enviar rastrear / debug info al depurador + + + + Username for JSON-RPC connections + Usuario para las conexiones JSON-RPC + + + + + Password for JSON-RPC connections + Contraseña para las conexiones JSON-RPC + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Escucha conexiones JSON-RPC en el puerto <port> (predeterminado: 8332) + + + + + Allow JSON-RPC connections from specified IP address + Permite conexiones JSON-RPC desde la dirección IP especificada + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Envía comando al nodo situado en <ip> (predeterminado: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Ejecutar un comando cuando cambia el mejor bloque (%s en cmd se sustituye por el hash de bloque) + + + + Upgrade wallet to latest format + Actualizar el monedero al último formato + + + + Set key pool size to <n> (default: 100) + Ajusta el número de claves en reserva <n> (predeterminado: 100) + + + + + Rescan the block chain for missing wallet transactions + Volver a examinar la cadena de bloques en busca de transacciones del monedero perdidas + + + + How many blocks to check at startup (default: 2500, 0 = all) + Cuántos bloques para comprobar en el arranque (por defecto: 2500, 0 = todos) + + + + How thorough the block verification is (0-6, default: 1) + Cómo completa la verificación del bloque es (0-6, por defecto: 1) + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + Opciones SSL: (ver la Bitcoin Wiki para instrucciones de configuración SSL) + + + + + Use OpenSSL (https) for JSON-RPC connections + Usa OpenSSL (https) para las conexiones JSON-RPC + + + + + Server certificate file (default: server.cert) + Certificado del servidor (Predeterminado: server.cert) + + + + + Server private key (default: server.pem) + Clave privada del servidor (Predeterminado: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Cifrados aceptados (Predeterminado: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + Este mensaje de ayuda + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + No se puede obtener permiso de trabajo en la carpeta de datos %s. Probablemente Bitcoin ya se está ejecutando. + + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Cargando direcciones... + + + + Error loading blkindex.dat + Error al cargar blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Error al cargar wallet.dat: el monedero está dañado + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Error al cargar wallet.dat: El monedero requiere una versión más reciente de Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + El monedero ha necesitado ser reescrito. Reinicie Bitcoin para completar el proceso + + + + Error loading wallet.dat + Error al cargar wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + Error: monedero bloqueado. Bitcoin es incapaz de crear las transacciones + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Error: esta transacción está sujeta a una tarifa de %s, bien por su cantidad, complejidad, o por el uso de fondos recientemente recibidos + + + + Error: Transaction creation failed + Error: no se ha podido crear la transacción + + + + Sending... + Enviando... + + + + 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. + Error: la transacción fue rechazada. Esto puede pasar si alguna de las monedas ya estaba gastada o si ha usado una copia de wallet.dat y las monedas se gastaron en la copia pero no se han marcado como gastadas aquí. + + + + Invalid amount + Cuantía no válida + + + + Insufficient funds + Fondos insuficientes + + + + Loading block index... + Cargando el índice de bloques... + + + + Add a node to connect to and attempt to keep the connection open + Añadir un nodo para conectarse y tratar de mantener la conexión abierta + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + Encontrar los pares utilizando Internet Relay Chat (por defecto: 0) + + + + Accept connections from outside (default: 1) + Aceptar conexiones desde el exterior (por defecto: 1) + + + + Find peers using DNS lookup (default: 1) + Encontrar compañeros con búsqueda de DNS (por defecto: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Use Universal Plug and Play para asignar el puerto de escucha (por defecto: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Use Universal Plug and Play para asignar el puerto de escucha (por defecto: 0) + + + + Fee per KB to add to transactions you send + Tarifa por KB que añadir a las transacciones que envíe + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Cargando monedero... + + + + Cannot downgrade wallet + No se puede rebajar el monedero + + + + Cannot initialize keypool + No se puede inicializar grupo de teclas + + + + Cannot write default address + No se puede escribir la dirección por defecto + + + + Rescanning... + Rescaneando... + + + + Done loading + Generado pero no aceptado + + + + To use the %s option + Para utilizar la opción %s + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, tiene que establecer rpcpassword en el archivo de configuración: ⏎ +%s ⏎ +Se recomienda utilizar la siguiente contraseña aleatoria: ⏎ +rpcuser = bitcoinrpc ⏎ +rpcpassword =%s ⏎ +(no es necesario para recordar esta contraseña) ⏎ +Si el archivo no existe se crea con los permisos de lectura y escritura solamente del propietario. ⏎ + + + + Error + Error + + + + An error occured while setting up the RPC port %i for listening: %s + Ha ocurrido un error al instalar el puerto RPC %i para escuchar: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Tiene que establecer rpcpassword=<contraseña> en el fichero de configuración: ⏎ +%s ⏎ +Si el archivo no existe, se crea con permisos de propietario de lectura de sólo archivos. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Precaución: revise por favor que la fecha y hora de su sistema son correctas. Si el reloj está mal Bitcoin no funcionará correctamente. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts new file mode 100644 index 0000000..5a11ee2 --- /dev/null +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -0,0 +1,2538 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Sobre Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> - versión + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 desarrolladores Bitcoin + +Este es un software experimental. + +Distribuído bajo la licencia de software MIT/X11, vease el archivo adjunto licence.txt o http://www.opensource.org/licenses/mit-license.php. + +Este producto include software desarrollado por el proyecto OpenSSL para ser usado en el OpenSSL Toolkit (http://www.openssl.org/) y software criptográfico escrito por Eric Young (eay@cryptsoft.com) y el software UPnP escrito por Thomas Bernard. + + + + AddressBookPage + + + Address Book + Guia de direcciones + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Estas son tus direcciones Bitcoin para recibir pagos. Puedes utilizar una diferente por cada persona emisora para saber quien te está pagando. + + + + Double-click to edit address or label + Haz doble clic para editar una dirección o etiqueta + + + + Create a new address + Crea una nueva dirección + + + + Copy the currently selected address to the system clipboard + Copia la dirección seleccionada al portapapeles + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Mostrar Código &QR + + + + Sign a message to prove you own this address + Firmar un mensaje para provar que usted es dueño de esta dirección + + + + &Sign Message + Firmar Mensaje + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Borra la dirección seleccionada de la lista. Solo las direcciónes de envio se pueden borrar. + + + + &Delete + &Borrar + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Exporta datos de la guia de direcciones + + + + Comma separated file (*.csv) + Archivos separados por coma (*.csv) + + + + Error exporting + Exportar errores + + + + Could not write to file %1. + No se pudo escribir al archivo %1. + + + + AddressTableModel + + + Label + Etiqueta + + + + Address + Dirección + + + + (no label) + (sin etiqueta) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Introduce contraseña actual + + + + New passphrase + Nueva contraseña + + + + Repeat new passphrase + Repite nueva contraseña: + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Introduce la nueva contraseña para la billetera.<br/>Por favor utiliza un contraseña <b>de 10 o mas caracteres aleatorios</b>, u <b>ocho o mas palabras</b>. + + + + Encrypt wallet + Codificar billetera + + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operación necesita la contraseña para desbloquear la billetera. + + + + Unlock wallet + Desbloquea billetera + + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operación necesita la contraseña para decodificar la billetara. + + + + Decrypt wallet + Decodificar cartera + + + + Change passphrase + Cambia contraseña + + + + Enter the old and new passphrase to the wallet. + Introduce la contraseña anterior y la nueva de cartera + + + + Confirm wallet encryption + Confirma la codificación de cartera + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ATENCIÓN: ¡Si codificas tu billetera y pierdes la contraseña perderás <b>TODOS TUS BITCOINS</b>!" +¿Seguro que quieres seguir codificando la billetera? + + + + + Wallet encrypted + Billetera codificada + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin se cerrará para finalizar el proceso de encriptación. Recuerde que encriptar su billetera no protegera completatamente sus bitcoins de ser robados por malware que infecte su computador + + + + + Warning: The Caps Lock key is on. + Precaucion: Mayúsculas Activadas + + + + + + + Wallet encryption failed + Falló la codificación de la billetera + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + La codificación de la billetera falló debido a un error interno. Tu billetera no ha sido codificada. + + + + + The supplied passphrases do not match. + Las contraseñas no coinciden. + + + + Wallet unlock failed + Ha fallado el desbloqueo de la billetera + + + + + + The passphrase entered for the wallet decryption was incorrect. + La contraseña introducida para decodificar la billetera es incorrecta. + + + + Wallet decryption failed + Ha fallado la decodificación de la billetera + + + + Wallet passphrase was succesfully changed. + La contraseña de billetera ha sido cambiada con éxito. + + + + BitcoinGUI + + + Bitcoin Wallet + Billetera Bitcoin + + + + Sign &message... + + + + + Show/Hide &Bitcoin + Mostrar/Ocultar &Bitcoin + + + + Synchronizing with network... + Sincronizando con la red... + + + + &Overview + &Vista general + + + + Show general overview of wallet + Muestra una vista general de la billetera + + + + &Transactions + &Transacciónes + + + + Browse transaction history + Explora el historial de transacciónes + + + + &Address Book + &Guia de direcciónes + + + + Edit the list of stored addresses and labels + Edita la lista de direcciones y etiquetas almacenadas + + + + &Receive coins + &Recibir monedas + + + + Show the list of addresses for receiving payments + Muestra la lista de direcciónes utilizadas para recibir pagos + + + + &Send coins + &Envíar monedas + + + + Prove you control an address + Suministre dirección de control + + + + E&xit + &Salir + + + + Quit application + Salir del programa + + + + &About %1 + S&obre %1 + + + + Show information about Bitcoin + Muestra información acerca de Bitcoin + + + + About &Qt + Acerca de + + + + Show information about Qt + Mostrar Información sobre QT + + + + &Options... + &Opciones + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + %n bloque restante%n bloques restantes + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Descargados %1 de %2 bloques del historial de transacciones (%3% hecho). + + + + &Export... + &Exportar... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Mostrar u ocultar la ventana de Bitcoin + + + + Export the data in the current tab to a file + Exportar los datos de la pestaña actual a un archivo + + + + Encrypt or decrypt wallet + Codificar o decodificar la billetera + + + + Backup wallet to another location + Respaldar billetera en otra ubicación + + + + Change the passphrase used for wallet encryption + Cambiar la contraseña utilizada para la codificación de la billetera + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Archivo + + + + &Settings + &Configuración + + + + &Help + &Ayuda + + + + Tabs toolbar + Barra de pestañas + + + + Actions toolbar + Barra de acciónes + + + + + [testnet] + [red-de-pruebas] + + + + + Bitcoin client + Cliente Bitcoin + + + + %n active connection(s) to Bitcoin network + %n conexión activa hacia la red Bitcoin%n conexiones activas hacia la red Bitcoin + + + + Downloaded %1 blocks of transaction history. + Descargado %1 bloques del historial de transacciones. + + + + %n second(s) ago + Hace %n segundoHace %n segundos + + + + %n minute(s) ago + Hace %n minutoHace %n minutos + + + + %n hour(s) ago + Hace %n horaHace %n horas + + + + %n day(s) ago + Hace %n díaHace %n días + + + + Up to date + Actualizado + + + + Catching up... + Recuperando... + + + + Last received block was generated %1. + El ultimo bloque recibido fue generado %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Esta transacción supera el límite. Puedes seguir enviandola incluyendo una comisión de %s que se va a repartir entre los nodos que procesan su transacción y ayudan a mantener la red. ¿Quieres seguir con la transacción? + + + + Confirm transaction fee + + + + + Sent transaction + Transacción enviada + + + + Incoming transaction + Transacción entrante + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Fecha: %1 +Cantidad: %2 +Tipo: %3 +Dirección: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + La billetera esta <b>codificada</b> y actualmente <b>desbloqueda</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + La billetera esta <b>codificada</b> y actualmente <b>bloqueda</b> + + + + Backup Wallet + Respaldar billetera + + + + Wallet Data (*.dat) + Datos de billetera (*.dat) + + + + Backup Failed + Ha fallado el respaldo + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Mostrado + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Elige la subdivisión por defecto para mostrar cantidaded en la interfaz cuando se envien monedas + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Editar dirección + + + + &Label + &Etiqueta + + + + The label associated with this address book entry + La etiqueta asociada con esta entrada de la libreta de direcciones + + + + &Address + &Dirección + + + + The address associated with this address book entry. This can only be modified for sending addresses. + La dirección asociada con esta entrada en la libreta de direcciones. Solo puede ser modificada para direcciónes de envío. + + + + New receiving address + Nueva dirección para recibir + + + + New sending address + Nueva dirección para enviar + + + + Edit receiving address + Editar dirección de recepción + + + + Edit sending address + Editar dirección de envio + + + + The entered address "%1" is already in the address book. + La dirección introducida "%1" ya esta guardada en la libreta de direcciones. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + No se pudo desbloquear la billetera. + + + + New key generation failed. + La generación de nueva clave falló. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Uso: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + Arranca minimizado + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Comisión de &transacciónes + + + + Main + Principal + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Comisión opcional por kB que ayuda a asegurar que sus transacciones son procesadas rápidamente. La mayoria de transacciones son de 1 KB. Se recomienda comisión de 0.01 + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + La dirección con la que codificar el mensaje (ej: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Elije dirección de la guia + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Pega dirección desde portapapeles + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Escriba el mensaje que desea firmar + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Click en "Firmar Mensage" para conseguir firma + + + + Sign a message to prove you own this address + Firmar un mensjage para probar que usted es dueño de esta dirección + + + + &Sign Message + & Firmar Mensaje + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Introduce una dirección Bitcoin (ej. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Error al firmar + + + + %1 is not a valid address. + %1 no es una dirección válida. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Llave privada para %q no esta disponible. + + + + Sign failed + Falló Firma + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Direcciona el puerto usando &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Abre automáticamente el puerto del cliente Bitcoin en el router. Esto funciona solo cuando tu router es compatible con UPnP y está habilitado. + + + + &Connect through SOCKS4 proxy: + &Conecta a traves de un proxy SOCKS4: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Conecta a la red Bitcoin a través de un proxy SOCKS4 (ej. cuando te conectas por la red Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + Dirección IP del servidor proxy (ej. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Puerto del servidor proxy (ej. 1234) + + + + OptionsDialog + + + Options + Opciones + + + + OverviewPage + + + Form + Formulario + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Saldo: + + + + Number of transactions: + Numero de transacciones: + + + + Unconfirmed: + No confirmados: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Transacciones recientes</b> + + + + Your current balance + Tu saldo actual + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Total de transacciones que no han sido confirmadas aun, y que no cuentan para el saldo actual. + + + + Total number of transactions in wallet + Número total de transacciones en la billetera + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + Código QR + + + + Request Payment + Solicitar Pago + + + + Amount: + Cantidad: + + + + BTC + BTC + + + + Label: + Etiqueta + + + + Message: + Mensaje: + + + + &Save As... + &Guardar Como... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + Imágenes PNG (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Enviar monedas + + + + Send to multiple recipients at once + Enviar a múltiples destinatarios + + + + &Add Recipient + + + + + Remove all transaction fields + Remover todos los campos de la transacción + + + + Clear &All + + + + + Balance: + Balance: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Confirma el envio + + + + &Send + &Envía + + + + <b>%1</b> to %2 (%3) + <b>%1</b> to %2 (%3) + + + + Confirm send coins + Confirmar el envio de monedas + + + + Are you sure you want to send %1? + Estas seguro que quieres enviar %1? + + + + and + y + + + + The recepient address is not valid, please recheck. + La dirección de destinatarion no es valida, comprueba otra vez. + + + + The amount to pay must be larger than 0. + La cantidad por pagar tiene que ser mayor 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Envio + + + + A&mount: + Cantidad: + + + + Pay &To: + &Pagar a: + + + + + Enter a label for this address to add it to your address book + Introduce una etiqueta a esta dirección para añadirla a tu guia + + + + &Label: + &Etiqueta: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + La dirección donde enviar el pago (ej. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Elije dirección de la guia + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Pega dirección desde portapapeles + + + + Alt+P + Alt+P + + + + Remove this recipient + Elimina destinatario + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Introduce una dirección Bitcoin (ej. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Abierto hasta %1 bloques + + + + Open until %1 + Abierto hasta %1 + + + + %1/offline? + %1/fuera de linea? + + + + %1/unconfirmed + %1/no confirmado + + + + %1 confirmations + %1 confirmaciónes + + + + <b>Status:</b> + <b>Estado:</b> + + + + , has not been successfully broadcast yet + , no ha sido emitido satisfactoriamente todavía + + + + , broadcast through %1 node + , emitido mediante %1 nodo + + + + , broadcast through %1 nodes + , emitido mediante %1 nodos + + + + <b>Date:</b> + <b>Fecha:</b> + + + + <b>Source:</b> Generated<br> + <b>Fuente:</b> Generado<br> + + + + + <b>From:</b> + <b>De:</b> + + + + unknown + desconocido + + + + + + <b>To:</b> + <b>Para:</b> + + + + (yours, label: + (tuya, etiqueta: + + + + (yours) + (tuya) + + + + + + + <b>Credit:</b> + <b>Crédito:</b> + + + + (%1 matures in %2 more blocks) + (%1 madura en %2 bloques mas) + + + + (not accepted) + (no aceptada) + + + + + + <b>Debit:</b> + <b>Débito:</b> + + + + <b>Transaction fee:</b> + <b>Comisión transacción:</b> + + + + <b>Net amount:</b> + <b>Cantidad total:</b> + + + + Message: + Mensaje: + + + + Comment: + Comentario: + + + + Transaction ID: + ID de Transacción: + + + + Generated coins must wait 8 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. + Las monedas generadas deben esperar 8 bloques antes de ser gastadas. Cuando has generado este bloque se emitió a la red para ser agregado en la cadena de bloques. Si falla al incluirse en la cadena, cambiará a "no aceptado" y las monedas no se podrán gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque casi al mismo tiempo que el tuyo. + + + + TransactionDescDialog + + + Transaction details + Detalles de transacción + + + + This pane shows a detailed description of the transaction + Esta ventana muestra información detallada sobre la transacción + + + + TransactionTableModel + + + Date + Fecha + + + + Type + Tipo + + + + Address + Dirección + + + + Amount + Cantidad + + + + Open for %n block(s) + Abierto por %n bloqueAbierto por %n bloques + + + + Open until %1 + Abierto hasta %1 + + + + Offline (%1 confirmations) + Fuera de linea (%1 confirmaciónes) + + + + Unconfirmed (%1 of %2 confirmations) + No confirmado (%1 de %2 confirmaciónes) + + + + Confirmed (%1 confirmations) + Confirmado (%1 confirmaciones) + + + + Mined balance will be available in %n more blocks + El balance minado estará disponible en %n bloque masEl balance minado estará disponible en %n bloques mas + + + + This block was not received by any other nodes and will probably not be accepted! + Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado ! + + + + Generated but not accepted + Generado pero no acceptado + + + + Received with + Recibido con + + + + Received from + Recibido de + + + + Sent to + Enviado a + + + + Payment to yourself + Pagar a usted mismo + + + + Mined + Minado + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + Estado de transacción. Pasa el raton sobre este campo para ver el numero de confirmaciónes. + + + + Date and time that the transaction was received. + Fecha y hora cuando se recibió la transaccion + + + + Type of transaction. + Tipo de transacción. + + + + Destination address of transaction. + Dirección de destino para la transacción + + + + Amount removed from or added to balance. + Cantidad restada o añadida al balance + + + + TransactionView + + + + All + Todo + + + + Today + Hoy + + + + This week + Esta semana + + + + This month + Esta mes + + + + Last month + Mes pasado + + + + This year + Este año + + + + Range... + Rango... + + + + Received with + Recibido con + + + + Sent to + Enviado a + + + + To yourself + A ti mismo + + + + Mined + Minado + + + + Other + Otra + + + + Enter address or label to search + Introduce una dirección o etiqueta para buscar + + + + Min amount + Cantidad minima + + + + Copy address + Copia dirección + + + + Copy label + Copia etiqueta + + + + Copy amount + Copiar Cantidad + + + + Edit label + Edita etiqueta + + + + Show transaction details + + + + + Export Transaction Data + Exportar datos de transacción + + + + Comma separated file (*.csv) + Archivos separados por coma (*.csv) + + + + Confirmed + Confirmado + + + + Date + Fecha + + + + Type + Tipo + + + + Label + Etiqueta + + + + Address + Dirección + + + + Amount + Cantidad + + + + ID + ID + + + + Error exporting + Error exportando + + + + Could not write to file %1. + No se pudo escribir en el archivo %1. + + + + Range: + Rango: + + + + to + para + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Copiar la dirección seleccionada al portapapeles + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Enviando... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Minimiza a la bandeja en vez de la barra de tareas + + + + Show only a tray icon after minimizing the window + Muestra solo un ícono en la bandeja después de minimizar la ventana + + + + M&inimize on close + + + + + 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. + Minimiza la ventana en lugar de salir del programa cuando la ventana se cierra. Cuando esta opción esta activa el programa solo se puede cerrar seleccionando Salir desde el menu. + + + + bitcoin-core + + + Bitcoin version + Versión Bitcoin + + + + Usage: + Uso: + + + + Send command to -server or bitcoind + Envia comando a bitcoin lanzado con -server u bitcoind + + + + + List commands + Muestra comandos + + + + + Get help for a command + Recibir ayuda para un comando + + + + + Options: + Opciones: + + + + + Specify configuration file (default: bitcoin.conf) + Especifica archivo de configuración (predeterminado: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + Especifica archivo pid (predeterminado: bitcoin.pid) + + + + + Generate coins + Genera monedas + + + + + Don't generate coins + No generar monedas + + + + + Specify data directory + Especifica directorio para los datos + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Especifica tiempo de espera para conexion (en milisegundos) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Escuchar por conecciones en <puerto> (Por defecto: 8333 o red de prueba: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Mantener al menos <n> conecciones por cliente (por defecto: 125) + + + + Connect only to the specified node + Conecta solo al nodo especificado + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Umbral de desconección de clientes con mal comportamiento (por defecto: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Aceptar comandos consola y JSON-RPC + + + + + Run in the background as a daemon and accept commands + Correr como demonio y acepta comandos + + + + + Use the test network + Usa la red de pruebas + + + + + Output extra debugging information + Adjuntar informacion extra de depuracion + + + + Prepend debug output with timestamp + Anteponer salida de depuracion con marca de tiempo + + + + Send trace/debug info to console instead of debug.log file + Enviar informacion de seguimiento a la consola en vez del archivo debug.log + + + + Send trace/debug info to debugger + Enviar informacion de seguimiento al depurador + + + + Username for JSON-RPC connections + Usuario para las conexiones JSON-RPC + + + + + Password for JSON-RPC connections + Contraseña para las conexiones JSON-RPC + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Escucha conexiones JSON-RPC en el puerto <port> (predeterminado: 8332) + + + + + Allow JSON-RPC connections from specified IP address + Permite conexiones JSON-RPC desde la dirección IP especificada + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Envia comando al nodo situado en <ip> (predeterminado: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + Actualizar billetera al formato actual + + + + Set key pool size to <n> (default: 100) + Ajusta el numero de claves en reserva <n> (predeterminado: 100) + + + + + Rescan the block chain for missing wallet transactions + Rescanea la cadena de bloques para transacciones perdidas de la cartera + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + Opciones SSL: (ver la Bitcoin Wiki para instrucciones de configuración SSL) + + + + + Use OpenSSL (https) for JSON-RPC connections + Usa OpenSSL (https) para las conexiones JSON-RPC + + + + + Server certificate file (default: server.cert) + Certificado del servidor (Predeterminado: server.cert) + + + + + Server private key (default: server.pem) + Clave privada del servidor (Predeterminado: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Cifrados aceptados (Predeterminado: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + Este mensaje de ayuda + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + No se puede obtener permiso de trabajo en la carpeta de datos %s. Probablemente Bitcoin ya se está ejecutando. + + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Cargando direcciónes... + + + + Error loading blkindex.dat + Error cargando blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Error cargando wallet.dat: Billetera corrupta + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Error cargando wallet.dat: Billetera necesita una vercion reciente de Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + La billetera necesita ser reescrita: reinicie Bitcoin para completar + + + + Error loading wallet.dat + Error cargando wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + Error: Billetera bloqueada, no es posible crear la transacción + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Error: Esta transación requiere una comisión de al menos %s por su cantidad, complejidad o uso de fondos recibidos recientemente. + + + + Error: Transaction creation failed + Error: La transacción no se pudo crear + + + + Sending... + Enviando... + + + + 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. + Error: La transacción fue rechazada. Esto puede haber ocurrido si alguna de las monedas ya estaba gastada o si ha usado una copia de wallet.dat y las monedas se gastaron en la copia pero no se han marcado como gastadas aqui. + + + + Invalid amount + Cantidad inválida + + + + Insufficient funds + Fondos insuficientes + + + + Loading block index... + Cargando el index de bloques... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + Buscar pares usando 'internet relay chat (IRC)' (predeterminado: 0) + + + + Accept connections from outside (default: 1) + Aceptar conexiones desde el exterior (predeterminado: 1) + + + + Find peers using DNS lookup (default: 1) + Buscar pares usando el sistema DNS (predeterminado: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Cargando cartera... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Rescaneando... + + + + Done loading + Carga completa + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + Error + + + + An error occured while setting up the RPC port %i for listening: %s + Ha ocurrido un error estableciendo el puerto RPC %i en modo escucha: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Precaución: Por favor revise que la fecha y hora de tu ordenador son correctas. Si tu reloj está mal configurado Bitcoin no funcionará correctamente. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts new file mode 100644 index 0000000..aafd7a2 --- /dev/null +++ b/src/qt/locale/bitcoin_et.ts @@ -0,0 +1,2499 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + + + + + <b>Bitcoin</b> version + + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + + + + + Double-click to edit address or label + + + + + Create a new address + Loo uus aadress + + + + Copy the currently selected address to the system clipboard + + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + + + + + &Delete + &Kustuta + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + + + + + Comma separated file (*.csv) + + + + + Error exporting + Viga eksportimisel + + + + Could not write to file %1. + + + + + AddressTableModel + + + Label + Silt + + + + Address + Aadress + + + + (no label) + (silti pole) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + + + + + New passphrase + + + + + Repeat new passphrase + + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + + + + + Encrypt wallet + + + + + This operation needs your wallet passphrase to unlock the wallet. + + + + + Unlock wallet + + + + + This operation needs your wallet passphrase to decrypt the wallet. + + + + + Decrypt wallet + + + + + Change passphrase + + + + + Enter the old and new passphrase to the wallet. + + + + + Confirm wallet encryption + + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + + + + + + Wallet encrypted + + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + + + + The supplied passphrases do not match. + + + + + Wallet unlock failed + + + + + + + The passphrase entered for the wallet decryption was incorrect. + + + + + Wallet decryption failed + + + + + Wallet passphrase was succesfully changed. + + + + + BitcoinGUI + + + Bitcoin Wallet + + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + + + + + &Overview + &Ülevaade + + + + Show general overview of wallet + + + + + &Transactions + &Tehingud + + + + Browse transaction history + Sirvi tehingute ajalugu + + + + &Address Book + &Aadressiraamat + + + + Edit the list of stored addresses and labels + + + + + &Receive coins + + + + + Show the list of addresses for receiving payments + + + + + &Send coins + + + + + Prove you control an address + + + + + E&xit + + + + + Quit application + + + + + &About %1 + + + + + Show information about Bitcoin + + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + &Valikud... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Ekspordi... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Fail + + + + &Settings + &Seaded + + + + &Help + &Abiinfo + + + + Tabs toolbar + + + + + Actions toolbar + + + + + + [testnet] + + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + + + + + Downloaded %1 blocks of transaction history. + + + + + %n second(s) ago + + + + + %n minute(s) ago + + + + + %n hour(s) ago + + + + + %n day(s) ago + + + + + Up to date + + + + + Catching up... + + + + + Last received block was generated %1. + + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + + + + + Confirm transaction fee + + + + + Sent transaction + + + + + Incoming transaction + + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Muuda aadressi + + + + &Label + Si&lt + + + + The label associated with this address book entry + + + + + &Address + + + + + The address associated with this address book entry. This can only be modified for sending addresses. + + + + + New receiving address + + + + + New sending address + + + + + Edit receiving address + + + + + Edit sending address + + + + + The entered address "%1" is already in the address book. + + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + + + + + New key generation failed. + + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + + + + + Main + + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + + + &Connect through SOCKS4 proxy: + + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + + + + + Port of the proxy (e.g. 1234) + + + + + OptionsDialog + + + Options + + + + + OverviewPage + + + Form + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + + + + + Number of transactions: + + + + + Unconfirmed: + + + + + Wallet + + + + + <b>Recent transactions</b> + + + + + Your current balance + + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + + + Total number of transactions in wallet + + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + Sõnum: + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + + + + + Send to multiple recipients at once + + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + + + + + 123.456 BTC + + + + + Confirm the send action + + + + + &Send + + + + + <b>%1</b> to %2 (%3) + + + + + Confirm send coins + + + + + Are you sure you want to send %1? + + + + + and + + + + + The recepient address is not valid, please recheck. + + + + + The amount to pay must be larger than 0. + + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + + + + + A&mount: + + + + + Pay &To: + + + + + + Enter a label for this address to add it to your address book + + + + + &Label: + + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose address from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Remove this recipient + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + TransactionDesc + + + Open for %1 blocks + + + + + Open until %1 + + + + + %1/offline? + + + + + %1/unconfirmed + + + + + %1 confirmations + + + + + <b>Status:</b> + + + + + , has not been successfully broadcast yet + + + + + , broadcast through %1 node + + + + + , broadcast through %1 nodes + + + + + <b>Date:</b> + + + + + <b>Source:</b> Generated<br> + + + + + + <b>From:</b> + + + + + unknown + tundmatu + + + + + + <b>To:</b> + + + + + (yours, label: + + + + + (yours) + + + + + + + + <b>Credit:</b> + + + + + (%1 matures in %2 more blocks) + + + + + (not accepted) + + + + + + + <b>Debit:</b> + + + + + <b>Transaction fee:</b> + + + + + <b>Net amount:</b> + + + + + Message: + Sõnum: + + + + Comment: + Kommentaar: + + + + Transaction ID: + + + + + 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. + + + + + TransactionDescDialog + + + Transaction details + + + + + This pane shows a detailed description of the transaction + + + + + TransactionTableModel + + + Date + Kuupäev + + + + Type + Tüüp + + + + Address + Aadress + + + + Amount + Kogus + + + + Open for %n block(s) + + + + + Open until %1 + + + + + Offline (%1 confirmations) + + + + + Unconfirmed (%1 of %2 confirmations) + + + + + Confirmed (%1 confirmations) + + + + + Mined balance will be available in %n more blocks + + + + + This block was not received by any other nodes and will probably not be accepted! + + + + + Generated but not accepted + + + + + Received with + + + + + Received from + + + + + Sent to + + + + + Payment to yourself + + + + + Mined + + + + + (n/a) + + + + + Transaction status. Hover over this field to show number of confirmations. + + + + + Date and time that the transaction was received. + + + + + Type of transaction. + + + + + Destination address of transaction. + + + + + Amount removed from or added to balance. + + + + + TransactionView + + + + All + + + + + Today + + + + + This week + + + + + This month + + + + + Last month + + + + + This year + + + + + Range... + + + + + Received with + + + + + Sent to + + + + + To yourself + + + + + Mined + + + + + Other + + + + + Enter address or label to search + + + + + Min amount + + + + + Copy address + + + + + Copy label + + + + + Copy amount + + + + + Edit label + + + + + Show transaction details + + + + + Export Transaction Data + + + + + Comma separated file (*.csv) + + + + + Confirmed + + + + + Date + Kuupäev + + + + Type + Tüüp + + + + Label + Silt + + + + Address + Aadress + + + + Amount + Kogus + + + + ID + + + + + Error exporting + Viga eksportimisel + + + + Could not write to file %1. + + + + + Range: + + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + + + + + Show only a tray icon after minimizing the window + + + + + M&inimize on close + + + + + 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. + + + + + bitcoin-core + + + Bitcoin version + + + + + Usage: + + + + + Send command to -server or bitcoind + + + + + List commands + + + + + Get help for a command + + + + + Options: + + + + + Specify configuration file (default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + + + + + Generate coins + + + + + Don't generate coins + + + + + Specify data directory + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + + + + + Run in the background as a daemon and accept commands + + + + + Use the test network + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + + + + + Password for JSON-RPC connections + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + + Use OpenSSL (https) for JSON-RPC connections + + + + + Server certificate file (default: server.cert) + + + + + Server private key (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + + Bitcoin + + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + + + + + Sending... + + + + + 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. + + + + + Invalid amount + + + + + Insufficient funds + + + + + Loading block index... + + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + + + + + Done loading + + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts new file mode 100644 index 0000000..01a156c --- /dev/null +++ b/src/qt/locale/bitcoin_eu_ES.ts @@ -0,0 +1,2499 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> Bertsio + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + Helbide-liburua + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + + + + + Double-click to edit address or label + + + + + Create a new address + Sortu helbide berria + + + + Copy the currently selected address to the system clipboard + + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + + + + + &Delete + &Ezabatu + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + + + + + Comma separated file (*.csv) + + + + + Error exporting + + + + + Could not write to file %1. + + + + + AddressTableModel + + + Label + + + + + Address + Helbidea + + + + (no label) + + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + + + + + New passphrase + + + + + Repeat new passphrase + + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + + + + + Encrypt wallet + + + + + This operation needs your wallet passphrase to unlock the wallet. + + + + + Unlock wallet + + + + + This operation needs your wallet passphrase to decrypt the wallet. + + + + + Decrypt wallet + + + + + Change passphrase + + + + + Enter the old and new passphrase to the wallet. + + + + + Confirm wallet encryption + + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + + + + + + Wallet encrypted + + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + + + + The supplied passphrases do not match. + + + + + Wallet unlock failed + + + + + + + The passphrase entered for the wallet decryption was incorrect. + + + + + Wallet decryption failed + + + + + Wallet passphrase was succesfully changed. + + + + + BitcoinGUI + + + Bitcoin Wallet + + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + + + + + &Overview + + + + + Show general overview of wallet + + + + + &Transactions + + + + + Browse transaction history + + + + + &Address Book + + + + + Edit the list of stored addresses and labels + + + + + &Receive coins + + + + + Show the list of addresses for receiving payments + + + + + &Send coins + + + + + Prove you control an address + + + + + E&xit + + + + + Quit application + + + + + &About %1 + + + + + Show information about Bitcoin + + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + + + + + &Settings + + + + + &Help + + + + + Tabs toolbar + + + + + Actions toolbar + + + + + + [testnet] + + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + + + + + Downloaded %1 blocks of transaction history. + + + + + %n second(s) ago + + + + + %n minute(s) ago + + + + + %n hour(s) ago + + + + + %n day(s) ago + + + + + Up to date + + + + + Catching up... + + + + + Last received block was generated %1. + + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + + + + + Confirm transaction fee + + + + + Sent transaction + + + + + Incoming transaction + + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + + + + + &Label + + + + + The label associated with this address book entry + + + + + &Address + + + + + The address associated with this address book entry. This can only be modified for sending addresses. + + + + + New receiving address + + + + + New sending address + + + + + Edit receiving address + + + + + Edit sending address + + + + + The entered address "%1" is already in the address book. + + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + + + + + New key generation failed. + + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + + + + + Main + + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + + + &Connect through SOCKS4 proxy: + + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + + + + + Port of the proxy (e.g. 1234) + + + + + OptionsDialog + + + Options + + + + + OverviewPage + + + Form + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + + + + + Number of transactions: + + + + + Unconfirmed: + + + + + Wallet + + + + + <b>Recent transactions</b> + + + + + Your current balance + + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + + + Total number of transactions in wallet + + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + + + + + Send to multiple recipients at once + + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + + + + + 123.456 BTC + + + + + Confirm the send action + + + + + &Send + + + + + <b>%1</b> to %2 (%3) + + + + + Confirm send coins + + + + + Are you sure you want to send %1? + + + + + and + + + + + The recepient address is not valid, please recheck. + + + + + The amount to pay must be larger than 0. + + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + + + + + A&mount: + + + + + Pay &To: + + + + + + Enter a label for this address to add it to your address book + + + + + &Label: + + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose address from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Remove this recipient + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + TransactionDesc + + + Open for %1 blocks + + + + + Open until %1 + + + + + %1/offline? + + + + + %1/unconfirmed + + + + + %1 confirmations + + + + + <b>Status:</b> + + + + + , has not been successfully broadcast yet + + + + + , broadcast through %1 node + + + + + , broadcast through %1 nodes + + + + + <b>Date:</b> + + + + + <b>Source:</b> Generated<br> + + + + + + <b>From:</b> + + + + + unknown + + + + + + + <b>To:</b> + + + + + (yours, label: + + + + + (yours) + + + + + + + + <b>Credit:</b> + + + + + (%1 matures in %2 more blocks) + + + + + (not accepted) + + + + + + + <b>Debit:</b> + + + + + <b>Transaction fee:</b> + + + + + <b>Net amount:</b> + + + + + Message: + + + + + Comment: + + + + + Transaction ID: + + + + + 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. + + + + + TransactionDescDialog + + + Transaction details + + + + + This pane shows a detailed description of the transaction + + + + + TransactionTableModel + + + Date + + + + + Type + + + + + Address + Helbidea + + + + Amount + + + + + Open for %n block(s) + + + + + Open until %1 + + + + + Offline (%1 confirmations) + + + + + Unconfirmed (%1 of %2 confirmations) + + + + + Confirmed (%1 confirmations) + + + + + Mined balance will be available in %n more blocks + + + + + This block was not received by any other nodes and will probably not be accepted! + + + + + Generated but not accepted + + + + + Received with + + + + + Received from + + + + + Sent to + + + + + Payment to yourself + + + + + Mined + + + + + (n/a) + + + + + Transaction status. Hover over this field to show number of confirmations. + + + + + Date and time that the transaction was received. + + + + + Type of transaction. + + + + + Destination address of transaction. + + + + + Amount removed from or added to balance. + + + + + TransactionView + + + + All + + + + + Today + + + + + This week + + + + + This month + + + + + Last month + + + + + This year + + + + + Range... + + + + + Received with + + + + + Sent to + + + + + To yourself + + + + + Mined + + + + + Other + + + + + Enter address or label to search + + + + + Min amount + + + + + Copy address + + + + + Copy label + + + + + Copy amount + + + + + Edit label + + + + + Show transaction details + + + + + Export Transaction Data + + + + + Comma separated file (*.csv) + + + + + Confirmed + + + + + Date + + + + + Type + + + + + Label + + + + + Address + Helbidea + + + + Amount + + + + + ID + + + + + Error exporting + + + + + Could not write to file %1. + + + + + Range: + + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + + + + + Show only a tray icon after minimizing the window + + + + + M&inimize on close + + + + + 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. + + + + + bitcoin-core + + + Bitcoin version + + + + + Usage: + + + + + Send command to -server or bitcoind + + + + + List commands + + + + + Get help for a command + + + + + Options: + + + + + Specify configuration file (default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + + + + + Generate coins + + + + + Don't generate coins + + + + + Specify data directory + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + + + + + Run in the background as a daemon and accept commands + + + + + Use the test network + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + + + + + Password for JSON-RPC connections + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + + Use OpenSSL (https) for JSON-RPC connections + + + + + Server certificate file (default: server.cert) + + + + + Server private key (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + + Bitcoin + + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + + + + + Sending... + + + + + 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. + + + + + Invalid amount + + + + + Insufficient funds + + + + + Loading block index... + + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + + + + + Done loading + + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts new file mode 100644 index 0000000..e918c46 --- /dev/null +++ b/src/qt/locale/bitcoin_fa.ts @@ -0,0 +1,2512 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + در مورد بیتکویین + + + + + <b>Bitcoin</b> version + نسخه + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + کپی رایت © 2012-2009 Bitcoin Developers + +این یک نرم‌افزار آزمایشی است. + +توزیع شده تحت امتیاز نرم‌افزار MIT/X11، از فایل همراه با عنوان license.txt یا http://www.opensource.org/licenses/mit-license.php دیدن کنید. + +این محصول از نرم‌افزار ساخته شده در OpenSSL Project برای استفاده در جعبه ابزار OpenSSL‏ (http://www.openssl.org/‎)، نرم‌افزار نهفته نوشته شده توسط اریک یانگ (eay@cryptsoft.com) و نرم‌افزار UPnP نوشته شده توسط توماس برنارد تشکیل شده است. + + + + AddressBookPage + + + Address Book + دفتر آدرس + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + ااینجا آدرسهای بیتکویین هستند برای در یافت پر داختها. شما می توانید از مسیر های متفاوت پر داخت در بیابید بدین دلیل شما می توانید مسیر پر داخت کننده نگهداری کنید +درس روی پنجره اصلی نمایش می شود + + + + Double-click to edit address or label + برای ویرایش آدرس یا بر چسب دو بار کلیک کنید + + + + Create a new address + آدرس نو ایجاد کنید + + + + Copy the currently selected address to the system clipboard + آدرس انتخاب شده در سیستم تخته رسم گیره دار کپی کنید + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + نمایش &کد QR + + + + Sign a message to prove you own this address + یک پیام را امضا کنید تا ثابت کنید صاحب این نشانی هستید + + + + &Sign Message + &امضای پیام + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + آدرس انتخاب شده از لیست حذف کنید. فقط آدرسهای ارسال شده می شود حفذ کرد + + + + &Delete + آدرس نو + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + آدرس انتخاب شده در سیستم تخته رسم گیره دار کپی کنید + + + + Comma separated file (*.csv) + Comma فایل جدا + + + + Error exporting + خطای صادرت + + + + Could not write to file %1. + تا فایل %1 نمی شود نوشت + + + + AddressTableModel + + + Label + ر چسب + + + + Address + ایل جدا + + + + (no label) + خطای صادرت + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + وارد عبارت عبور + + + + New passphrase + عبارت عبور نو + + + + Repeat new passphrase + تکرار عبارت عبور نو + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + وارد کنید..&lt;br/&gt عبارت عبور نو در پنجره + 10 یا بیشتر کاراکتورهای تصادفی استفاده کنید &lt;b&gt لطفا عبارت عبور + + + + Encrypt wallet + رمز بندی پنجره + + + + This operation needs your wallet passphrase to unlock the wallet. + این عملیت نیاز عبارت عبور پنجره شما دارد برای رمز گشایی آن + + + + Unlock wallet + تکرار عبارت عبور نو + + + + This operation needs your wallet passphrase to decrypt the wallet. + این عملیت نیاز عبارت عبور شما دارد برای رمز بندی آن + + + + Decrypt wallet + رمز بندی پنجره + + + + Change passphrase + تغییر عبارت عبور + + + + Enter the old and new passphrase to the wallet. + عبارت عبور نو و قدیم در پنجره وارد کنید + + + + Confirm wallet encryption + تایید رمز گذاری + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + هشدار اگر شما روی پنجره رمز بگذارید و عبارت عبور فراموش کنید همه بیتکویینس شما گم می کنید. متماینید کن که می خواهید رمز بگذارید + + + + + Wallet encrypted + تغییر عبارت عبور + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Biticon هم اکنون بسته می‌شود تا فرایند رمزگذاری را تمام کند. به خاطر داشته باشید که رمزگذاری کیف پولتان نمی‌تواند به طور کامل بیتیکون‌های شما را در برابر دزدیده شدن توسط بدافزارهایی که رایانه شما را آلوده می‌کنند، محافظت نماید. + + + + + Warning: The Caps Lock key is on. + هشدار: کلید حروف بزرگ روشن است. + + + + + + + Wallet encryption failed + عبارت عبور نو و قدیم در پنجره وارد کنید + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + تنا موفق رمز بندی پنجره ناشی از خطای داخل شد. پنجره شما مرز بندی نشده است + + + + + The supplied passphrases do not match. + عبارت عبور عرضه تطابق نشد + + + + Wallet unlock failed + نجره رمز گذار شد + + + + + + The passphrase entered for the wallet decryption was incorrect. + اموفق رمز بندی پنجر + + + + Wallet decryption failed + ناموفق رمز بندی پنجره + + + + Wallet passphrase was succesfully changed. + عبارت عبور با موفقیت تغییر شد + + + + BitcoinGUI + + + Bitcoin Wallet + پنجره بیتکویین + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + همگام سازی با شبکه ... + + + + &Overview + بررسی اجمالی + + + + Show general overview of wallet + نمای کلی پنجره نشان بده + + + + &Transactions + &amp;معاملات + + + + Browse transaction history + نمایش تاریخ معاملات + + + + &Address Book + دفتر آدرس + + + + Edit the list of stored addresses and labels + ویرایش لیست آدرسها و بر چسب های ذخیره ای + + + + &Receive coins + در یافت سکه + + + + Show the list of addresses for receiving payments + نمایش لیست آدرس ها برای در یافت پر داخت ها + + + + &Send coins + رسال سکه ها + + + + Prove you control an address + اثبات کنید که روی یک نشانی کنترل دارید + + + + E&xit + خروج + + + + Quit application + خروج از برنامه + + + + &About %1 + &حدود%1 + + + + Show information about Bitcoin + نمایش اطلاعات در مورد بیتکویین + + + + About &Qt + درباره &Qt + + + + Show information about Qt + نمایش اطلاعات درباره Qt + + + + &Options... + تنظیمات... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &;صادرات + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + رمز بندی یا رمز گشایی پنجره + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + عبارت عبور رمز گشایی پنجره تغییر کنید + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + فایل + + + + &Settings + تنظیمات + + + + &Help + کمک + + + + Tabs toolbar + نوار ابزار زبانه ها + + + + Actions toolbar + نوار ابزار عملیت + + + + + [testnet] + آزمایش شبکه + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + در صد ارتباطات فعال بیتکویین با شبکه %n + + + + Downloaded %1 blocks of transaction history. + دانلود بلوکهای معملات %1 + + + + %n second(s) ago + %n بعد از چند دقیقه + + + + %n minute(s) ago + %n بعد از چند دقیقه + + + + %n hour(s) ago + %n بعد از چند دقیقه + + + + %n day(s) ago + %n بعد از چند روزز + + + + Up to date + تا تاریخ + + + + Catching up... + ابتلا به بالا + + + + Last received block was generated %1. + خرین بلوک در یافت شده تولید شده بود %1 + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + این معامله از اندازه محدوده بیشتر است. شما می توانید آد را با دستمزد 1% بفرستید که شامل گره معامله شما می باشد و به شبکه های اینترنتی کمک خواهد کردو آیا شما می خواهید این پول پر داخت%1 + + + + Confirm transaction fee + + + + + Sent transaction + معامله ارسال شده + + + + Incoming transaction + معامله در یافت شده + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + تاریخ %1 +مبلغ%2 +نوع %3 +آدرس %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + زمایش شبکهه + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + زمایش شبکه + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + دیسپلی + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + زیر بخش پیش فرض در واسط انتخاب کنید و سکه ها ارسال کنید + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + اصلاح آدرس + + + + &Label + بر چسب + + + + The label associated with this address book entry + بر چسب با دفتر آدرس ورود مرتبط است + + + + &Address + آدرس + + + + The address associated with this address book entry. This can only be modified for sending addresses. + آدرس با دفتر آدرس ورودی مرتبط است. این فقط در مورد آدرسهای ارسال شده است + + + + New receiving address + آدرس در یافت نو + + + + New sending address + آدرس ارسال نو + + + + Edit receiving address + اصلاح آدرس در یافت + + + + Edit sending address + اصلاح آدرس ارسال + + + + The entered address "%1" is already in the address book. + %1آدرس وارد شده دیگر در دفتر آدرس است + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + رمز گشایی پنجره امکان پذیر نیست + + + + New key generation failed. + کلید نسل جدید ناموفق است + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + ستفاده : + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + شروع حد اقل + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + دستمزد&amp;پر داخت معامله + + + + Main + صلی + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + نرخ اختیاری تراکنش هر کیلوبایت که به شما کمک می‌کند اطمینان پیدا کنید که تراکنش‌ها به سرعت پردازش می‌شوند. بیشتر تراکنش‌ها ۱ کیلوبایت هستند. نرخ 0.01 پیشنهاد می‌شود. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + آدرس از دفتر انتخاب کنید + + + + Alt+A + Alt+A + + + + Paste address from clipboard + آدرس از تخته رسم گیره دار پست کنید + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + پیامی را که می‌خواهید امضا کنید در اینجا وارد کنید + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + روی «امضای پیام» کلیک کنید تا امضا را دریافت نمایید + + + + Sign a message to prove you own this address + یک پیام را امضا کنید تا ثابت کنید صاحب این نشانی هستید + + + + &Sign Message + &امضای پیام + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + آدرس بیتکویین وارد کنید (bijvoorbeeld: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + خطا در امضا + + + + %1 is not a valid address. + %1 یک نشانی معتبر نیست. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + کلید خصوصی برای %1 در دسترس نیست. + + + + Sign failed + امضا موفق نبود + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + درگاه با استفاده از + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + اتوماتیک باز کردن بندر بیتکویین در روتر . این فقط در مواردی می باشد که روتر با کمک یو پ ن پ کار می کند + + + + &Connect through SOCKS4 proxy: + ارتباط با توسط + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + وسل به شبکه بیتکویین با توسط + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + درس پروکسی + + + + Port of the proxy (e.g. 1234) + ورت پروکسی + + + + OptionsDialog + + + Options + اصلی + + + + OverviewPage + + + Form + تراز + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + راز: + + + + Number of transactions: + تعداد معامله + + + + Unconfirmed: + تایید نشده + + + + Wallet + + + + + <b>Recent transactions</b> + اخرین معاملات&lt + + + + Your current balance + تزار جاری شما + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + تعداد معاملات که تایید شده ولی هنوز در تزار جاری شما بر شمار نرفته است + + + + Total number of transactions in wallet + تعداد معاملات در صندوق + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + کد QR + + + + Request Payment + درخواست پرداخت + + + + Amount: + مقدار: + + + + BTC + BTC + + + + Label: + برچسب: + + + + Message: + پیام + + + + &Save As... + &ذخیره به عنوان... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + ارسال سکه ها + + + + Send to multiple recipients at once + ارسال چندین در یافت ها فورا + + + + &Add Recipient + + + + + Remove all transaction fields + پاک کردن تمام ستون‌های تراکنش + + + + Clear &All + + + + + Balance: + تزار : + + + + 123.456 BTC + 123.456 بتس + + + + Confirm the send action + عملیت دوم تایید کنید + + + + &Send + &;ارسال + + + + <b>%1</b> to %2 (%3) + (%3) تا <b>%1</b> درصد%2 + + + + Confirm send coins + ارسال سکه ها تایید کنید + + + + Are you sure you want to send %1? + %1شما متماینید که می خواهید 1% ارسال کنید ؟ + + + + and + و + + + + The recepient address is not valid, please recheck. + آدرس در یافت دو باره چک کنید + + + + The amount to pay must be larger than 0. + مبلغ پر داخت باید از 0 بیشتر باشد + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + تراز + + + + A&mount: + A&amp;مبلغ : + + + + Pay &To: + به&amp;پر داخت : + + + + + Enter a label for this address to add it to your address book + برای آدرس بر پسب وارد کنید که در دفتر آدرس اضافه شود + + + + &Label: + & بر چسب + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + آدرس برای ارسال پر داخت (bijvoorbeeld: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + اآدرسن ازدفتر آدرس انتخاب کنید + + + + Alt+A + Alt+A + + + + Paste address from clipboard + آدرس از تخته رسم گیره دار پست کنید + + + + Alt+P + Alt+P + + + + Remove this recipient + بر داشتن این در یافت کننده + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + آدرس بیتکویین وارد کنید (bijvoorbeeld: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + باز کردن 1% بلوک 1%1 + + + + Open until %1 + باز کردن تا%1 + + + + %1/offline? + %1 انلاین نیست + + + + %1/unconfirmed + %1 تایید نشده + + + + %1 confirmations + ایید %1 + + + + <b>Status:</b> + &lt;b&gt;وضعیت :&lt;/b&gt; + + + + , has not been successfully broadcast yet + هنوز با مو فقیت ارسال نشده + + + + , broadcast through %1 node + ارسال توسط گره %1 + + + + , broadcast through %1 nodes + رسال توسط گره های %1 + + + + <b>Date:</b> + &lt;b&gt;تاریخ :&lt;/b&gt + + + + <b>Source:</b> Generated<br> + &lt;b&gt;منبع :&lt;/b&gt; Generated&lt;br&gt + + + + + <b>From:</b> + &lt;b&gt;از:&lt;/b&gt; + + + + unknown + مشخص نیست + + + + + + <b>To:</b> + &lt;b&gt;به :&lt;/b&gt; + + + + (yours, label: + مال شما ، بر چسب( + + + + (yours) + مال شما) ( + + + + + + + <b>Credit:</b> + &lt;b&gt;اعتبار :&lt;/b&gt; + + + + (%1 matures in %2 more blocks) + (%1 )بالغ در بلوک 2% و بیشتر%2 + + + + (not accepted) + قابل قبول نیست ( ) + + + + + + <b>Debit:</b> + &lt;b&gt;مقدار خالص:&lt;/b&gt; + + + + <b>Transaction fee:</b> + &lt;b&gt;پر داخت معامله :&lt;/b&gt; + + + + <b>Net amount:</b> + &lt;b&gt;مبلغ خالص :&lt;/b&gt; + + + + Message: + پیام + + + + Comment: + مورد نظر + + + + Transaction ID: + شماره تراکنش: + + + + 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. + برای ارسال واحد های تولید شده باید 120 بلوک باشند. هنگامی که بلون ایجاد می شود به شبکه ارسال می شود تا در زنجیر بلوکها اضافه شود. و گر نه بلوک به غیر قابول و غیر ارسال عوض می شود. این اتفاقی می افتد وقتی که همزمان گره دیگر در بلوک ایجاد می شود. + + + + TransactionDescDialog + + + Transaction details + جزییات معاملات + + + + This pane shows a detailed description of the transaction + در این قاب شیشه توصیف دقیق معامله نشان می شود + + + + TransactionTableModel + + + Date + تاریخ + + + + Type + نوع + + + + Address + ایل جدا + + + + Amount + مبلغ + + + + Open for %n block(s) + بلوک %n باز شده برای + + + + Open until %1 + از شده تا 1%1 + + + + Offline (%1 confirmations) + افلایین (%1) + + + + Unconfirmed (%1 of %2 confirmations) + تایید نشده (%1/%2) + + + + Confirmed (%1 confirmations) + تایید شده (%1) + + + + Mined balance will be available in %n more blocks + و بیشتر باشند قابل قابول می شود %n تزار اصلی بعد از اینکه بلوکها + + + + This block was not received by any other nodes and will probably not be accepted! + این بلوک از دیگر گره ها در یافت نشده بدین دلیل شاید قابل قابول نیست + + + + Generated but not accepted + تولید شده ولی قبول نشده + + + + Received with + در یافت با : + + + + Received from + دریافتی از + + + + Sent to + ارسال به : + + + + Payment to yourself + پر داخت به خودتان + + + + Mined + استخراج + + + + (n/a) + (کاربرد ندارد) + + + + Transaction status. Hover over this field to show number of confirmations. + وضعیت معالمه . عرصه که تعداد تایید نشان می دهد + + + + Date and time that the transaction was received. + تاریخ و ساعت در یافت معامله + + + + Type of transaction. + نوع معاملات + + + + Destination address of transaction. + آدرس مقصود معاملات + + + + Amount removed from or added to balance. + مبلغ از تزار شما خارج یا وارد شده + + + + TransactionView + + + + All + همه + + + + Today + امروز + + + + This week + این هفته + + + + This month + این ماه + + + + Last month + ماه گذشته + + + + This year + امسال + + + + Range... + محدوده + + + + Received with + در یافت با + + + + Sent to + ارسال به + + + + To yourself + به خودتان + + + + Mined + استخراج + + + + Other + یگر + + + + Enter address or label to search + برای جست‌‌وجو نشانی یا برچسب را وارد کنید + + + + Min amount + حد اقل مبلغ + + + + Copy address + کپی آدرس + + + + Copy label + کپی بر چسب + + + + Copy amount + روگرفت مقدار + + + + Edit label + اصلاح بر چسب + + + + Show transaction details + + + + + Export Transaction Data + صادرات تاریخ معامله + + + + Comma separated file (*.csv) + Comma فایل جدا + + + + Confirmed + تایید شده + + + + Date + تاریخ + + + + Type + نوع + + + + Label + ر چسب + + + + Address + ایل جدا + + + + Amount + مبلغ + + + + ID + آی دی + + + + Error exporting + خطای صادرت + + + + Could not write to file %1. + تا فایل %1 نمی شود نوشت + + + + Range: + >محدوده + + + + to + به + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + آدرس انتخاب شده در سیستم تخته رسم گیره دار کپی کنید + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + ارسال... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + حد اقل رساندن در جای نوار ابزار ها + + + + Show only a tray icon after minimizing the window + نمایش فقط نماد سینی بعد از حد اقل رساندن پنجره + + + + M&inimize on close + + + + + 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. + حد اقل رساندن در جای خروج بر نامه وقتیکه پنجره بسته است.وقتیکه این فعال است برنامه خاموش می شود بعد از انتخاب دستور خاموش در منیو + + + + bitcoin-core + + + Bitcoin version + سخه بیتکویین + + + + Usage: + ستفاده : + + + + Send command to -server or bitcoind + ارسال فرمان به سرور یا باتکویین + + + + List commands + لیست فومان ها + + + + Get help for a command + کمک برای فرمان + + + + Options: + تنظیمات + + + + Specify configuration file (default: bitcoin.conf) + (: bitcoin.confپیش فرض: )فایل تنظیمی خاص + + + + Specify pid file (default: bitcoind.pid) + (bitcoind.pidپیش فرض : ) فایل پید خاص + + + + Generate coins + سکه های تولید شده + + + + Don't generate coins + تولید سکه ها + + + + Specify data directory + دایرکتور اطلاعاتی خاص + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + (میلی ثانیه )فاصله ارتباط خاص + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + برای اتصالات به <port> (پیش‌فرض: 8333 یا تست‌نت: 18333) گوش کنید + + + + Maintain at most <n> connections to peers (default: 125) + حداکثر <n> اتصال با همکاران برقرار داشته باشید (پیش‌فرض: 125) + + + + Connect only to the specified node + ارتباط فقط به گره خاص + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + آستانه برای قطع ارتباط با همکاران بدرفتار (پیش‌فرض: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + مدت زمان به ثانیه برای جلوگیری از همکاران بدرفتار برای اتصال دوباره (پیش‌فرض: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + حداکثر بافر دریافتی در هر اتصال، 1000*<n> (پیش‌فرض: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + حداکثر بافر ارسالی در هر اتصال، 1000*<n> (پیش‌فرض: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + JSON-RPC قابل فرمانها و + + + + Run in the background as a daemon and accept commands + اجرای در پس زمینه به عنوان شبح و قبول فرمان ها + + + + Use the test network + استفاده شبکه آزمایش + + + + Output extra debugging information + اطلاعات اشکال‌زدایی اضافی خروجی + + + + Prepend debug output with timestamp + به خروجی اشکال‌زدایی برچسب زمان بزنید + + + + Send trace/debug info to console instead of debug.log file + اطلاعات ردگیری/اشکال‌زدایی را به جای فایل لاگ اشکال‌زدایی به کنسول بفرستید + + + + Send trace/debug info to debugger + اطلاعات ردگیری/اشکال‌زدایی را به اشکال‌زدا بفرستید + + + + Username for JSON-RPC connections + JSON-RPC شناسه برای ارتباطات + + + + Password for JSON-RPC connections + JSON-RPC عبارت عبور برای ارتباطات + + + + Listen for JSON-RPC connections on <port> (default: 8332) + ( 8332پیش فرض :) &lt;poort&gt; JSON-RPC شنوایی برای ارتباطات + + + + Allow JSON-RPC connections from specified IP address + از آدرس آی پی خاص JSON-RPC قبول ارتباطات + + + + Send commands to node running on <ip> (default: 127.0.0.1) + (127.0.0.1پیش فرض: ) &lt;ip&gt; دادن فرمانها برای استفاده گره ها روی + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + (100پیش فرض:)&lt;n&gt; گذاشتن اندازه کلید روی + + + + Rescan the block chain for missing wallet transactions + اسکان مجدد زنجیر بلوکها برای گم والت معامله + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +( نگاه کنید Bitcoin Wiki در SSLتنظیمات ):SSL گزینه های + + + + Use OpenSSL (https) for JSON-RPC connections + JSON-RPCبرای ارتباطات استفاده کنید OpenSSL (https) + + + + Server certificate file (default: server.cert) + (server.certپیش فرض: )گواهی نامه سرور + + + + Server private key (default: server.pem) + (server.pemپیش فرض: ) کلید خصوصی سرور + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + رمز های قابل قبول( TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + پیام کمکی + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + رمز گشایی دایرکتور داده ها امکان پذیر نیست. شاید بیت کویین در حال فعال می باشد%s + + + + Bitcoin + یت کویین + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + بار گیری آدرس ها + + + + Error loading blkindex.dat + خطا در بارگیری blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + خطا در بارگیری wallet.dat: کیف پول خراب شده است + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + خطا در بارگیری wallet.dat: کیف پول به ویرایش جدیدتری از Biticon نیاز دارد + + + + Wallet needed to be rewritten: restart Bitcoin to complete + سلام + + + + Error loading wallet.dat + خطا در بارگیری wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + خطا ایجاد معامله اشتباه است + + + + Sending... + ارسال... + + + + 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. + خطا . معامله رد شد.این هنگامی که سکه ها در والت شما هنوز ارسال شده اند ولی شما کپی والت استفاده می کنید و سکه ها روی کپی فرستاده شده اند و به عنوان ارسال شنه مشخص نشده اتفاقی می افتد. + + + + Invalid amount + + + + + Insufficient funds + بود جه نا کافی + + + + Loading block index... + بار گیری شاخص بلوک + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + پر داجت برای هر کیلو بیت برای اضافه به معامله ارسال + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + بار گیری والت + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + اسکان مجدد + + + + Done loading + بار گیری انجام شده است + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + هشدار: تاریخ و ساعت کامپیوتر شما چک کنید. اگر ساعت درست نیست بیتکویین مناسب نخواهد کار کرد + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts new file mode 100644 index 0000000..01958e8 --- /dev/null +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -0,0 +1,2499 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + در مورد بیتکویین + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> version + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + + + + + Double-click to edit address or label + + + + + Create a new address + + + + + Copy the currently selected address to the system clipboard + + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + + + + + &Delete + + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + + + + + Comma separated file (*.csv) + + + + + Error exporting + + + + + Could not write to file %1. + + + + + AddressTableModel + + + Label + + + + + Address + + + + + (no label) + + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + + + + + New passphrase + + + + + Repeat new passphrase + + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + + + + + Encrypt wallet + + + + + This operation needs your wallet passphrase to unlock the wallet. + + + + + Unlock wallet + + + + + This operation needs your wallet passphrase to decrypt the wallet. + + + + + Decrypt wallet + + + + + Change passphrase + + + + + Enter the old and new passphrase to the wallet. + + + + + Confirm wallet encryption + + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + + + + + + Wallet encrypted + + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + + + + The supplied passphrases do not match. + + + + + Wallet unlock failed + + + + + + + The passphrase entered for the wallet decryption was incorrect. + + + + + Wallet decryption failed + + + + + Wallet passphrase was succesfully changed. + + + + + BitcoinGUI + + + Bitcoin Wallet + + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + + + + + &Overview + + + + + Show general overview of wallet + + + + + &Transactions + + + + + Browse transaction history + + + + + &Address Book + + + + + Edit the list of stored addresses and labels + + + + + &Receive coins + + + + + Show the list of addresses for receiving payments + + + + + &Send coins + + + + + Prove you control an address + + + + + E&xit + + + + + Quit application + + + + + &About %1 + + + + + Show information about Bitcoin + + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + + + + + &Settings + + + + + &Help + + + + + Tabs toolbar + + + + + Actions toolbar + + + + + + [testnet] + + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + + + + + Downloaded %1 blocks of transaction history. + + + + + %n second(s) ago + + + + + %n minute(s) ago + + + + + %n hour(s) ago + + + + + %n day(s) ago + + + + + Up to date + + + + + Catching up... + + + + + Last received block was generated %1. + + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + + + + + Confirm transaction fee + + + + + Sent transaction + + + + + Incoming transaction + + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + + + + + &Label + + + + + The label associated with this address book entry + + + + + &Address + + + + + The address associated with this address book entry. This can only be modified for sending addresses. + + + + + New receiving address + + + + + New sending address + + + + + Edit receiving address + + + + + Edit sending address + + + + + The entered address "%1" is already in the address book. + + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + + + + + New key generation failed. + + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + + + + + Main + + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + + + &Connect through SOCKS4 proxy: + + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + + + + + Port of the proxy (e.g. 1234) + + + + + OptionsDialog + + + Options + + + + + OverviewPage + + + Form + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + + + + + Number of transactions: + + + + + Unconfirmed: + + + + + Wallet + + + + + <b>Recent transactions</b> + + + + + Your current balance + + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + + + Total number of transactions in wallet + + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + + + + + Send to multiple recipients at once + + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + + + + + 123.456 BTC + + + + + Confirm the send action + + + + + &Send + + + + + <b>%1</b> to %2 (%3) + + + + + Confirm send coins + + + + + Are you sure you want to send %1? + + + + + and + + + + + The recepient address is not valid, please recheck. + + + + + The amount to pay must be larger than 0. + + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + + + + + A&mount: + + + + + Pay &To: + + + + + + Enter a label for this address to add it to your address book + + + + + &Label: + + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose address from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Remove this recipient + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + TransactionDesc + + + Open for %1 blocks + + + + + Open until %1 + + + + + %1/offline? + + + + + %1/unconfirmed + + + + + %1 confirmations + + + + + <b>Status:</b> + + + + + , has not been successfully broadcast yet + + + + + , broadcast through %1 node + + + + + , broadcast through %1 nodes + + + + + <b>Date:</b> + + + + + <b>Source:</b> Generated<br> + + + + + + <b>From:</b> + + + + + unknown + + + + + + + <b>To:</b> + + + + + (yours, label: + + + + + (yours) + + + + + + + + <b>Credit:</b> + + + + + (%1 matures in %2 more blocks) + + + + + (not accepted) + + + + + + + <b>Debit:</b> + + + + + <b>Transaction fee:</b> + + + + + <b>Net amount:</b> + + + + + Message: + + + + + Comment: + + + + + Transaction ID: + + + + + 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. + + + + + TransactionDescDialog + + + Transaction details + + + + + This pane shows a detailed description of the transaction + + + + + TransactionTableModel + + + Date + + + + + Type + + + + + Address + + + + + Amount + + + + + Open for %n block(s) + + + + + Open until %1 + + + + + Offline (%1 confirmations) + + + + + Unconfirmed (%1 of %2 confirmations) + + + + + Confirmed (%1 confirmations) + + + + + Mined balance will be available in %n more blocks + + + + + This block was not received by any other nodes and will probably not be accepted! + + + + + Generated but not accepted + + + + + Received with + + + + + Received from + + + + + Sent to + + + + + Payment to yourself + + + + + Mined + + + + + (n/a) + + + + + Transaction status. Hover over this field to show number of confirmations. + + + + + Date and time that the transaction was received. + + + + + Type of transaction. + + + + + Destination address of transaction. + + + + + Amount removed from or added to balance. + + + + + TransactionView + + + + All + + + + + Today + + + + + This week + + + + + This month + + + + + Last month + + + + + This year + + + + + Range... + + + + + Received with + + + + + Sent to + + + + + To yourself + + + + + Mined + + + + + Other + + + + + Enter address or label to search + + + + + Min amount + + + + + Copy address + + + + + Copy label + + + + + Copy amount + + + + + Edit label + + + + + Show transaction details + + + + + Export Transaction Data + + + + + Comma separated file (*.csv) + + + + + Confirmed + + + + + Date + + + + + Type + + + + + Label + + + + + Address + + + + + Amount + + + + + ID + + + + + Error exporting + + + + + Could not write to file %1. + + + + + Range: + + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + + + + + Show only a tray icon after minimizing the window + + + + + M&inimize on close + + + + + 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. + + + + + bitcoin-core + + + Bitcoin version + + + + + Usage: + + + + + Send command to -server or bitcoind + + + + + List commands + + + + + Get help for a command + + + + + Options: + + + + + Specify configuration file (default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + + + + + Generate coins + + + + + Don't generate coins + + + + + Specify data directory + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + + + + + Run in the background as a daemon and accept commands + + + + + Use the test network + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + + + + + Password for JSON-RPC connections + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + + Use OpenSSL (https) for JSON-RPC connections + + + + + Server certificate file (default: server.cert) + + + + + Server private key (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + + Bitcoin + + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + + + + + Sending... + + + + + 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. + + + + + Invalid amount + + + + + Insufficient funds + + + + + Loading block index... + + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + + + + + Done loading + + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts new file mode 100644 index 0000000..e9fcf50 --- /dev/null +++ b/src/qt/locale/bitcoin_fi.ts @@ -0,0 +1,2520 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Tietoa Bitcoinista + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> versio + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + AddressBookPage + + + Address Book + Osoitekirja + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Nämä ovat sinun Bitcoin-osoitteesi suoritusten vastaanottamiseen. Voit halutessasi antaa kullekin lähettäjälle eri osoitteen, jotta voit seurata kuka sinulle maksaa. + + + + Double-click to edit address or label + Kaksoisnapauta muokataksesi osoitetta tai nimeä + + + + Create a new address + Luo uusi osoite + + + + Copy the currently selected address to the system clipboard + Kopioi valittu osoite leikepöydälle + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Näytä &QR-koodi + + + + Sign a message to prove you own this address + Allekirjoita viesti millä todistat omistavasi tämän osoitteen + + + + &Sign Message + &Allekirjoita viesti + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Poista valittuna oleva osoite listasta. Vain lähettämiseen käytettäviä osoitteita voi poistaa. + + + + &Delete + &Poista + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Vie osoitekirja + + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + + Error exporting + Virhe viedessä osoitekirjaa + + + + Could not write to file %1. + Ei voida kirjoittaa tiedostoon %1. + + + + AddressTableModel + + + Label + Nimi + + + + Address + Osoite + + + + (no label) + (ei nimeä) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Anna tunnuslause + + + + New passphrase + Uusi tunnuslause + + + + Repeat new passphrase + Toista uusi tunnuslause + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Anna lompakolle uusi tunnuslause.<br/>Käytä tunnuslausetta, jossa on ainakin <b>10 satunnaista mekkiä</b> tai <b>kahdeksan sanaa</b>. + + + + Encrypt wallet + Salaa lompakko + + + + This operation needs your wallet passphrase to unlock the wallet. + Tätä toimintoa varten sinun täytyy antaa lompakon tunnuslause sen avaamiseksi. + + + + Unlock wallet + Avaa lompakko + + + + This operation needs your wallet passphrase to decrypt the wallet. + Tätä toimintoa varten sinun täytyy antaa lompakon tunnuslause salauksen purkuun. + + + + Decrypt wallet + Pura lompakon salaus + + + + Change passphrase + Vaihda tunnuslause + + + + Enter the old and new passphrase to the wallet. + Anna vanha ja uusi tunnuslause. + + + + Confirm wallet encryption + Hyväksy lompakon salaus + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + VAROITUS: Mikäli salaat lompakkosi ja unohdat tunnuslauseen, <b>MENETÄT LOMPAKON KOKO SISÄLLÖN</b>! +Tahdotko varmasti salata lompakon? + + + + + Wallet encrypted + Lompakko salattu + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin sulkeutuu lopettaakseen salausprosessin. Muista, että salattu lompakko ei täysin suojaa sitä haittaohjelmien aiheuttamilta varkauksilta. + + + + + Warning: The Caps Lock key is on. + Varoitus: Caps Lock on päällä. + + + + + + + Wallet encryption failed + Lompakon salaus epäonnistui + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Lompakon salaaminen epäonnistui sisäisen virheen vuoksi. Lompakkoa ei salattu. + + + + + The supplied passphrases do not match. + Annetut tunnuslauseet eivät täsmää. + + + + Wallet unlock failed + Lompakon avaaminen epäonnistui. + + + + + + The passphrase entered for the wallet decryption was incorrect. + Annettu tunnuslause oli väärä. + + + + Wallet decryption failed + Lompakon salauksen purku epäonnistui. + + + + Wallet passphrase was succesfully changed. + Lompakon tunnuslause on vaihdettu. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin-lompakko + + + + Sign &message... + + + + + Show/Hide &Bitcoin + Näytä/Kätke &Bitcoin + + + + Synchronizing with network... + Synkronoidaan verkon kanssa... + + + + &Overview + &Yleisnäkymä + + + + Show general overview of wallet + Näyttää kokonaiskatsauksen lompakon tilanteesta + + + + &Transactions + &Rahansiirrot + + + + Browse transaction history + Selaa rahansiirtohistoriaa + + + + &Address Book + &Osoitekirja + + + + Edit the list of stored addresses and labels + Muokkaa tallennettujen nimien ja osoitteiden listaa + + + + &Receive coins + &Vastaanota Bitcoineja + + + + Show the list of addresses for receiving payments + Näytä Bitcoinien vastaanottamiseen käytetyt osoitteet + + + + &Send coins + &Lähetä Bitcoineja + + + + Prove you control an address + Todista että hallitset osoitetta + + + + E&xit + L&opeta + + + + Quit application + Lopeta ohjelma + + + + &About %1 + &Tietoja %1 + + + + Show information about Bitcoin + Näytä tietoa Bitcoin-projektista + + + + About &Qt + Tietoja &Qt + + + + Show information about Qt + Näytä tietoja QT:ta + + + + &Options... + &Asetukset... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + ~%n lohko jäljellä~%n lohkoja jäljellä + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Ladattu %1 / %2 lohkoista rahansiirtohistoriasta (%3% suoritettu). + + + + &Export... + &Vie... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Näytä tai piillota Bitcoin-ikkuna + + + + Export the data in the current tab to a file + Vie auki olevan välilehden tiedot tiedostoon + + + + Encrypt or decrypt wallet + Salaa tai poista salaus lompakosta + + + + Backup wallet to another location + Varmuuskopioi lompakko toiseen sijaintiin + + + + Change the passphrase used for wallet encryption + Vaihda lompakon salaukseen käytettävä tunnuslause + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Tiedosto + + + + &Settings + &Asetukset + + + + &Help + &Apua + + + + Tabs toolbar + Välilehtipalkki + + + + Actions toolbar + Toimintopalkki + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Bitcoin-asiakas + + + + %n active connection(s) to Bitcoin network + %n aktiivinen yhteys Bitcoin-verkkoon%n aktiivista yhteyttä Bitcoin-verkkoon + + + + Downloaded %1 blocks of transaction history. + Ladattu %1 lohkoa rahansiirron historiasta. + + + + %n second(s) ago + %n sekunti sitten%n sekuntia sitten + + + + %n minute(s) ago + %n minuutti sitten%n minuuttia sitten + + + + %n hour(s) ago + %n tunti sitten%n tuntia sitten + + + + %n day(s) ago + %n päivä sitten%n päivää sitten + + + + Up to date + Rahansiirtohistoria on ajan tasalla + + + + Catching up... + Kurotaan kiinni... + + + + Last received block was generated %1. + Viimeisin vastaanotettu lohko tuotettu %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Tämä rahansiirto ylittää kokorajoituksen. Voit siitä huolimatta lähettää sen %1 siirtopalkkion mikä menee solmuille jotka käsittelevät rahansiirtosi tämä auttaa myös verkostoa. Haluatko maksaa siirtopalkkion? + + + + Confirm transaction fee + + + + + Sent transaction + Lähetetyt rahansiirrot + + + + Incoming transaction + Saapuva rahansiirto + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Päivä: %1 +Määrä: %2 +Tyyppi: %3 +Osoite: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Lompakko on <b>salattu</b> ja tällä hetkellä <b>avoinna</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Lompakko on <b>salattu</b> ja tällä hetkellä <b>lukittuna</b> + + + + Backup Wallet + Varmuuskopioi lompakko + + + + Wallet Data (*.dat) + Lompakkodata (*.dat) + + + + Backup Failed + Varmuuskopio epäonnistui + + + + There was an error trying to save the wallet data to the new location. + Virhe tallennettaessa lompakkodataa uuteen sijaintiin. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Näyttö + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Valitse oletus lisämääre mikä näkyy käyttöliittymässä ja kun lähetät kolikoita + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Muokkaa osoitetta + + + + &Label + &Nimi + + + + The label associated with this address book entry + Tähän osoitteeseen liitetty nimi + + + + &Address + &Osoite + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Osoite, joka liittyy tämän osoitekirjan merkintään. Tätä voidaan muuttaa vain lähtevissä osoitteissa. + + + + New receiving address + Uusi vastaanottava osoite + + + + New sending address + Uusi lähettävä osoite + + + + Edit receiving address + Muokkaa vastaanottajan osoitetta + + + + Edit sending address + Muokkaa lähtevää osoitetta + + + + The entered address "%1" is already in the address book. + Osoite "%1" on jo osoitekirjassa. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Lompakkoa ei voitu avata. + + + + New key generation failed. + Uuden avaimen luonti epäonnistui. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Käyttö: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + Set language, for example "de_DE" (default: system locale) + + + + Start minimized + Käynnistä pienennettynä + + + + Show splash screen on startup (default: 1) + Näytä aloitusruutu käynnistettäessä (oletus: 1) + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Maksa rahansiirtopalkkio + + + + Main + Yleiset + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Vapaaehtoinen rahansiirtopalkkio per kB auttaa nopeuttamaan siirtoja. Useimmat rahansiirrot ovat 1 kB. 0.01 palkkio on suositeltava. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Voit allekirjoittaa viestit omalla osoitteellasi todistaaksesi että omistat ne. Ole huolellinen, että et allekirjoita mitään epämääräistä, phishing-hyökkääjät voivat huijata sinua allekirjoittamaan luovuttamalla henkilöllisyytesi. Allekirjoita selvitys täysin yksityiskohtaisesti mihin olet sitoutunut. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Osoite millä viesti allekirjoitetaan (esim. +1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Valitse osoite osoitekirjasta + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Liitä osoite leikepöydältä + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Kirjoita tähän viesti minkä haluat allekirjoittaa + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Klikkaa "Allekirjoita viesti" saadaksesi allekirjoituksen + + + + Sign a message to prove you own this address + Allekirjoita viesti millä todistat omistavasi tämän osoitteen + + + + &Sign Message + &Allekirjoita viesti + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Anna Bitcoin-osoite (esim. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Virhe allekirjoitettaessa + + + + %1 is not a valid address. + %1 ei ole kelvollinen osoite. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Yksityisavain %1 :lle ei ole saatavilla. + + + + Sign failed + Allekirjoittaminen epäonnistui + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Portin uudelleenohjaus &UPnP:llä + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Avaa Bitcoin-asiakasohjelman portti reitittimellä automaattisesti. Tämä toimii vain, jos reitittimesi tukee UPnP:tä ja se on käytössä. + + + + &Connect through SOCKS4 proxy: + &Yhdistä SOCKS4-välityspalvelimen kautta: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Yhdistä Bitcoin-verkkoon SOCKS4-välityspalvelimen kautta (esimerkiksi käyttäessä Tor:ia) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + Välityspalvelimen IP-osoite (esim. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Portti, johon Bitcoin-asiakasohjelma yhdistää (esim. 1234) + + + + OptionsDialog + + + Options + Asetukset + + + + OverviewPage + + + Form + Lomake + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Saldo: + + + + Number of transactions: + Rahansiirtojen lukumäärä: + + + + Unconfirmed: + Vahvistamatta: + + + + Wallet + Lompakko + + + + <b>Recent transactions</b> + <b>Viimeisimmät rahansiirrot</b> + + + + Your current balance + Tililläsi tällä hetkellä olevien Bitcoinien määrä + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Niiden saapuvien rahansiirtojen määrä, joita Bitcoin-verkko ei vielä ole ehtinyt vahvistaa ja siten eivät vielä näy saldossa. + + + + Total number of transactions in wallet + Lompakolla tehtyjen rahansiirtojen yhteismäärä + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + QR-koodi + + + + Request Payment + Vastaanota maksu + + + + Amount: + Määrä: + + + + BTC + BTC + + + + Label: + Tunniste: + + + + Message: + Viesti: + + + + &Save As... + &Tallenna nimellä... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + Tuloksen URI liian pitkä, yritä lyhentää otsikon tekstiä / viestiä. + + + + Save QR Code + + + + + PNG Images (*.png) + PNG kuvat (*png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Lähetä Bitcoineja + + + + Send to multiple recipients at once + Lähetä monelle vastaanottajalle + + + + &Add Recipient + + + + + Remove all transaction fields + Poista kaikki rahansiirtokentät + + + + Clear &All + + + + + Balance: + Saldo: + + + + 123.456 BTC + 123,456 BTC + + + + Confirm the send action + Vahvista lähetys + + + + &Send + &Lähetä + + + + <b>%1</b> to %2 (%3) + <b>%1</b> to %2 (%3) + + + + Confirm send coins + Hyväksy Bitcoinien lähettäminen + + + + Are you sure you want to send %1? + Haluatko varmasti lähettää %1? + + + + and + ja + + + + The recepient address is not valid, please recheck. + Vastaanottajan osoite ei kelpaa, ole hyvä ja tarkista + + + + The amount to pay must be larger than 0. + Maksettavan summan tulee olla suurempi kuin 0 Bitcoinia. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Lomake + + + + A&mount: + M&äärä: + + + + Pay &To: + Maksun saaja: + + + + + Enter a label for this address to add it to your address book + Anna nimi tälle osoitteelle, jos haluat lisätä sen osoitekirjaan + + + + &Label: + &Nimi: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Osoite, johon Bitcoinit lähetetään (esim. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Valitse osoite osoitekirjasta + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Liitä osoite leikepöydältä + + + + Alt+P + Alt+P + + + + Remove this recipient + Poista + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Anna Bitcoin-osoite (esim. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Avoinna %1 lohkolle + + + + Open until %1 + Avoinna %1 asti + + + + %1/offline? + %1/ei linjalla? + + + + %1/unconfirmed + %1/vahvistamaton + + + + %1 confirmations + %1 vahvistusta + + + + <b>Status:</b> + <b>Tila:</b> + + + + , has not been successfully broadcast yet + , ei ole vielä onnistuneesti lähetetty + + + + , broadcast through %1 node + , lähetetään %1 solmun kautta + + + + , broadcast through %1 nodes + , lähetetään %1 solmun kautta + + + + <b>Date:</b> + <b>Päivä:</b> + + + + <b>Source:</b> Generated<br> + <b>Lähde:</b> Generoitu<br> + + + + + <b>From:</b> + <b>Lähettäjä:</b> + + + + unknown + tuntematon + + + + + + <b>To:</b> + <b>Vast. ott.:</b> + + + + (yours, label: + (sinun, tunniste: + + + + (yours) + (sinun) + + + + + + + <b>Credit:</b> + <b>Krediitti:</b> + + + + (%1 matures in %2 more blocks) + (%1 erääntyy %2 useammassa lohkossa) + + + + (not accepted) + (ei hyväksytty) + + + + + + <b>Debit:</b> + <b>Debit:</b> + + + + <b>Transaction fee:</b> + <b>Rahansiirtomaksu:</b> + + + + <b>Net amount:</b> + <b>Nettomäärä:</b> + + + + Message: + Viesti: + + + + Comment: + Kommentti: + + + + Transaction ID: + Rahansiirron ID: + + + + 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. + Luotujen kolikoiden on odotettava 120 lohkoa ennen kuin ne voidaan käyttää. Kun loit tämän lohkon, se lähetettiin verkkoon lisättäväksi lohkoketjuun. Jos se epäonnistuu ketjuun liittymisessä, sen tila muuttuu "ei hyväksytty" eikä sitä voi käyttää. Tätä voi silloin tällöin esiintyä jos toinen solmu luo lohkon muutamia sekunteja omastasi. + + + + TransactionDescDialog + + + Transaction details + Rahansiirron yksityiskohdat + + + + This pane shows a detailed description of the transaction + Tämä ruutu näyttää yksityiskohtaisen tiedon rahansiirrosta + + + + TransactionTableModel + + + Date + Päivämäärä + + + + Type + Laatu + + + + Address + Osoite + + + + Amount + Määrä + + + + Open for %n block(s) + Auki %n lohkolleAuki %n lohkoille + + + + Open until %1 + Avoinna %1 asti + + + + Offline (%1 confirmations) + Ei yhteyttä verkkoon (%1 vahvistusta) + + + + Unconfirmed (%1 of %2 confirmations) + Vahvistamatta (%1/%2 vahvistusta) + + + + Confirmed (%1 confirmations) + Vahvistettu (%1 vahvistusta) + + + + Mined balance will be available in %n more blocks + Louhittu saldo tulee saataville %n lohkossaLouhittu saldo tulee saataville %n lohkossa + + + + This block was not received by any other nodes and will probably not be accepted! + Tätä lohkoa ei vastaanotettu mistään muusta solmusta ja sitä ei mahdollisesti hyväksytä! + + + + Generated but not accepted + Generoitu mutta ei hyväksytty + + + + Received with + Vastaanotettu osoitteella + + + + Received from + Vastaanotettu + + + + Sent to + Saaja + + + + Payment to yourself + Maksu itsellesi + + + + Mined + Louhittu + + + + (n/a) + (ei saatavilla) + + + + Transaction status. Hover over this field to show number of confirmations. + Rahansiirron tila. Siirrä osoitin kentän päälle nähdäksesi vahvistusten lukumäärä. + + + + Date and time that the transaction was received. + Rahansiirron vastaanottamisen päivämäärä ja aika. + + + + Type of transaction. + Rahansiirron laatu. + + + + Destination address of transaction. + Rahansiirron kohteen Bitcoin-osoite + + + + Amount removed from or added to balance. + Saldoon lisätty tai siitä vähennetty määrä. + + + + TransactionView + + + + All + Kaikki + + + + Today + Tänään + + + + This week + Tällä viikolla + + + + This month + Tässä kuussa + + + + Last month + Viime kuussa + + + + This year + Tänä vuonna + + + + Range... + Alue... + + + + Received with + Vastaanotettu osoitteella + + + + Sent to + Saaja + + + + To yourself + Itsellesi + + + + Mined + Louhittu + + + + Other + Muu + + + + Enter address or label to search + Anna etsittävä osoite tai tunniste + + + + Min amount + Minimimäärä + + + + Copy address + Kopioi osoite + + + + Copy label + Kopioi nimi + + + + Copy amount + Kopioi määrä + + + + Edit label + Muokkaa nimeä + + + + Show transaction details + + + + + Export Transaction Data + Vie rahansiirron tiedot + + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + + Confirmed + Vahvistettu + + + + Date + Aika + + + + Type + Laatu + + + + Label + Nimi + + + + Address + Osoite + + + + Amount + Määrä + + + + ID + ID + + + + Error exporting + Virhe tietojen viennissä + + + + Could not write to file %1. + Ei voida kirjoittaa tiedostoon %1. + + + + Range: + Alue: + + + + to + kenelle + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Kopioi valittu osoite leikepöydälle + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Lähetetään... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Pienennä ilmaisinalueelle työkalurivin sijasta + + + + Show only a tray icon after minimizing the window + Näytä ainoastaan pikkukuvake ikkunan pienentämisen jälkeen + + + + M&inimize on close + + + + + 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. + Ikkunaa suljettaessa vain pienentää Bitcoin-ohjelman ikkunan lopettamatta itse ohjelmaa. Kun tämä asetus on valittuna, ohjelman voi sulkea vain valitsemalla Lopeta ohjelman valikosta. + + + + bitcoin-core + + + Bitcoin version + Bitcoinin versio + + + + Usage: + Käyttö: + + + + Send command to -server or bitcoind + Lähetä käsky palvelimelle tai bitcoind:lle + + + + List commands + Lista komennoista + + + + Get help for a command + Hanki apua käskyyn + + + + Options: + Asetukset: + + + + Specify configuration file (default: bitcoin.conf) + Määritä asetustiedosto (oletus: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Määritä pid-tiedosto (oletus: bitcoin.pid) + + + + Generate coins + Generoi kolikoita + + + + Don't generate coins + Älä generoi kolikoita + + + + Specify data directory + Määritä data-hakemisto + + + + Set database cache size in megabytes (default: 25) + Aseta tietokannan välimuistin koko megatavuina (oletus: 25) + + + + Set database disk log size in megabytes (default: 100) + Aseta tietokannan lokitiedoston koko megatavuina (oletus: 100) + + + + Specify connection timeout (in milliseconds) + Määritä yhteyden aikakatkaisu (millisekunneissa) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Kuuntele yhteyksiä portista <port> (oletus: 8333 tai testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Pidä enintään <n> yhteyttä verkkoihin (oletus: 125) + + + + Connect only to the specified node + Muodosta yhteys vain tiettyyn solmuun + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Kynnysarvo aikakatkaisulle heikosti toimiville verkoille (oletus: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Sekuntien määrä, kuinka kauan uudelleenkytkeydytään verkkoihin (oletus: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maksimi verkkoyhteyden vastaanottopuskuri, <n>*1000 tavua (oletus: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maksimi verkkoyhteyden lähetyspuskuri, <n>*1000 tavua (oletus: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Hyväksy merkkipohjaiset- ja JSON-RPC-käskyt + + + + Run in the background as a daemon and accept commands + Aja taustalla daemonina ja hyväksy komennot + + + + Use the test network + Käytä test -verkkoa + + + + Output extra debugging information + Tulosta ylimääräistä debuggaustietoa + + + + Prepend debug output with timestamp + Lisää debuggaustiedon tulostukseen aikaleima + + + + Send trace/debug info to console instead of debug.log file + Lähetä jäljitys/debug-tieto konsoliin, debug.log-tiedoston sijaan + + + + Send trace/debug info to debugger + Lähetä jäljitys/debug-tieto debuggeriin + + + + Username for JSON-RPC connections + Käyttäjätunnus JSON-RPC-yhteyksille + + + + Password for JSON-RPC connections + Salasana JSON-RPC-yhteyksille + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Kuuntele JSON-RPC -yhteyksiä portista <port> (oletus: 8332) + + + + Allow JSON-RPC connections from specified IP address + Salli JSON-RPC yhteydet tietystä ip-osoitteesta + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Lähetä käskyjä solmuun osoitteessa <ip> (oletus: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Suorita käsky kun paras lohko muuttuu (%s cmd on vaihdettu block hashin kanssa) + + + + Upgrade wallet to latest format + Päivitä lompakko uusimpaan formaattiin + + + + Set key pool size to <n> (default: 100) + Aseta avainpoolin koko arvoon <n> (oletus: 100) + + + + Rescan the block chain for missing wallet transactions + Skannaa uudelleen lohkoketju lompakon puuttuvien rahasiirtojen vuoksi + + + + How many blocks to check at startup (default: 2500, 0 = all) + Kuinka monta lohkoa tarkistetaan käynnistettäessä (oletus: 2500, 0 = kaikki) + + + + How thorough the block verification is (0-6, default: 1) + Kuinka tiukka lohkovarmistus on (0-6, oletus: 1) + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + SSL-asetukset: (lisätietoja Bitcoin-Wikistä) + + + + Use OpenSSL (https) for JSON-RPC connections + Käytä OpenSSL:ää (https) JSON-RPC-yhteyksille + + + + Server certificate file (default: server.cert) + Palvelimen sertifikaatti-tiedosto (oletus: server.cert) + + + + Server private key (default: server.pem) + Palvelimen yksityisavain (oletus: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Hyväksyttävä salaus (oletus: +TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + Tämä ohjeviesti + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + En pääse käsiksi data-hakemiston lukitukseen %s. Bitcoin on todennäköisesti jo käynnistetty. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Ladataan osoitteita... + + + + Error loading blkindex.dat + Virhe ladattaessa blkindex.dat-tiedostoa + + + + Error loading wallet.dat: Wallet corrupted + Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Virhe ladattaessa wallet.dat-tiedostoa: Tarvitset uudemman version Bitcoinista + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Lompakko tarvitsee uudelleenkirjoittaa: käynnistä Bitcoin uudelleen + + + + Error loading wallet.dat + Virhe ladattaessa wallet.dat-tiedostoa + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + Virhe: Lompakko on lukittu, rahansiirtoa ei voida luoda + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Virhe: Tämä rahansiirto vaatii rahansiirtopalkkion vähintään %s johtuen sen määrästä, monimutkaisuudesta tai hiljattain vastaanotettujen summien käytöstä + + + + Error: Transaction creation failed + Virhe: Rahansiirron luonti epäonnistui + + + + Sending... + Lähetetään... + + + + 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. + Virhe: Rahansiirto hylättiin. Tämä voi tapahtua jos jotkin bitcoineistasi on jo käytetty, esimerkiksi jos olet käyttänyt kopiota wallet.dat-lompakkotiedostosta ja bitcoinit on merkitty käytetyksi vain kopiossa. + + + + Invalid amount + Virheellinen määrä + + + + Insufficient funds + Lompakon saldo ei riitä + + + + Loading block index... + Ladataan lohkoindeksiä... + + + + Add a node to connect to and attempt to keep the connection open + Linää solmu mihin liittyä pitääksesi yhteyden auki + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + Etsi solmuja käyttäen internet relay chatia (oletus: 0) + + + + Accept connections from outside (default: 1) + Hyväksytään ulkopuoliset yhteydet (oletus: 1) + + + + Find peers using DNS lookup (default: 1) + Etsi solmuja käyttämällä DNS hakua (oletus: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Käytä Plug and Play kartoitusta kuunnellaksesi porttia (oletus: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Käytä Plug and Play kartoitusta kuunnellaksesi porttia (oletus: 0) + + + + Fee per KB to add to transactions you send + Rahansiirtopalkkio per KB lisätään lähettämääsi rahansiirtoon + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Ladataan lompakkoa... + + + + Cannot downgrade wallet + Et voi päivittää lompakkoasi vanhempaan versioon + + + + Cannot initialize keypool + Avainvarastoa ei voi alustaa + + + + Cannot write default address + Oletusosoitetta ei voi kirjoittaa + + + + Rescanning... + Skannataan uudelleen... + + + + Done loading + Lataus on valmis + + + + To use the %s option + Käytä %s optiota + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, sinun täytyy asettaa rpcpassword asetustiedostoon: +%s +On suositeltavaa käyttää seuraavaan satunnaista salasanaa: +rpcuser=bitcoinrpc +rpcpassword=%s +(sinun ei tarvitse muistaa tätä salasanaa) +Jos tiedostoa ei ole, niin luo se ainoastaan omistajan kirjoitusoikeuksin. + + + + + Error + Virhe + + + + An error occured while setting up the RPC port %i for listening: %s + Virhe asetettaessa RCP-porttia %i kuunteluun: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Sinun täytyy asettaa rpcpassword=<password> asetustiedostoon: +%s +Jos tiedostoa ei ole, niin luo se ainoastaan omistajan kirjoitusoikeuksin. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Varoitus: Tarkista, ovatko tietokoneesi päivämäärä ja aika oikein. Mikäli aika on väärin, Bitcoin-ohjelma ei toimi oikein. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts new file mode 100644 index 0000000..03ff69e --- /dev/null +++ b/src/qt/locale/bitcoin_fr.ts @@ -0,0 +1,2520 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + À propos de Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> version + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Développeurs de Bitcoin + +Ce logiciel est en phase expérimentale. + +Distribué sous licence MIT/X11, voir le fichier license.txt ou http://www.opensource.org/licenses/mit-license.php. + +Ce produit comprend des logiciels développés par le projet OpenSSL pour être utilisés dans la boîte à outils OpenSSL (http://www.openssl.org/), un logiciel cryptographique écrit par Eric Young (eay@cryptsoft.com) et un logiciel UPnP écrit par Thomas Bernard. + + + + AddressBookPage + + + Address Book + Options interface utilisateur + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Voici vos adresses Bitcoin qui vous permettent de recevoir des paiements. Vous pouvez donner une adresse différente à chaque expéditeur afin de savoir qui vous paye. + + + + Double-click to edit address or label + Double cliquez afin de modifier l'adresse ou l'étiquette + + + + Create a new address + Créer une nouvelle adresse + + + + Copy the currently selected address to the system clipboard + Signature invalide + + + + &New Address + &Nouvelle adresse + + + + &Copy Address + &Copier l'adresse + + + + Show &QR Code + Afficher le &QR Code + + + + Sign a message to prove you own this address + Signer un message pour prouver que vous détenez cette adresse + + + + &Sign Message + &Signer un message + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Supprimer l'adresse sélectionnée dans la liste. Seules les adresses d'envoi peuvent être supprimées. + + + + &Delete + &Supprimer + + + + Copy &Label + Copier l'é&tiquette + + + + &Edit + &Éditer + + + + Export Address Book Data + Exporter les données du carnet d'adresses + + + + Comma separated file (*.csv) + Valeurs séparées par des virgules (*.csv) + + + + Error exporting + Erreur lors de l'exportation + + + + Could not write to file %1. + Impossible d'écrire sur le fichier %1. + + + + AddressTableModel + + + Label + Étiquette + + + + Address + Adresse + + + + (no label) + (aucune étiquette) + + + + AskPassphraseDialog + + + Passphrase Dialog + Dialogue de phrase de passe + + + + Enter passphrase + Entrez la phrase de passe + + + + New passphrase + Nouvelle phrase de passe + + + + Repeat new passphrase + Répétez la phrase de passe + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Entrez une nouvelle phrase de passe pour le porte-monnaie.<br/>Veuillez utiliser une phrase de <b>10 caractères au hasard ou plus</b> ou bien de <b>huit mots ou plus</b>. + + + + Encrypt wallet + Chiffrer le porte-monnaie + + + + This operation needs your wallet passphrase to unlock the wallet. + Cette opération nécessite votre phrase de passe pour déverrouiller le porte-monnaie. + + + + Unlock wallet + Déverrouiller le porte-monnaie + + + + This operation needs your wallet passphrase to decrypt the wallet. + Cette opération nécessite votre phrase de passe pour décrypter le porte-monnaie. + + + + Decrypt wallet + Décrypter le porte-monnaie + + + + Change passphrase + Changer la phrase de passe + + + + Enter the old and new passphrase to the wallet. + Entrez l’ancienne phrase de passe pour le porte-monnaie ainsi que la nouvelle. + + + + Confirm wallet encryption + Confirmer le chiffrement du porte-monnaie + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ATTENTION : Si vous chiffrez votre porte-monnaie et perdez votre phrase de passe, vous <b>PERDREZ TOUS VOS BITCOINS</b> ! +Êtes-vous sûr de vouloir chiffrer votre porte-monnaie ? + + + + + Wallet encrypted + Porte-monnaie chiffré + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin va à présent se fermer pour terminer la procédure de cryptage. N'oubliez pas que le chiffrement de votre porte-monnaie ne peut pas fournir une protection totale contre le vol par des logiciels malveillants qui infecteraient votre ordinateur. + + + + + Warning: The Caps Lock key is on. + Attention : la touche Verrouiller Maj est activée. + + + + + + + Wallet encryption failed + Le chiffrement du porte-monnaie a échoué + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Le chiffrement du porte-monnaie a échoué en raison d'une erreur interne. Votre porte-monnaie n'a pas été chiffré. + + + + + The supplied passphrases do not match. + Les phrases de passe entrées ne correspondent pas. + + + + Wallet unlock failed + Le déverrouillage du porte-monnaie a échoué + + + + + + The passphrase entered for the wallet decryption was incorrect. + La phrase de passe entrée pour décrypter le porte-monnaie était incorrecte. + + + + Wallet decryption failed + Le décryptage du porte-monnaie a échoué + + + + Wallet passphrase was succesfully changed. + La phrase de passe du porte-monnaie a été modifiée avec succès. + + + + BitcoinGUI + + + Bitcoin Wallet + Porte-monnaie Bitcoin + + + + Sign &message... + Signer le &message... + + + + Show/Hide &Bitcoin + Afficher/Cacher &Bitcoin + + + + Synchronizing with network... + Synchronisation avec le réseau... + + + + &Overview + &Vue d'ensemble + + + + Show general overview of wallet + Affiche une vue d'ensemble du porte-monnaie + + + + &Transactions + &Transactions + + + + Browse transaction history + Permet de parcourir l'historique des transactions + + + + &Address Book + Carnet d'&adresses + + + + Edit the list of stored addresses and labels + Éditer la liste des adresses et des étiquettes stockées + + + + &Receive coins + &Recevoir des pièces + + + + Show the list of addresses for receiving payments + Affiche la liste des adresses pour recevoir des paiements + + + + &Send coins + &Envoyer des pièces + + + + Prove you control an address + Prouver que vous contrôlez une adresse + + + + E&xit + Q&uitter + + + + Quit application + Quitter l'application + + + + &About %1 + &À propos de %1 + + + + Show information about Bitcoin + Afficher des informations à propos de Bitcoin + + + + About &Qt + À propos de &Qt + + + + Show information about Qt + Afficher des informations sur Qt + + + + &Options... + &Options... + + + + &Encrypt Wallet... + &Chiffrer le porte-monnaie... + + + + &Backup Wallet... + &Sauvegarder le porte-monnaie... + + + + &Change Passphrase... + &Modifier la phrase de passe... + + + + ~%n block(s) remaining + ~%n bloc restant~%n blocs restants + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + %1 blocs de l'historique des transactions sur %2 téléchargés (%3% effectué). + + + + &Export... + &Exporter... + + + + Send coins to a Bitcoin address + Envoyer des pièces à une adresse Bitcoin + + + + Modify configuration options for Bitcoin + Modifier les options de configuration de Bitcoin + + + + Show or hide the Bitcoin window + Afficher ou cacher la fenêtre Bitcoin + + + + Export the data in the current tab to a file + Exporter les données de l'onglet courant vers un fichier + + + + Encrypt or decrypt wallet + Chiffrer ou décrypter le porte-monnaie + + + + Backup wallet to another location + Sauvegarder le porte-monnaie à un autre emplacement + + + + Change the passphrase used for wallet encryption + Modifier la phrase de passe utilisée pour le cryptage du porte-monnaie + + + + &Debug window + Fenêtre de &débogage + + + + Open debugging and diagnostic console + Ouvrir une console de débogage et de diagnostic + + + + &Verify message... + &Vérifier le message... + + + + Verify a message signature + Vérifier la signature d'un message + + + + &File + &Fichier + + + + &Settings + &Réglages + + + + &Help + &Aide + + + + Tabs toolbar + Barre d'outils des onglets + + + + Actions toolbar + Barre d'outils des actions + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Client Bitcoin + + + + %n active connection(s) to Bitcoin network + %n connexion active avec le réseau Bitcoin%n connexions actives avec le réseau Bitcoin + + + + Downloaded %1 blocks of transaction history. + %1 blocs de l'historique des transactions téléchargés. + + + + %n second(s) ago + il y a %n secondeil y a %n secondes + + + + %n minute(s) ago + il y a %n minuteil y a %n minutes + + + + %n hour(s) ago + il y a %n heureil y a %n heures + + + + %n day(s) ago + il y a %n jouril y a %n jours + + + + Up to date + À jour + + + + Catching up... + Rattrapage... + + + + Last received block was generated %1. + Le dernier bloc reçu a été généré %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Cette transaction dépasse la limite de taille. Vous pouvez quand même l'envoyer en vous acquittant de frais d'un montant de %1, qui iront aux nœuds qui traiteront la transaction et aideront à soutenir le réseau. Voulez-vous payer les frais ? + + + + Confirm transaction fee + Confirmer les frais de transaction + + + + Sent transaction + Transaction envoyée + + + + Incoming transaction + Transaction entrante + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Date : %1 +Montant : %2 +Type : %3 +Adresse : %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Le porte-monnaie est <b>chiffré</b> et est actuellement <b>déverrouillé</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Le porte-monnaie est <b>chiffré</b> et est actuellement <b>verrouillé</b> + + + + Backup Wallet + Sauvegarder le porte-monnaie + + + + Wallet Data (*.dat) + Données de porte-monnaie (*.dat) + + + + Backup Failed + La sauvegarde a échoué + + + + There was an error trying to save the wallet data to the new location. + Une erreur est survenue lors de l'enregistrement des données de porte-monnaie à un autre emplacement. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + Une erreur fatale est survenue. Bitcoin ne peut plus continuer à fonctionner de façon sûre et va s'arrêter. + + + + ClientModel + + + Network Alert + Alerte réseau + + + + DisplayOptionsPage + + + Display + Affichage + + + + default + par défaut + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + La langue de l'interface utilisateur peut être définie ici. Ce réglage ne sera pris en compte qu'après un redémarrage de Bitcoin. + + + + User Interface &Language: + &Langue de l'interface utilisateur : + + + + &Unit to show amounts in: + &Unité d'affichage des montants : + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Choisissez la sous-unité par défaut pour l'affichage dans l'interface et lors de l'envoi de pièces + + + + &Display addresses in transaction list + &Afficher les adresses sur la liste des transactions + + + + Whether to show Bitcoin addresses in the transaction list + Détermine si les adresses Bitcoin seront affichées sur la liste des transactions + + + + Warning + Attention + + + + This setting will take effect after restarting Bitcoin. + Ce réglage sera pris en compte après un redémarrage de Bitcoin. + + + + EditAddressDialog + + + Edit Address + Éditer l'adresse + + + + &Label + &Étiquette + + + + The label associated with this address book entry + L'étiquette associée à cette entrée du carnet d'adresses + + + + &Address + &Adresse + + + + The address associated with this address book entry. This can only be modified for sending addresses. + L'adresse associée avec cette entrée du carnet d'adresses. Ne peut être modifiée que pour les adresses d'envoi. + + + + New receiving address + Nouvelle adresse de réception + + + + New sending address + Nouvelle adresse d'envoi + + + + Edit receiving address + Éditer l'adresse de réception + + + + Edit sending address + Éditer l'adresse d'envoi + + + + The entered address "%1" is already in the address book. + L'adresse fournie « %1 » est déjà présente dans le carnet d'adresses. + + + + The entered address "%1" is not a valid Bitcoin address. + L'adresse fournie « %1 » n'est pas une adresse Bitcoin valide. + + + + Could not unlock wallet. + Impossible de déverrouiller le porte-monnaie. + + + + New key generation failed. + Échec de la génération de la nouvelle clef. + + + + HelpMessageBox + + + + Bitcoin-Qt + Bitcoin-Qt + + + + version + version + + + + Usage: + Utilisation : + + + + options + options + + + + UI options + Options Interface Utilisateur + + + + Set language, for example "de_DE" (default: system locale) + Définir la langue, par exemple « de_DE » (par défaut : la langue du système) + + + + Start minimized + Démarrer sous forme minimisée + + + + Show splash screen on startup (default: 1) + Afficher l'écran d'accueil au démarrage (par défaut : 1) + + + + MainOptionsPage + + + 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. + Détacher les bases de données des blocs et des adresses lors de la fermeture. Cela permet de les déplacer dans un autre répertoire de données mais ralentit la fermeture. Le porte-monnaie est toujours détaché. + + + + Pay transaction &fee + Payer des &frais de transaction + + + + Main + Principal + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Frais de transaction optionnels par ko qui aident à garantir un traitement rapide des transactions. La plupart des transactions occupent 1 ko. Des frais de 0.01 sont recommandés. + + + + &Start Bitcoin on system login + &Démarrer Bitcoin lors de l'ouverture d'une session + + + + Automatically start Bitcoin after logging in to the system + Démarrer Bitcoin automatiquement après avoir ouvert une session sur l'ordinateur + + + + &Detach databases at shutdown + &Détacher les bases de données lors de la fermeture + + + + MessagePage + + + Sign Message + Signer le message + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Vous pouvez signer des messages avec vos adresses pour prouver que les détenez. Faites attention à ne pas signer quoi que ce soit de vague car des attaques d'hameçonnage peuvent essayer d'obtenir votre identité par votre signature. Ne signez que des déclarations entièrement détaillées et avec lesquelles vous serez d'accord. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + L'adresse avec laquelle le message sera signé ( par ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Choisir une adresse depuis le carnet d'adresses + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Coller une adresse depuis le presse-papiers + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Entrez ici le message que vous désirez signer + + + + Copy the current signature to the system clipboard + Copier la signature actuelle dans le presse-papiers + + + + &Copy Signature + &Copier la signature + + + + Reset all sign message fields + Remettre à zéro tous les champs de signature de message + + + + Clear &All + &Tout nettoyer + + + + Click "Sign Message" to get signature + Cliquez sur « Signer le message » pour obtenir la signature + + + + Sign a message to prove you own this address + Signer le message pour prouver que vous détenez cette adresse + + + + &Sign Message + &Signer le message + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Entrez une adresse Bitcoin (par ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Une erreur est survenue lors de la signature + + + + %1 is not a valid address. + %1 n'est pas une adresse valide. + + + + %1 does not refer to a key. + %1 ne renvoie pas à une clef. + + + + Private key for %1 is not available. + La clef privée pour %1 n'est pas disponible. + + + + Sign failed + Échec de la signature + + + + NetworkOptionsPage + + + Network + Réseau + + + + Map port using &UPnP + Ouvrir le port avec l'&UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Ouvrir le port du client Bitcoin automatiquement sur le routeur. Cela ne fonctionne que si votre routeur supporte l'UPnP et si la fonctionnalité est activée. + + + + &Connect through SOCKS4 proxy: + &Connexion à travers un proxy SOCKS4 : + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Connexion au réseau Bitcoin à travers un proxy SOCKS4 (par ex. lors d'une connexion via Tor) + + + + Proxy &IP: + &IP du proxy : + + + + &Port: + &Port : + + + + IP address of the proxy (e.g. 127.0.0.1) + Adresse IP du proxy (par ex. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Port du proxy (par ex. 1234) + + + + OptionsDialog + + + Options + Options + + + + OverviewPage + + + Form + Formulaire + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + L'information affichée peut être obsolète. Votre porte-monnaie est automatiquement synchronisé avec le réseau Bitcoin lorsque la connexion s'établit, mais ce processus n'est pas encore terminé. + + + + Balance: + Solde : + + + + Number of transactions: + Nombre de transactions : + + + + Unconfirmed: + Non confirmé : + + + + Wallet + Porte-monnaie + + + + <b>Recent transactions</b> + <b>Transactions récentes</b> + + + + Your current balance + Votre solde actuel + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Total des transactions qui doivent encore être confirmées et qui ne sont pas prises en compte pour le solde actuel + + + + Total number of transactions in wallet + Nombre total de transactions dans le porte-monnaie + + + + + out of sync + désynchronisé + + + + QRCodeDialog + + + QR Code Dialog + Dialogue de QR Code + + + + QR Code + QR Code + + + + Request Payment + Demande de paiement + + + + Amount: + Montant : + + + + BTC + BTC + + + + Label: + Étiquette : + + + + Message: + Message : + + + + &Save As... + &Enregistrer sous... + + + + Error encoding URI into QR Code. + Erreur de l'encodage de l'URI dans le QR Code. + + + + Resulting URI too long, try to reduce the text for label / message. + L'URI résultant est trop long, essayez avec un texte d'étiquette ou de message plus court. + + + + Save QR Code + Sauvegarder le QR Code + + + + PNG Images (*.png) + Images PNG (*.png) + + + + RPCConsole + + + Bitcoin debug window + Fenêtre de débogage de Bitcoin + + + + Client name + Nom du client + + + + + + + + + + + + N/A + Indisponible + + + + Client version + Version du client + + + + &Information + &Information + + + + Client + Client + + + + Startup time + Temps de démarrage + + + + Network + Réseau + + + + Number of connections + Nombre de connexions + + + + On testnet + Sur testnet + + + + Block chain + Chaîne de blocs + + + + Current number of blocks + Nombre actuel de blocs + + + + Estimated total blocks + Nombre total estimé de blocs + + + + Last block time + Horodatage du dernier bloc + + + + Debug logfile + Journal de débogage + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + Ouvrir le journal de débogage de Bitcoin depuis le répertoire courant. Cela peut prendre quelques secondes pour les journaux de grande taille. + + + + &Open + &Ouvrir + + + + &Console + &Console + + + + Build date + Date de compilation + + + + Clear console + Nettoyer la console + + + + Welcome to the Bitcoin RPC console. + Bienvenue sur la console RPC de Bitcoin. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Utilisez les touches de curseur pour naviguer dans l'historique et <b>Ctrl-L</b> pour effacer l'écran. + + + + Type <b>help</b> for an overview of available commands. + Tapez <b>help</b> pour afficher une vue générale des commandes disponibles. + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Envoyer des pièces + + + + Send to multiple recipients at once + Envoyer des pièces à plusieurs destinataires à la fois + + + + &Add Recipient + &Ajouter un destinataire + + + + Remove all transaction fields + Enlever tous les champs de transaction + + + + Clear &All + &Tout nettoyer + + + + Balance: + Solde : + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Confirmer l'action d'envoi + + + + &Send + &Envoyer + + + + <b>%1</b> to %2 (%3) + <b>%1</b> à %2 (%3) + + + + Confirm send coins + Confirmer l'envoi des pièces + + + + Are you sure you want to send %1? + Êtes-vous sûr de vouloir envoyer %1 ? + + + + and + et + + + + The recepient address is not valid, please recheck. + L'adresse du destinataire n'est pas valide, veuillez la vérifier. + + + + The amount to pay must be larger than 0. + Le montant à payer doit être supérieur à 0. + + + + The amount exceeds your balance. + Le montant dépasse votre solde. + + + + The total exceeds your balance when the %1 transaction fee is included. + Le montant dépasse votre solde lorsque les frais de transaction de %1 sont inclus. + + + + Duplicate address found, can only send to each address once per send operation. + Adresse dupliquée trouvée, il n'est possible d'envoyer qu'une fois à chaque adresse par opération d'envoi. + + + + Error: Transaction creation failed. + Erreur : échec de la création de la transaction. + + + + 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. + Erreur : la transaction a été rejetée. Cela peut arriver si certaines pièces de votre porte-monnaie ont déjà été dépensées, par exemple si vous avez utilisé une copie de wallet.dat avec laquelle les pièces ont été dépensées mais pas marquées comme telles ici. + + + + SendCoinsEntry + + + Form + Formulaire + + + + A&mount: + &Montant : + + + + Pay &To: + Payer &à : + + + + + Enter a label for this address to add it to your address book + Entrez une étiquette pour cette adresse afin de l'ajouter à votre carnet d'adresses + + + + &Label: + &Étiquette : + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + L'adresse à laquelle le paiement sera envoyé (par ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Choisir une adresse dans le carnet d'adresses + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Coller une adresse depuis le presse-papiers + + + + Alt+P + Alt+P + + + + Remove this recipient + Enlever ce destinataire + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Entrez une adresse Bitcoin (par ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Ouvert pour %1 blocs + + + + Open until %1 + Ouvert jusqu'à %1 + + + + %1/offline? + %1/hors ligne ? + + + + %1/unconfirmed + %1/non confirmée + + + + %1 confirmations + %1 confirmations + + + + <b>Status:</b> + <b>État :</b> + + + + , has not been successfully broadcast yet + , n'a pas encore été diffusée avec succès + + + + , broadcast through %1 node + , diffusée à travers %1 nœud + + + + , broadcast through %1 nodes + , diffusée à travers %1 nœuds + + + + <b>Date:</b> + <b>Date :</b> + + + + <b>Source:</b> Generated<br> + <b>Source :</b> Généré<br> + + + + + <b>From:</b> + <b>De :</b> + + + + unknown + inconnu + + + + + + <b>To:</b> + <b>À :</b> + + + + (yours, label: + (vôtre, étiquette : + + + + (yours) + (vôtre) + + + + + + + <b>Credit:</b> + <b>Crédit : </b> + + + + (%1 matures in %2 more blocks) + (%1 sera considérée comme mûre suite à %2 blocs de plus) + + + + (not accepted) + (pas accepté) + + + + + + <b>Debit:</b> + <b>Débit : </b> + + + + <b>Transaction fee:</b> + <b>Frais de transaction :</b> + + + + <b>Net amount:</b> + <b>Montant net :</b> + + + + Message: + Message : + + + + Comment: + Commentaire : + + + + Transaction ID: + ID de la transaction : + + + + 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. + Les pièces générées doivent attendre 120 blocs avant de pouvoir être dépensées. Lorsque vous avez généré ce bloc, il a été diffusé sur le réseau pour être ajouté à la chaîne des blocs. S'il échoue a intégrer la chaîne, il sera modifié en « pas accepté » et il ne sera pas possible de le dépenser. Cela peut arriver occasionnellement si un autre nœud génère un bloc quelques secondes avant ou après vous. + + + + TransactionDescDialog + + + Transaction details + Détails de la transaction + + + + This pane shows a detailed description of the transaction + Ce panneau affiche une description détaillée de la transaction + + + + TransactionTableModel + + + Date + Date + + + + Type + Type + + + + Address + Adresse + + + + Amount + Montant + + + + Open for %n block(s) + Ouvert pour %n blocOuvert pour %n blocs + + + + Open until %1 + Ouvert jusqu'à %1 + + + + Offline (%1 confirmations) + Hors ligne (%1 confirmations) + + + + Unconfirmed (%1 of %2 confirmations) + Non confirmée (%1 confirmations sur un total de %2) + + + + Confirmed (%1 confirmations) + Confirmée (%1 confirmations) + + + + Mined balance will be available in %n more blocks + Le solde d'extraction (mined) sera disponible dans %n blocLe solde d'extraction (mined) sera disponible dans %n blocs + + + + This block was not received by any other nodes and will probably not be accepted! + Ce bloc n'a été reçu par aucun autre nœud et ne sera probablement pas accepté ! + + + + Generated but not accepted + Généré mais pas accepté + + + + Received with + Reçue avec + + + + Received from + Reçue de + + + + Sent to + Envoyée à + + + + Payment to yourself + Paiement à vous-même + + + + Mined + Extraction + + + + (n/a) + (indisponible) + + + + Transaction status. Hover over this field to show number of confirmations. + État de la transaction. Laissez le pointeur de la souris sur ce champ pour voir le nombre de confirmations. + + + + Date and time that the transaction was received. + Date et heure de réception de la transaction. + + + + Type of transaction. + Type de transaction. + + + + Destination address of transaction. + L'adresse de destination de la transaction. + + + + Amount removed from or added to balance. + Montant ajouté au ou enlevé du solde. + + + + TransactionView + + + + All + Toutes + + + + Today + Aujourd'hui + + + + This week + Cette semaine + + + + This month + Ce mois + + + + Last month + Mois dernier + + + + This year + Cette année + + + + Range... + Intervalle... + + + + Received with + Reçues avec + + + + Sent to + Envoyées à + + + + To yourself + À vous-même + + + + Mined + Extraction + + + + Other + Autres + + + + Enter address or label to search + Entrez une adresse ou une étiquette à rechercher + + + + Min amount + Montant min + + + + Copy address + Copier l'adresse + + + + Copy label + Copier l'étiquette + + + + Copy amount + Copier le montant + + + + Edit label + Éditer l'étiquette + + + + Show transaction details + Afficher les détails de la transaction + + + + Export Transaction Data + Exporter les données des transactions + + + + Comma separated file (*.csv) + Valeurs séparées par des virgules (*.csv) + + + + Confirmed + Confirmée + + + + Date + Date + + + + Type + Type + + + + Label + Étiquette + + + + Address + Adresse + + + + Amount + Montant + + + + ID + ID + + + + Error exporting + Erreur lors de l'exportation + + + + Could not write to file %1. + Impossible d'écrire sur le fichier %1. + + + + Range: + Intervalle : + + + + to + à + + + + VerifyMessageDialog + + + Verify Signed Message + Vérifier le message signé + + + + 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. + Entrez le message et la signature ci-dessous (faites attention à copier correctement les nouvelles lignes, les espacement, tabulations et autre caractères invisibles) pour obtenir l'adresse Bitcoin utilisée pour signer le message. + + + + Verify a message and obtain the Bitcoin address used to sign the message + Vérifier un message et obtenir l'adresse Bitcoin utilisée pour le signer + + + + &Verify Message + &Vérifier le message + + + + Copy the currently selected address to the system clipboard + Copier l'adresse surlignée dans votre presse-papiers + + + + &Copy Address + &Copier l'adresse + + + + Reset all verify message fields + Remettre à zéro tous les champs de vérification de message + + + + Clear &All + &Tout nettoyer + + + + Enter Bitcoin signature + Entrer une signature Bitcoin + + + + Click "Verify Message" to obtain address + Cliquez sur « Vérifier le message » pour obtenir l'adresse + + + + + Invalid Signature + Signature Invalide + + + + The signature could not be decoded. Please check the signature and try again. + La signature n'a pu être décodée. Veuillez la vérifier et réessayer. + + + + The signature did not match the message digest. Please check the signature and try again. + La signature ne correspond pas au hachage du message. Veuillez vérifier la signature et réessayer. + + + + Address not found in address book. + Addresse non trouvée dans l'annuaire. + + + + Address found in address book: %1 + Adresse trouvée dans le carnet d'adresses : %1 + + + + WalletModel + + + Sending... + Envoi en cours... + + + + WindowOptionsPage + + + Window + Fenêtre + + + + &Minimize to the tray instead of the taskbar + &Minimiser dans la barre système au lieu de la barre des tâches + + + + Show only a tray icon after minimizing the window + Montrer uniquement une icône système après minimisation + + + + M&inimize on close + M&inimiser lors de la fermeture + + + + 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. + Minimiser au lieu quitter l'application lorsque la fenêtre est fermée. Lorsque cette option est activée, l'application ne pourra être fermée qu'en sélectionnant Quitter dans le menu déroulant. + + + + bitcoin-core + + + Bitcoin version + Version de Bitcoin + + + + Usage: + Utilisation : + + + + Send command to -server or bitcoind + Envoyer une commande à -server ou à bitcoind + + + + List commands + Lister les commandes + + + + Get help for a command + Obtenir de l'aide pour une commande + + + + Options: + Options : + + + + Specify configuration file (default: bitcoin.conf) + Spécifier le fichier de configuration (par défaut : bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Spécifier le fichier pid (par défaut : bitcoind.pid) + + + + Generate coins + Générer des pièces + + + + Don't generate coins + Ne pas générer de pièces + + + + Specify data directory + Spécifier le répertoire de données + + + + Set database cache size in megabytes (default: 25) + Définir la taille du tampon en mégaoctets (par défaut :25) + + + + Set database disk log size in megabytes (default: 100) + Définir la taille du journal de la base de données sur le disque en mégaoctets (par défaut : 100) + + + + Specify connection timeout (in milliseconds) + Spécifier le délai d'expiration de la connexion (en millisecondes) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Écouter les connexions sur le <port> (par défaut : 8333 ou testnet : 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Garder au plus <n> connexions avec les pairs (par défaut : 125) + + + + Connect only to the specified node + Ne se connecter qu'au nœud spécifié + + + + Connect to a node to retrieve peer addresses, and disconnect + Se connecter à un nœud pour obtenir des adresses de pairs puis se déconnecter + + + + Specify your own public address + Spécifier votre propre adresse publique + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + Se connecter uniquement aux nœuds du réseau <net> (IPv4 ou IPv6) + + + + Try to discover public IP address (default: 1) + Essayer de découvrir l'adresse IP publique (par défaut : 1) + + + + Bind to given address. Use [host]:port notation for IPv6 + Attacher à l'adresse définie. Utilisez la notation [hôte]:port pour l'IPv6 + + + + Threshold for disconnecting misbehaving peers (default: 100) + Seuil de déconnexion des pairs de mauvaise qualité (par défaut : 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Délai en secondes de refus de reconnexion aux pairs de mauvaise qualité (par défaut : 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Tampon maximal de réception par connexion, <n>*1000 octets (par défaut : 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Tampon maximal d'envoi par connexion, <n>*1000 octets (par défaut : 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + Détacher les bases de données des blocs et des adresses. Augmente le délai de fermeture (par défaut : 0) + + + + Accept command line and JSON-RPC commands + Accepter les commandes de JSON-RPC et de la ligne de commande + + + + Run in the background as a daemon and accept commands + Fonctionner en arrière-plan en tant que démon et accepter les commandes + + + + Use the test network + Utiliser le réseau de test + + + + Output extra debugging information + Informations de débogage supplémentaires + + + + Prepend debug output with timestamp + Faire précéder les données de débogage par un horodatage + + + + Send trace/debug info to console instead of debug.log file + Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log + + + + Send trace/debug info to debugger + Envoyer les informations de débogage/trace au débogueur + + + + Username for JSON-RPC connections + Nom d'utilisateur pour les connexions JSON-RPC + + + + Password for JSON-RPC connections + Mot de passe pour les connexions JSON-RPC + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Écouter les connexions JSON-RPC sur le <port> (par défaut : 8332) + + + + Allow JSON-RPC connections from specified IP address + Autoriser les connexions JSON-RPC depuis l'adresse IP spécifiée + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Envoyer des commandes au nœud fonctionnant à <ip> (par défaut : 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Exécuter la commande lorsque le meilleur bloc change (%s est remplacé par le hachage du bloc dans cmd) + + + + Upgrade wallet to latest format + Mettre à jour le format du porte-monnaie + + + + Set key pool size to <n> (default: 100) + Régler la taille de la plage de clefs sur <n> (par défaut : 100) + + + + Rescan the block chain for missing wallet transactions + Réanalyser la chaîne de blocs pour les transactions de porte-monnaie manquantes + + + + How many blocks to check at startup (default: 2500, 0 = all) + Nombre de blocs à tester au démarrage (par défaut : 2500, 0 = tous) + + + + How thorough the block verification is (0-6, default: 1) + Profondeur de la vérification des blocs (0-6, par défaut : 1) + + + + Imports blocks from external blk000?.dat file + Importe des blocs depuis un fichier blk000?.dat externe + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +Options SSL : (cf. le wiki Bitcoin pour les réglages SSL) + + + + Use OpenSSL (https) for JSON-RPC connections + Utiliser OpenSSL (https) pour les connexions JSON-RPC + + + + Server certificate file (default: server.cert) + Fichier de certificat serveur (par défaut : server.cert) + + + + Server private key (default: server.pem) + Clef privée du serveur (par défaut : server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Clefs de chiffrement acceptables (par défaut : TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + Attention : l'espace disque est faible + + + + This help message + Ce message d'aide + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Impossible d'obtenir un verrou sur le répertoire de données %s. Bitcoin fonctionne probablement déjà. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + Impossible de se lier à %s sur cet ordinateur (bind a retourné l'erreur %d, %s) + + + + Connect through socks proxy + Connexion via un proxy socks + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + Sélectionner la version du proxy socks à utiliser (4 ou 5, 5 étant la valeur par défaut) + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + Ne pas utiliser de proxy pour les connexions au réseau <net> (IPv4 ou IPv6) + + + + Allow DNS lookups for -addnode, -seednode and -connect + Autoriser les recherches DNS pour -addnode, -seednode et -connect + + + + Pass DNS requests to (SOCKS5) proxy + Transmettre les requêtes DNS au proxy (SOCKS5) + + + + Loading addresses... + Chargement des adresses... + + + + Error loading blkindex.dat + Erreur lors du chargement de blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Erreur lors du chargement de wallet.dat : porte-monnaie corrompu + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Erreur lors du chargement de wallet.dat : le porte-monnaie nécessite une version plus récente de Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Le porte-monnaie nécessitait une réécriture. Veuillez redémarrer Bitcoin pour terminer l'opération + + + + Error loading wallet.dat + Erreur lors du chargement de wallet.dat + + + + Invalid -proxy address: '%s' + Adresse -proxy invalide : « %s » + + + + Unknown network specified in -noproxy: '%s' + Le réseau spécifié dans -noproxy est inconnu : « %s » + + + + Unknown network specified in -onlynet: '%s' + Réseau inconnu spécifié sur -onlynet : « %s » + + + + Unknown -socks proxy version requested: %i + Version inconnue de proxy -socks demandée : %i + + + + Cannot resolve -bind address: '%s' + Impossible de résoudre l'adresse -bind : « %s » + + + + Not listening on any port + Aucune écoute sur quel port que ce soit + + + + Cannot resolve -externalip address: '%s' + Impossible de résoudre l'adresse -externalip : « %s » + + + + Invalid amount for -paytxfee=<amount>: '%s' + Montant invalide pour -paytxfee=<montant> : « %s » + + + + Error: could not start node + Erreur : le nœud n'a pu être démarré + + + + Error: Wallet locked, unable to create transaction + Erreur : le porte-monnaie est verrouillé, impossible de créer la transaction + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Erreur : cette transaction nécessite des frais de transaction d'au moins %s en raison de son montant, de sa complexité ou parce que des fonds reçus récemment sont utilisés + + + + Error: Transaction creation failed + Erreur : échec de la création de la transaction + + + + Sending... + Envoi en cours... + + + + 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. + Erreur : la transaction a été rejetée. Cela peut arriver si certaines pièces de votre porte-monnaie ont déjà été dépensées, par exemple si vous avez utilisé une copie de wallet.dat et si des pièces ont été dépensées avec cette copie sans être marquées comme telles ici. + + + + Invalid amount + Montant invalide + + + + Insufficient funds + Fonds insuffisants + + + + Loading block index... + Chargement de l'index des blocs... + + + + Add a node to connect to and attempt to keep the connection open + Ajouter un nœud auquel se connecter et tenter de garder la connexion ouverte + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + Impossible de se lier à %s sur cet ordinateur. Bitcoin fonctionne probablement déjà. + + + + Find peers using internet relay chat (default: 0) + Trouver des pairs en utilisant Internet Relay Chat (par défaut : 0) + + + + Accept connections from outside (default: 1) + Accepter les connexions entrantes (par défaut : 1) + + + + Find peers using DNS lookup (default: 1) + Trouver des pairs en utilisant la recherche DNS (par défaut : 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Utiliser Universal Plug and Play pour rediriger le port d'écoute (par défaut : 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Utiliser Universal Plug and Play pour rediriger le port d'écoute (par défaut : 0) + + + + Fee per KB to add to transactions you send + Frais par Ko à ajouter aux transactions que vous enverrez + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + Attention : -paytxfee est réglée sur un montant très élevé. Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction. + + + + Loading wallet... + Chargement du porte-monnaie... + + + + Cannot downgrade wallet + Impossible de revenir à une version antérieure du porte-monnaie + + + + Cannot initialize keypool + Impossible d'initialiser le keypool + + + + Cannot write default address + Impossible d'écrire l'adresse par défaut + + + + Rescanning... + Nouvelle analyse... + + + + Done loading + Chargement terminé + + + + To use the %s option + Pour utiliser l'option %s + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, vous devez établir un mot de passe rpc dans le fichier de configuration : + %s +Il est recommandé d'utiliser le mot de passe aléatoire suivant : +rcpuser=bitcoinrpc +rpcpassword=%s +(vous n'avez pas besoin de mémoriser ce mot de passe) +Si le fichier n'existe pas, créez-le avec les droits de lecture accordés au propriétaire. + + + + + Error + Erreur + + + + An error occured while setting up the RPC port %i for listening: %s + Une erreur est survenue lors de mise en place du port RPC d'écoute %i : %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Vous devez ajouter la ligne rpcpassword=<mot-de-passe> au fichier de configuration : +%s +Si le fichier n'existe pas, créez-le avec les droits de lecture seule accordés au propriétaire. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Attention : veuillez vérifier que l'heure et la date de votre ordinateur sont correctes. Si votre horloge n'est pas à l'heure, Bitcoin ne fonctionnera pas correctement. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts new file mode 100644 index 0000000..e3565d2 --- /dev/null +++ b/src/qt/locale/bitcoin_fr_CA.ts @@ -0,0 +1,2499 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + A propos de Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> version + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + Carnet d'adresses + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Ceux-ci sont vos adresses Bitcoin qui vous permettent de recevoir des paiements. Vous pouvez en donner une différente à chaque expédieur afin de savoir qui vous payent. + + + + Double-click to edit address or label + Double-cliquez afin de modifier l'adress ou l'étiquette + + + + Create a new address + Créer une nouvelle adresse + + + + Copy the currently selected address to the system clipboard + Copier l'adresse surligné a votre presse-papier + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Supprimer l'adresse sélectionnée dans la liste. Seules les adresses d'envoi peuvent être supprimé. + + + + &Delete + &Supprimer + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Exporter les données du carnet d'adresses + + + + Comma separated file (*.csv) + + + + + Error exporting + + + + + Could not write to file %1. + + + + + AddressTableModel + + + Label + + + + + Address + + + + + (no label) + + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + + + + + New passphrase + + + + + Repeat new passphrase + + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + + + + + Encrypt wallet + + + + + This operation needs your wallet passphrase to unlock the wallet. + + + + + Unlock wallet + + + + + This operation needs your wallet passphrase to decrypt the wallet. + + + + + Decrypt wallet + + + + + Change passphrase + + + + + Enter the old and new passphrase to the wallet. + + + + + Confirm wallet encryption + + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + + + + + + Wallet encrypted + + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + + + + The supplied passphrases do not match. + + + + + Wallet unlock failed + + + + + + + The passphrase entered for the wallet decryption was incorrect. + + + + + Wallet decryption failed + + + + + Wallet passphrase was succesfully changed. + + + + + BitcoinGUI + + + Bitcoin Wallet + + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + + + + + &Overview + + + + + Show general overview of wallet + + + + + &Transactions + + + + + Browse transaction history + + + + + &Address Book + + + + + Edit the list of stored addresses and labels + + + + + &Receive coins + + + + + Show the list of addresses for receiving payments + + + + + &Send coins + + + + + Prove you control an address + + + + + E&xit + + + + + Quit application + + + + + &About %1 + + + + + Show information about Bitcoin + + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + + + + + &Settings + + + + + &Help + + + + + Tabs toolbar + + + + + Actions toolbar + + + + + + [testnet] + + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + + + + + Downloaded %1 blocks of transaction history. + + + + + %n second(s) ago + + + + + %n minute(s) ago + + + + + %n hour(s) ago + + + + + %n day(s) ago + + + + + Up to date + + + + + Catching up... + + + + + Last received block was generated %1. + + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + + + + + Confirm transaction fee + + + + + Sent transaction + + + + + Incoming transaction + + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + + + + + &Label + + + + + The label associated with this address book entry + + + + + &Address + + + + + The address associated with this address book entry. This can only be modified for sending addresses. + + + + + New receiving address + + + + + New sending address + + + + + Edit receiving address + + + + + Edit sending address + + + + + The entered address "%1" is already in the address book. + + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + + + + + New key generation failed. + + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + + + + + Main + + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + + + &Connect through SOCKS4 proxy: + + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + + + + + Port of the proxy (e.g. 1234) + + + + + OptionsDialog + + + Options + + + + + OverviewPage + + + Form + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + + + + + Number of transactions: + + + + + Unconfirmed: + + + + + Wallet + + + + + <b>Recent transactions</b> + + + + + Your current balance + + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + + + Total number of transactions in wallet + + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + + + + + Send to multiple recipients at once + + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + + + + + 123.456 BTC + + + + + Confirm the send action + + + + + &Send + + + + + <b>%1</b> to %2 (%3) + + + + + Confirm send coins + + + + + Are you sure you want to send %1? + + + + + and + + + + + The recepient address is not valid, please recheck. + + + + + The amount to pay must be larger than 0. + + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + + + + + A&mount: + + + + + Pay &To: + + + + + + Enter a label for this address to add it to your address book + + + + + &Label: + + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose address from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Remove this recipient + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + TransactionDesc + + + Open for %1 blocks + + + + + Open until %1 + + + + + %1/offline? + + + + + %1/unconfirmed + + + + + %1 confirmations + + + + + <b>Status:</b> + + + + + , has not been successfully broadcast yet + + + + + , broadcast through %1 node + + + + + , broadcast through %1 nodes + + + + + <b>Date:</b> + + + + + <b>Source:</b> Generated<br> + + + + + + <b>From:</b> + + + + + unknown + + + + + + + <b>To:</b> + + + + + (yours, label: + + + + + (yours) + + + + + + + + <b>Credit:</b> + + + + + (%1 matures in %2 more blocks) + + + + + (not accepted) + + + + + + + <b>Debit:</b> + + + + + <b>Transaction fee:</b> + + + + + <b>Net amount:</b> + + + + + Message: + + + + + Comment: + + + + + Transaction ID: + + + + + 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. + + + + + TransactionDescDialog + + + Transaction details + + + + + This pane shows a detailed description of the transaction + + + + + TransactionTableModel + + + Date + + + + + Type + + + + + Address + + + + + Amount + + + + + Open for %n block(s) + + + + + Open until %1 + + + + + Offline (%1 confirmations) + + + + + Unconfirmed (%1 of %2 confirmations) + + + + + Confirmed (%1 confirmations) + + + + + Mined balance will be available in %n more blocks + + + + + This block was not received by any other nodes and will probably not be accepted! + + + + + Generated but not accepted + + + + + Received with + + + + + Received from + + + + + Sent to + + + + + Payment to yourself + + + + + Mined + + + + + (n/a) + + + + + Transaction status. Hover over this field to show number of confirmations. + + + + + Date and time that the transaction was received. + + + + + Type of transaction. + + + + + Destination address of transaction. + + + + + Amount removed from or added to balance. + + + + + TransactionView + + + + All + + + + + Today + + + + + This week + + + + + This month + + + + + Last month + + + + + This year + + + + + Range... + + + + + Received with + + + + + Sent to + + + + + To yourself + + + + + Mined + + + + + Other + + + + + Enter address or label to search + + + + + Min amount + + + + + Copy address + + + + + Copy label + + + + + Copy amount + + + + + Edit label + + + + + Show transaction details + + + + + Export Transaction Data + + + + + Comma separated file (*.csv) + + + + + Confirmed + + + + + Date + + + + + Type + + + + + Label + + + + + Address + + + + + Amount + + + + + ID + + + + + Error exporting + + + + + Could not write to file %1. + + + + + Range: + + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Copier l'adresse surligné a votre presse-papier + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + + + + + Show only a tray icon after minimizing the window + + + + + M&inimize on close + + + + + 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. + + + + + bitcoin-core + + + Bitcoin version + + + + + Usage: + + + + + Send command to -server or bitcoind + + + + + List commands + + + + + Get help for a command + + + + + Options: + + + + + Specify configuration file (default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + + + + + Generate coins + + + + + Don't generate coins + + + + + Specify data directory + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + + + + + Run in the background as a daemon and accept commands + + + + + Use the test network + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + + + + + Password for JSON-RPC connections + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + + Use OpenSSL (https) for JSON-RPC connections + + + + + Server certificate file (default: server.cert) + + + + + Server private key (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + + Bitcoin + + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + + + + + Sending... + + + + + 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. + + + + + Invalid amount + + + + + Insufficient funds + + + + + Loading block index... + + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + + + + + Done loading + + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts new file mode 100644 index 0000000..224bf54 --- /dev/null +++ b/src/qt/locale/bitcoin_he.ts @@ -0,0 +1,2517 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + אודות ביטקוין + + + + <b>Bitcoin</b> version + גרסת <b>ביטקוין</b> + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + זכויות יוצרים © 2009-2012 שמורות למפתחי ביטקוין + +זוהי תוכנה ניסיונית. + +מופץ תחת רישיון תוכנה MIT/X11, ראה את הקובץ המלווה license.txt או http://www.opensource.org/licenses/mit-license.php. + +המוצר הזה כולל תוכנה שפותחה על ידי פרויקט OpenSSL עבור שימוש בערכת הכלים של OpenSSL (http://www.openssl.org/) ובתוכנה קריפטוגרפית שנכתבה על ידי אריק יאנג (eay@cryptsoft.com) ותוכנת UPnP שנכתבה על ידי תומס ברנרד. + + + + AddressBookPage + + + Address Book + פנקס כתובות + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + אלה כתובות הביטקוין שלך עבור קבלת תשלומים. אתה עשוי לרצות לתת כתובת שונה לכל שולח כדי שתוכל לעקוב אחר מי משלם לך. + + + + Double-click to edit address or label + לחץ לחיצה כפולה לערוך כתובת או תוית + + + + Create a new address + יצירת כתובת חדשה + + + + Copy the currently selected address to the system clipboard + העתק את הכתובת המסומנת ללוח העריכה + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + הצג &קוד QR + + + + Sign a message to prove you own this address + חתום על הודעה כדי להוכיח שכתובת זו בבעלותך + + + + &Sign Message + חתום על הו&דעה + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + מחק את הכתובת המסומנת מהרשימה. ניתן למחוק רק כתובות לשליחה. + + + + &Delete + &מחיקה + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + יצוא נתוני פנקס כתובות + + + + Comma separated file (*.csv) + קובץ מופרד בפסיקים (*.csv) + + + + Error exporting + שגיאה ביצוא + + + + Could not write to file %1. + לא מסוגל לכתוב לקובץ %1. + + + + AddressTableModel + + + Label + תוית + + + + Address + כתובת + + + + (no label) + (ללא כתובת) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + הכנס סיסמא + + + + New passphrase + סיסמה חדשה + + + + Repeat new passphrase + חזור על הסיסמה החדשה + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + הכנס את הסיסמה החדשה לארנק. <br/>אנא השתמש בסיסמה המכילה <b>10 תוים אקראיים או יותר</b>, או <b>שמונה מילים או יותר</b>. + + + + Encrypt wallet + הצפנת ארנק + + + + This operation needs your wallet passphrase to unlock the wallet. + הפעולה הזו דורשת את סיסמת הארנק שלך בשביל לפתוח את הארנק. + + + + Unlock wallet + פתיחת ארנק + + + + This operation needs your wallet passphrase to decrypt the wallet. + הפעולה הזו דורשת את סיסמת הארנק שלך בשביל לפענח את הארנק. + + + + Decrypt wallet + פענוח ארנק + + + + Change passphrase + שינוי סיסמה + + + + Enter the old and new passphrase to the wallet. + הכנס את הסיסמות הישנה והחדשה לארנק. + + + + Confirm wallet encryption + אשר הצפנת ארנק + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + אזהרה: אם תצפין את הארנק שלך ותאבד את הסיסמה אתה <b>תאבד את כל הביטקוין שלך</b>! +אתה בטוח שברצונך להצפין את הארנק? + + + + + Wallet encrypted + הארנק הוצפן + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + ביטקוין ייסגר עכשיו כדי להשלים את תהליך ההצפנה. זכור שהצפנת הארנק שלך אינו יכול להגן באופן מלא על הביטקוינים שלך מתוכנות זדוניות המושתלות על המחשב. + + + + + Warning: The Caps Lock key is on. + אזהרה: מקש Caps Lock מופעל. + + + + + + + Wallet encryption failed + הצפנת הארנק נכשלה + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + הצפנת הארנק נכשלה עקב שגיאה פנימית. הארנק שלך לא הוצפן. + + + + + The supplied passphrases do not match. + הסיסמות שניתנו אינן תואמות. + + + + Wallet unlock failed + פתיחת הארנק נכשלה + + + + + + The passphrase entered for the wallet decryption was incorrect. + הסיסמה שהוכנסה לפענוח הארנק שגויה. + + + + Wallet decryption failed + פענוח הארנק נכשל + + + + Wallet passphrase was succesfully changed. + סיסמת הארנק שונתה בהצלחה. + + + + BitcoinGUI + + + Bitcoin Wallet + ארנק ביטקוין + + + + Sign &message... + + + + + Show/Hide &Bitcoin + הצג/הסתר את &ביטקוין + + + + Synchronizing with network... + מסתנכרן עם הרשת... + + + + &Overview + &סקירה + + + + Show general overview of wallet + הצג סקירה כללית של הארנק + + + + &Transactions + &פעולות + + + + Browse transaction history + דפדף בהיסטוריית הפעולות + + + + &Address Book + פנקס &כתובות + + + + Edit the list of stored addresses and labels + ערוך את רשימת הכתובות והתויות + + + + &Receive coins + &קבלת מטבעות + + + + Show the list of addresses for receiving payments + הצג את רשימת הכתובות לקבלת תשלומים + + + + &Send coins + &שלח מטבעות + + + + Prove you control an address + הוכח שאתה שולט בכתובת + + + + E&xit + י&ציאה + + + + Quit application + סגור תוכנה + + + + &About %1 + &אודות %1 + + + + Show information about Bitcoin + הצג מידע על ביטקוין + + + + About &Qt + אודות Qt + + + + Show information about Qt + הצג מידע על Qt + + + + &Options... + &אפשרויות + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + בלוק אחד נותר~%n בלוקים נותרו + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + הורדו %1 בלוקים של היסטוריית פעולות מתוך %2 (הושלם %3% מהסה"כ). + + + + &Export... + י&צא לקובץ + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + הצג או הסתר את חלון ביטקוין. + + + + Export the data in the current tab to a file + יצוא הנתונים בטאב הנוכחי לקובץ + + + + Encrypt or decrypt wallet + הצפן או פענח ארנק + + + + Backup wallet to another location + גיבוי הארנק למקום אחר + + + + Change the passphrase used for wallet encryption + שנה את הסיסמה להצפנת הארנק + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &קובץ + + + + &Settings + ה&גדרות + + + + &Help + &עזרה + + + + Tabs toolbar + סרגל כלים טאבים + + + + Actions toolbar + סרגל כלים פעולות + + + + + [testnet] + [רשת-בדיקה] + + + + + Bitcoin client + תוכנת ביטקוין + + + + %n active connection(s) to Bitcoin network + חיבור פעיל אחד לרשת הביטקוין%n חיבורים פעילים לרשת הביטקוין + + + + Downloaded %1 blocks of transaction history. + הורדו %1 בלוקים של היסטוריית פעולות. + + + + %n second(s) ago + לפני שניהלפני %n שניות + + + + %n minute(s) ago + לפני דקהלפני %n דקות + + + + %n hour(s) ago + לפני שעהלפני %n שעות + + + + %n day(s) ago + לפני יוםלפני %n ימים + + + + Up to date + עדכני + + + + Catching up... + מתעדכן... + + + + Last received block was generated %1. + הבלוק האחרון שהתקבל נוצר ב-%1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + הפעולה הזאת חורגת מהמגבלה. ניתן לשלוח אותה תמורת עמלה בסך %1, שמגיעה לצמתים שמעבדים את הפעולה ועוזרת לתמוך ברשת. האם אתה מעוניין לשלם את העמלה? + + + + Confirm transaction fee + + + + + Sent transaction + פעולה שנשלחה + + + + Incoming transaction + פעולה שהתקבלה + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + תאריך: %1 +כמות: %2 +סוג: %3 +כתובת: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + הארנק <b>מוצפן</b> וכרגע <b>פתוח</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + הארנק <b>מוצפן</b> וכרגע <b>נעול</b> + + + + Backup Wallet + גיבוי ארנק + + + + Wallet Data (*.dat) + נתוני ארנק (*.dat) + + + + Backup Failed + הגיבוי נכשל + + + + There was an error trying to save the wallet data to the new location. + היתה שגיאה בניסיון לשמור את מידע הארנק למיקום החדש. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + תצוגה + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + בחר את יחידת החלוקה להצגה בממשק, ובעת שליחת מטבעות + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + ערוך כתובת + + + + &Label + ת&וית + + + + The label associated with this address book entry + התוית המשויכת לרשומה הזו בפנקס הכתובות + + + + &Address + &כתובת + + + + The address associated with this address book entry. This can only be modified for sending addresses. + הכתובת המשויכת לרשומה זו בפנקס הכתובות. ניתן לשנות זאת רק עבור כתובות לשליחה. + + + + New receiving address + כתובת חדשה לקבלה + + + + New sending address + כתובת חדשה לשליחה + + + + Edit receiving address + ערוך כתובת לקבלה + + + + Edit sending address + ערוך כתובת לשליחה + + + + The entered address "%1" is already in the address book. + הכתובת שהכנסת "%1" כבר נמצאת בפנקס הכתובות. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + פתיחת הארנק נכשלה. + + + + New key generation failed. + יצירת מפתח חדש נכשלה. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + שימוש: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + קבע שפה, למשל "he_il" (ברירת מחדל: שפת המערכת) + + + + Start minimized + התחל ממוזער + + + + Show splash screen on startup (default: 1) + הצג מסך פתיחה בעת הפעלה (ברירת מחדל: 1) + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + שלם &עמלת פעולה + + + + Main + ראשי + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + עמלת פעולה אופציונלית לכל kB תבטיח שהפעולה שלך תעובד בזריזות. רוב הפעולות הן 1 kB. מומלצת עמלה בסך 0.01. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + אתה יכול לחתום על הודעות עם הכתובות שלך כדי להוכיח שהן בבעלותך. היזהר לא לחתום על משהו מעורפל, שכן התקפות פישינג עשויות לגרום לך בעורמה למסור את זהותך. חתום רק על אמרות מפורטות לחלוטין שאתה מסכים עימן. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + הכתובת המשמשת לחתימה על ההודעה (למשל 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + בחר כתובת מפנקס הכתובות + + + + Alt+A + Alt+A + + + + Paste address from clipboard + הדבק כתובת מהלוח + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + הכנס כאן את ההודעה שעליך ברצונך לחתום + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + לחץ על "חתום על הודעה" לקבלת חתימה + + + + Sign a message to prove you own this address + חתום על הודעה כדי להוכיח שכתובת זו בבעלותך + + + + &Sign Message + חתום על הו&דעה + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + הכנס כתובת ביטקוין (למשל 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + שגיאה בחתימה + + + + %1 is not a valid address. + %1 אינה כתובת תקינה. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + המפתח הפרטי עבור %1 אינו זמין. + + + + Sign failed + החתימה נכשלה + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + מיפוי פורט באמצעות UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + פתח את פורט ביטקוין בנתב באופן אוטומטי. עובד רק אם UPnP מאופשר ונתמך ע"י הנתב. + + + + &Connect through SOCKS4 proxy: + התח&בר דרך פרוקסי SOCKS4: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + התחבר לרשת הביטקוין דרך פרוקסי SOCKS4 (למשל, בעת חיבור דרך Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + כתובת האינטרנט של הפרוקסי (למשל 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + הפורט של הפרוקסי (למשל 1234) + + + + OptionsDialog + + + Options + אפשרויות + + + + OverviewPage + + + Form + טופס + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + יתרה: + + + + Number of transactions: + מספר פעולות: + + + + Unconfirmed: + ממתין לאישור: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>פעולות אחרונות</b> + + + + Your current balance + היתרה הנוכחית שלך + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + הסכום הכולל של פעולות שטרם אושרו, ועוד אינן נספרות בחישוב היתרה הנוכחית + + + + Total number of transactions in wallet + המספר הכולל של פעולות בארנק + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + קוד QR + + + + Request Payment + בקש תשלום + + + + Amount: + כמות: + + + + BTC + ביטקוין + + + + Label: + תוית: + + + + Message: + הודעה: + + + + &Save As... + &שמור בשם... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + המזהה המתקבל ארוך מדי, נסה להפחית את הטקסט בתוית / הודעה. + + + + Save QR Code + + + + + PNG Images (*.png) + תמונות PNG (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + שלח מטבעות + + + + Send to multiple recipients at once + שלח למספר מקבלים בו-זמנית + + + + &Add Recipient + + + + + Remove all transaction fields + הסר את כל השדות בפעולה + + + + Clear &All + + + + + Balance: + יתרה: + + + + 123.456 BTC + 123.456 ביטקוין + + + + Confirm the send action + אשר את פעולת השליחה + + + + &Send + &שלח + + + + <b>%1</b> to %2 (%3) + <b>%1</b> ל- %2 (%3) + + + + Confirm send coins + אשר שליחת מטבעות + + + + Are you sure you want to send %1? + האם אתה בטוח שברצונך לשלוח %1? + + + + and + ו- + + + + The recepient address is not valid, please recheck. + כתובת המקבל אינה תקינה, אנא בדוק שנית. + + + + The amount to pay must be larger than 0. + הכמות לשלם חייבת להיות גדולה מ-0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + טופס + + + + A&mount: + כ&מות: + + + + Pay &To: + שלם &ל: + + + + + Enter a label for this address to add it to your address book + הכנס תוית לכתובת הזאת כדי להכניס לפנקס הכתובות + + + + &Label: + ת&וית: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + הכתובת אליה יישלח התשלום (למשל 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + בחר כתובת מפנקס הכתובות + + + + Alt+A + Alt+A + + + + Paste address from clipboard + הדבר כתובת מהלוח + + + + Alt+P + Alt+P + + + + Remove this recipient + הסר את המקבל הזה + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + הכנס כתובת ביטקוין (למשל 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + פתוח למשך %1 בלוקים + + + + Open until %1 + פתוח עד %1 + + + + %1/offline? + %1/לא מחובר? + + + + %1/unconfirmed + %1/ממתין לאישור + + + + %1 confirmations + %1 אישורים + + + + <b>Status:</b> + <b>מצב:</b> + + + + , has not been successfully broadcast yet + , טרם שודר בהצלחה + + + + , broadcast through %1 node + , שודר דרך צומת %1 + + + + , broadcast through %1 nodes + , שודר דרך %1 צמתים + + + + <b>Date:</b> + <b>תאריך:</b> + + + + <b>Source:</b> Generated<br> + <b>מקור:</b> נוצר<br> + + + + + <b>From:</b> + <b>מאת:</b> + + + + unknown + לא ידוע + + + + + + <b>To:</b> + <b>אל:</b> + + + + (yours, label: + (שלך, תוית: + + + + (yours) + (שלך) + + + + + + + <b>Credit:</b> + <b>זיכוי:</b> + + + + (%1 matures in %2 more blocks) + (%1 יבגור עוד %2 בלוקים) + + + + (not accepted) + (לא התקבל) + + + + + + <b>Debit:</b> + <b<חיוב:</b> + + + + <b>Transaction fee:</b> + <b>עמלת פעולה:</b> + + + + <b>Net amount:</b> + <b>כמות נטו:</b> + + + + Message: + הודעה: + + + + Comment: + הערה: + + + + Transaction ID: + מזהה פעולה: + + + + 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. + מטבעות שנוצרו חייבים לחכות 120 בלוקים לפני שניתן לנצל אותם. כשיצרת את הבלוק הזה, הוא שודר לרשת כדי להתווסף לשרשרת הבלוקים. אם הוא אינו מצליח להיכנס לשרשרת, הוא ישתנה ל"לא התקבל" ולא ניתן יהיה לנצל אותו. זה יכול לקרות מדי פעם אם צומת אחר מייצר בלוק בהפרש של מספר שניות מהבלוק שלך. + + + + TransactionDescDialog + + + Transaction details + פרטי הפעולה + + + + This pane shows a detailed description of the transaction + חלונית זו מציגה תיאור מפורט של הפעולה + + + + TransactionTableModel + + + Date + תאריך + + + + Type + סוג + + + + Address + כתובת + + + + Amount + כמות + + + + Open for %n block(s) + פתוח למשך בלוק אחדפתוח למשך %n בלוקים + + + + Open until %1 + פתוח עד %1 + + + + Offline (%1 confirmations) + לא מחובר (%1 אישורים) + + + + Unconfirmed (%1 of %2 confirmations) + ממתין לאישור (%1 מתוך %2 אישורים) + + + + Confirmed (%1 confirmations) + מאושר (%1 אישורים) + + + + Mined balance will be available in %n more blocks + יתרה שנכרתה תהיה זמינה עוד בלוק אחדיתרה שנכרתה תהיה זמינה עוד %n בלוקים + + + + This block was not received by any other nodes and will probably not be accepted! + הבלוק הזה לא נקלט על ידי אף צומת אחר, וכנראה לא יתקבל! + + + + Generated but not accepted + נוצר אך לא התקבל + + + + Received with + התקבל עם + + + + Received from + התקבל מאת + + + + Sent to + נשלח ל + + + + Payment to yourself + תשלום לעצמך + + + + Mined + נכרה + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + מצב הפעולה. השהה את הסמן מעל שדה זה כדי לראות את מספר האישורים. + + + + Date and time that the transaction was received. + התאריך והשעה בה הפעולה הזאת התקבלה. + + + + Type of transaction. + סוג הפעולה. + + + + Destination address of transaction. + כתובת היעד של הפעולה. + + + + Amount removed from or added to balance. + הכמות שהתווספה או הוסרה מהיתרה. + + + + TransactionView + + + + All + הכל + + + + Today + היום + + + + This week + השבוע + + + + This month + החודש + + + + Last month + החודש שעבר + + + + This year + השנה + + + + Range... + טווח... + + + + Received with + התקבל עם + + + + Sent to + נשלח ל + + + + To yourself + לעצמך + + + + Mined + נכרה + + + + Other + אחר + + + + Enter address or label to search + הכנס כתובת או תוית לחפש + + + + Min amount + כמות מזערית + + + + Copy address + העתק כתובת + + + + Copy label + העתק תוית + + + + Copy amount + העתק כמות + + + + Edit label + ערוך תוית + + + + Show transaction details + + + + + Export Transaction Data + יצוא נתוני פעולות + + + + Comma separated file (*.csv) + קובץ מופרד בפסיקים (*.csv) + + + + Confirmed + מאושר + + + + Date + תאריך + + + + Type + סוג + + + + Label + תוית + + + + Address + כתובת + + + + Amount + כמות + + + + ID + מזהה + + + + Error exporting + שגיאה ביצוא + + + + Could not write to file %1. + לא מסוגל לכתוב לקובץ %1. + + + + Range: + טווח: + + + + to + אל + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + העתק את הכתובת שסומנה ללוח המערכת + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + שולח... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + מ&זער למגש במקום לשורת המשימות + + + + Show only a tray icon after minimizing the window + הצג אייקון מגש בלבד לאחר מזעור החלון + + + + M&inimize on close + + + + + 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. + מזער את התוכנה במקום לצאת ממנה כשהחלון נסגר. כשאפשרות זו פעילה, התוכנה תיסגר רק לאחר בחירת יציאה מהתפריט. + + + + bitcoin-core + + + Bitcoin version + גרסת ביטקוין + + + + Usage: + שימוש: + + + + Send command to -server or bitcoind + שלח פקודה ל -server או bitcoind + + + + List commands + רשימת פקודות + + + + Get help for a command + קבל עזרה עבור פקודה + + + + Options: + אפשרויות: + + + + Specify configuration file (default: bitcoin.conf) + ציין קובץ הגדרות (ברירת מחדל: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + ציין קובץ pid (ברירת מחדל: bitcoind.pid) + + + + Generate coins + צור מטבעות + + + + Don't generate coins + אל תייצר מטבעות + + + + Specify data directory + ציין תיקיית נתונים + + + + Set database cache size in megabytes (default: 25) + קבע את גודל המטמון של מסד הנתונים במגהבייט (ברירת מחדל: 25) + + + + Set database disk log size in megabytes (default: 100) + קבע את גודל יומן פעילות מסד הנתונים במגהבייט (ברירת מחדל: 100) + + + + Specify connection timeout (in milliseconds) + ציין הגבלת זמן לחיבור (במילישניות) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + האזן לחיבורים ב<פורט> (ברירת מחדל: 8333 או ברשת הבדיקה: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + החזק לכל היותר <n> חיבורים לעמיתים (ברירת מחדל: 125) + + + + Connect only to the specified node + התחבר רק לצומת המצוין + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + סף להתנתקות מעמיתים הנוהגים שלא כהלכה (ברירת מחדל: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + מספר שניות למנוע מעמיתים הנוהגים שלא כהלכה מלהתחבר מחדש (ברירת מחדל: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + חוצץ מירבי לקבלה לכל חיבור, <n>*1000 בתים (ברירת מחדל: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + חוצץ מירבי לשליחה לכל חיבור, <n>*1000 בתים (ברירת מחדל: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + קבל פקודות משורת הפקודה ו- JSON-RPC + + + + Run in the background as a daemon and accept commands + רוץ ברקע כדימון וקבל פקודות + + + + Use the test network + השתמש ברשת הבדיקה + + + + Output extra debugging information + פלוט מידע דיבאג נוסף + + + + Prepend debug output with timestamp + הוסף חותמת זמן לפני פלט דיבאג + + + + Send trace/debug info to console instead of debug.log file + שלח מידע דיבאג ועקבה לקונסולה במקום לקובץ debug.log + + + + Send trace/debug info to debugger + שלח מידע דיבאג ועקבה לכלי דיבאג + + + + Username for JSON-RPC connections + שם משתמש לחיבורי JSON-RPC + + + + Password for JSON-RPC connections + סיסמה לחיבורי JSON-RPC + + + + Listen for JSON-RPC connections on <port> (default: 8332) + האזן לחיבורי JSON-RPC ב<פורט> (ברירת מחדל: 8332) + + + + Allow JSON-RPC connections from specified IP address + אפשר חיבורי JSON-RPC מכתובת האינטרנט המצוינת + + + + Send commands to node running on <ip> (default: 127.0.0.1) + שלח פקודות לצומת ב-<ip> (ברירת מחדל: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + בצע פקודה זו כשהבלוק הטוב ביותר משתנה (%s בפקודה יוחלף בגיבוב הבלוק) + + + + Upgrade wallet to latest format + שדרג את הארנק לפורמט העדכני + + + + Set key pool size to <n> (default: 100) + קבע את גודל המאגר ל -<n> (ברירת מחדל: 100) + + + + Rescan the block chain for missing wallet transactions + סרוק מחדש את שרשרת הבלוקים למציאת פעולות חסרות בארנק + + + + How many blocks to check at startup (default: 2500, 0 = all) + מספר הבלוקים לבדוק בעת ההפעלה (ברירת מחדל: 2500, 0=כולם) + + + + How thorough the block verification is (0-6, default: 1) + מידת היסודיות של אימות הבלוקים (0-6, ברירת מחדל: 1) + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + אפשרויות SSL: (ראה את הויקי של ביטקוין עבור הוראות להתקנת SSL) + + + + Use OpenSSL (https) for JSON-RPC connections + השתמש ב-OpenSSL (https( עבור חיבורי JSON-RPC + + + + Server certificate file (default: server.cert) + קובץ תעודת שרת (ברירת מחדל: server.cert) + + + + Server private key (default: server.pem) + מפתח פרטי של השרת (ברירת מחדל: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + צפנים קבילים (ברירת מחדל: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + הודעת העזרה הזו + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + אינו מסוגל לנעול את תיקיית הנתונים %s. כנראה שביטקוין כבר רץ. + + + + Bitcoin + ביטקוין + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + טוען כתובות... + + + + Error loading blkindex.dat + שגיאה בטעינת הקובץ blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + שגיאה בטעינת הקובץ wallet.dat: הארנק מושחת + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + שגיאה בטעינת הקובץ wallet.dat: הארנק דורש גרסה חדשה יותר של ביטקוין + + + + Wallet needed to be rewritten: restart Bitcoin to complete + יש לכתוב מחדש את הארנק: אתחל את ביטקוין לסיום + + + + Error loading wallet.dat + שגיאה בטעינת הקובץ wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + שגיאה: הארנק נעול, לא ניתן ליצור פעולה + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + שגיאה: הפעולה דורשת עמלת פעולה של לפחות %s מפאת הכמות, המורכבות, או השימוש בכספים שהתקבלו לאחרונה + + + + Error: Transaction creation failed + שגיאה: יצירת הפעולה נכשלה + + + + Sending... + שולח... + + + + 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. + שגיאה: הפעולה נדחתה. זה עשוי לקרות אם חלק מהמטבעות בארנק שלך כבר נוצלו, למשל אם השתמשת בעותק של הקובץ wallet.dat ומטבעות נוצלו בהעתק אך לא סומנו כמנוצלות כאן. + + + + Invalid amount + כמות לא תקינה + + + + Insufficient funds + אין מספיק כספים + + + + Loading block index... + טוען את אינדקס הבלוקים... + + + + Add a node to connect to and attempt to keep the connection open + הוסף צומת להתחברות ונסה לשמור את החיבור פתוח + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + מצא עמיתים תוך שימוש ב-IRC (ברירת מחדל: 0) + + + + Accept connections from outside (default: 1) + קבל חיבורים מבחוץ (ברירת מחדל: 1) + + + + Find peers using DNS lookup (default: 1) + מצא עמיתים באמצעות בדיקת DNS (ברירת מחדל: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + השתמש ב-UPnP כדי למפות את הפורט להאזנה (ברירת מחדל: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + השתמש ב-UPnP כדי למפות את הפורט להאזנה (ברירת מחדל: 0) + + + + Fee per KB to add to transactions you send + עמלה להוסיף לפעולות שאתה שולח עבור כל KB + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + טוען ארנק... + + + + Cannot downgrade wallet + לא יכול להוריד דרגת הארנק + + + + Cannot initialize keypool + לא יכול לאתחל את מאגר המפתחות + + + + Cannot write default address + לא יכול לכתוב את כתובת ברירת המחדל + + + + Rescanning... + סורק מחדש... + + + + Done loading + טעינה הושלמה + + + + To use the %s option + להשתמש באפשרות %s + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, עליך לקבוע את rpcpassword בקובץ ההגדרות: +%s +מומלץ להשתמש בסיסמה האקראית הבאה: +rpcuser=bitcoinrpc +rpcpassword=%s +(אין צורך לזכור סיסמה זו) +אם הקובץ אינו קיים, צור אותו עם הרשאות קריאה לבעלים בלבד. + + + + Error + שגיאה + + + + An error occured while setting up the RPC port %i for listening: %s + אירעה שגיאה בעת קביעת פורט RPC %i להאזנה: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + עליך לקבוע rpcpassword=yourpassword בקובץ ההגדרות: +%s +אם הקובץ אינו קיים, צור אותו עם הרשאות קריאה לבעלים בלבד. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + אזהרה: אנא בדוק שהתאריך והשעה של המחשב הזה נכונים. אם השעון שלך שגוי ביטקוין לא יפעל כהלכה. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts new file mode 100644 index 0000000..300bbd6 --- /dev/null +++ b/src/qt/locale/bitcoin_hr.ts @@ -0,0 +1,2510 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + O Bitcoinu + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> verzija + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Bitcoin Developers + +Ovo je eksperimentalan softver. + +Djeljen pod MIT/X11 licencom, pogledajte prateću datoteku license.txt ili http://www.opensource.org/licenses/mit-license.php. + +Ovaj proizvod sadrži softver kojeg je razvio OpenSSL Project za korištenje u OpenSSL Toolkit (http://www.openssl.org/) i kriptografski softver kojeg je napisao Eric Young (eay@cryptsoft.com) i UPnP softver kojeg je napisao Thomas Bernard. + + + + AddressBookPage + + + Address Book + Adresar + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Ovo su vaše Bitcoin adrese za primanje isplate. Možda želite dati drukčiju adresu svakom primatelju tako da možete pratiti tko je platio. + + + + Double-click to edit address or label + Dvostruki klik za uređivanje adrese ili oznake + + + + Create a new address + Dodajte novu adresu + + + + Copy the currently selected address to the system clipboard + Kopiraj trenutno odabranu adresu u međuspremnik + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Prikaži &QR Kôd + + + + Sign a message to prove you own this address + Potpišite poruku kako bi dokazali da posjedujete ovu adresu + + + + &Sign Message + &Potpišite poruku + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Brisanje trenutno odabrane adrese s popisa. Samo adrese za slanje se mogu izbrisati. + + + + &Delete + &Brisanje + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Izvoz podataka adresara + + + + Comma separated file (*.csv) + Datoteka vrijednosti odvojenih zarezom (*. csv) + + + + Error exporting + Pogreška kod izvoza + + + + Could not write to file %1. + Ne mogu pisati u datoteku %1. + + + + AddressTableModel + + + Label + Oznaka + + + + Address + Adresa + + + + (no label) + (bez oznake) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Unesite lozinku + + + + New passphrase + Nova lozinka + + + + Repeat new passphrase + Ponovite novu lozinku + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Unesite novi lozinku za novčanik. <br/> Molimo Vas da koristite zaporku od <b>10 ili više slučajnih znakova,</b> ili <b>osam ili više riječi.</b> + + + + Encrypt wallet + Šifriranje novčanika + + + + This operation needs your wallet passphrase to unlock the wallet. + Ova operacija treba lozinku vašeg novčanika kako bi se novčanik otključao. + + + + Unlock wallet + Otključaj novčanik + + + + This operation needs your wallet passphrase to decrypt the wallet. + Ova operacija treba lozinku vašeg novčanika kako bi se novčanik dešifrirao. + + + + Decrypt wallet + Dešifriranje novčanika. + + + + Change passphrase + Promjena lozinke + + + + Enter the old and new passphrase to the wallet. + Unesite staru i novu lozinku za novčanik. + + + + Confirm wallet encryption + Potvrdi šifriranje novčanika + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + UPOZORENJE: Ako šifrirate vaš novčanik i izgubite lozinku, <b>IZGUBIT ĆETE SVE SVOJE BITCOINSE!</b> +Jeste li sigurni da želite šifrirati svoj novčanik? + + + + + Wallet encrypted + Novčanik šifriran + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin će se sada zatvoriti kako bi dovršio postupak šifriranja. Zapamtite da šifriranje vašeg novčanika ne može u potpunosti zaštititi vaše bitcoine od krađe preko zloćudnog softvera koji bi bio na vašem računalu. + + + + + Warning: The Caps Lock key is on. + Upozorenje: Tipka Caps Lock je upaljena. + + + + + + + Wallet encryption failed + Šifriranje novčanika nije uspjelo + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Šifriranje novčanika nije uspjelo zbog interne pogreške. Vaš novčanik nije šifriran. + + + + + The supplied passphrases do not match. + Priložene lozinke se ne podudaraju. + + + + Wallet unlock failed + Otključavanje novčanika nije uspjelo + + + + + + The passphrase entered for the wallet decryption was incorrect. + Lozinka za dešifriranje novčanika nije točna. + + + + Wallet decryption failed + Dešifriranje novčanika nije uspjelo + + + + Wallet passphrase was succesfully changed. + Lozinka novčanika je uspješno promijenjena. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin novčanik + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Usklađivanje s mrežom ... + + + + &Overview + &Pregled + + + + Show general overview of wallet + Prikaži opći pregled novčanika + + + + &Transactions + &Transakcije + + + + Browse transaction history + Pretraži povijest transakcija + + + + &Address Book + &Adresar + + + + Edit the list of stored addresses and labels + Uređivanje popisa pohranjenih adresa i oznaka + + + + &Receive coins + &Primanje novca + + + + Show the list of addresses for receiving payments + Prikaži popis adresa za primanje isplate + + + + &Send coins + &Slanje novca + + + + Prove you control an address + Dokažite da posjedujete adresu + + + + E&xit + &Izlaz + + + + Quit application + Izlazak iz programa + + + + &About %1 + &Više o %1 + + + + Show information about Bitcoin + Prikaži informacije o Bitcoinu + + + + About &Qt + Više o &Qt + + + + Show information about Qt + Prikaži informacije o Qt + + + + &Options... + &Postavke + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Izvoz... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + Izvoz podataka iz trenutnog taba u datoteku + + + + Encrypt or decrypt wallet + Šifriranje ili dešifriranje novčanika + + + + Backup wallet to another location + Napravite sigurnosnu kopiju novčanika na drugoj lokaciji + + + + Change the passphrase used for wallet encryption + Promijenite lozinku za šifriranje novčanika + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Datoteka + + + + &Settings + &Konfiguracija + + + + &Help + &Pomoć + + + + Tabs toolbar + Traka kartica + + + + Actions toolbar + Traka akcija + + + + + [testnet] + [testnet] + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + %n aktivna veza na Bitcoin mrežu%n aktivne veze na Bitcoin mrežu%n aktivnih veza na Bitcoin mrežu + + + + Downloaded %1 blocks of transaction history. + Preuzeto %1 blokova povijesti transakcije. + + + + %n second(s) ago + prije %n sekundeprije %n sekundeprije %n sekundi + + + + %n minute(s) ago + prije %n minuteprije %n minuteprije %n minuta + + + + %n hour(s) ago + prije %n sataprije %n sataprije %n sati + + + + %n day(s) ago + prije %n danaprije %n danaprije %n dana + + + + Up to date + Ažurno + + + + Catching up... + Ažuriranje... + + + + Last received block was generated %1. + Zadnji primljeni blok je generiran %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Ova transakcija je preko ograničenja veličine. Možete ju ipak poslati za naknadu od %1, koja se daje čvorovima koji procesiraju vaše transakcije i tako podržavate mrežu. Želite li platiti naknadu? + + + + Confirm transaction fee + + + + + Sent transaction + Poslana transakcija + + + + Incoming transaction + Dolazna transakcija + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Datum:%1 +Iznos:%2 +Tip:%3 +Adresa:%4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Novčanik je <b>šifriran</b> i trenutno <b>otključan</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Novčanik je <b>šifriran</b> i trenutno <b>zaključan</b> + + + + Backup Wallet + Backup novčanika + + + + Wallet Data (*.dat) + Podaci novčanika (*.dat) + + + + Backup Failed + Backup nije uspio + + + + There was an error trying to save the wallet data to the new location. + Došlo je do pogreške kod spremanja podataka novčanika na novu lokaciju. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Prikaz + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Izaberite željeni najmanji dio bitcoina koji će biti prikazan u sučelju i koji će se koristiti za plaćanje. + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Izmjeni adresu + + + + &Label + &Oznaka + + + + The label associated with this address book entry + Oznaka ovog upisa u adresar + + + + &Address + &Adresa + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Adresa ovog upisa u adresar. Može se mjenjati samo kod adresa za slanje. + + + + New receiving address + Nova adresa za primanje + + + + New sending address + Nova adresa za slanje + + + + Edit receiving address + Uredi adresu za primanje + + + + Edit sending address + Uredi adresu za slanje + + + + The entered address "%1" is already in the address book. + Upisana adresa "%1" je već u adresaru. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Ne mogu otključati novčanik. + + + + New key generation failed. + Stvaranje novog ključa nije uspjelo. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Upotreba: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + Pokreni minimiziran + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Plati &naknadu za transakciju + + + + Main + Glavno + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Neobavezna naknada za transakciju po kB koja omogućuje da se vaša transakcija obavi brže. Većina transakcija ima 1 kB. Preporučena naknada je 0.01. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Možete potpisati poruke sa svojom adresom kako bi dokazali da ih posjedujete. Budite oprezni da ne potpisujete ništa mutno, jer bi vas phishing napadi mogli na prevaru natjerati da prepišete svoj identitet njima. Potpisujte samo detaljno objašnjene izjave sa kojima se slažete. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + Odaberite adresu iz adresara + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Zalijepi adresu iz međuspremnika + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Upišite poruku koju želite potpisati ovdje + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Kliknite "Potpiši poruku" za potpis + + + + Sign a message to prove you own this address + Potpišite poruku kako bi dokazali da posjedujete ovu adresu + + + + &Sign Message + &Potpišite poruku + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Unesite Bitcoin adresu (npr. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Greška u potpisivanju + + + + %1 is not a valid address. + Upisana adresa "%1" nije valjana bitcoin adresa. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Privatni ključ za %1 nije dostupan. + + + + Sign failed + Potpis nije uspio + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Mapiraj port koristeći &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Automatski otvori port Bitcoin klijenta na ruteru. To radi samo ako ruter podržava UPnP i ako je omogućen. + + + + &Connect through SOCKS4 proxy: + &Povezivanje putem SOCKS4 proxy-a: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Spojite se na Bitcon mrežu putem SOCKS4 proxy-a (npr. kod povezivanja kroz Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + IP adresa proxy-a (npr. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Port od proxy-a (npr. 1234) + + + + OptionsDialog + + + Options + Postavke + + + + OverviewPage + + + Form + Oblik + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Stanje: + + + + Number of transactions: + Broj transakcija: + + + + Unconfirmed: + Nepotvrđene: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Nedavne transakcije</b> + + + + Your current balance + Vaše trenutno stanje računa + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Ukupni iznos transakcija koje tek trebaju biti potvrđene, i još uvijek nisu uračunate u trenutni saldo + + + + Total number of transactions in wallet + Ukupni broj tansakcija u novčaniku + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + QR kôd + + + + Request Payment + Zatraži plaćanje + + + + Amount: + Iznos: + + + + BTC + BTC + + + + Label: + Oznaka + + + + Message: + Poruka: + + + + &Save As... + &Spremi kao... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + PNG slike (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Slanje novca + + + + Send to multiple recipients at once + Pošalji k nekoliko primatelja odjednom + + + + &Add Recipient + + + + + Remove all transaction fields + Obriši sva polja transakcija + + + + Clear &All + + + + + Balance: + Stanje: + + + + 123.456 BTC + 123,456 BTC + + + + Confirm the send action + Potvrdi akciju slanja + + + + &Send + &Pošalji + + + + <b>%1</b> to %2 (%3) + <b>%1</b> do %2 (%3) + + + + Confirm send coins + Potvrdi slanje novca + + + + Are you sure you want to send %1? + Jeste li sigurni da želite poslati %1? + + + + and + i + + + + The recepient address is not valid, please recheck. + Adresa primatelja je nevaljala, molimo provjerite je ponovo. + + + + The amount to pay must be larger than 0. + Iznos mora biti veći od 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Oblik + + + + A&mount: + &Iznos: + + + + Pay &To: + &Primatelj plaćanja: + + + + + Enter a label for this address to add it to your address book + Unesite oznaku za ovu adresu kako bi ju dodali u vaš adresar + + + + &Label: + &Oznaka: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adresa za slanje plaćanja (npr. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Odaberite adresu iz adresara + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Zalijepi adresu iz međuspremnika + + + + Alt+P + Alt+P + + + + Remove this recipient + Ukloni ovog primatelja + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Unesite Bitcoin adresu (npr. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Otvori za %1 blokova + + + + Open until %1 + Otvoren do %1 + + + + %1/offline? + %1 nije dostupan? + + + + %1/unconfirmed + %1/nepotvrđeno + + + + %1 confirmations + %1 potvrda + + + + <b>Status:</b> + <b>Status:</b> + + + + , has not been successfully broadcast yet + , još nije bio uspješno emitiran + + + + , broadcast through %1 node + , emitiran kroz nod %1 + + + + , broadcast through %1 nodes + , emitiran kroz nodove %1 + + + + <b>Date:</b> + <b>Datum:</b> + + + + <b>Source:</b> Generated<br> + <b>Izvor:</b> Generirano<br> + + + + + <b>From:</b> + <b>Od:</b> + + + + unknown + nepoznato + + + + + + <b>To:</b> + <b>Za:</b> + + + + (yours, label: + (tvoje, oznaka: + + + + (yours) + (tvoje) + + + + + + + <b>Credit:</b> + <b>Uplaćeno:</b> + + + + (%1 matures in %2 more blocks) + (%1 stasava za %2 dodatna bloka) + + + + (not accepted) + (Nije prihvaćeno) + + + + + + <b>Debit:</b> + <b>Potrošeno:</b> + + + + <b>Transaction fee:</b> + <b>Naknada za transakciju:</b> + + + + <b>Net amount:</b> + <b>Neto iznos:</b> + + + + Message: + Poruka: + + + + Comment: + Komentar: + + + + Transaction ID: + ID transakcije: + + + + 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. + Generirani novčići moraju pričekati nastanak 120 blokova prije nego što ih je moguće potrošiti. Kad ste generirali taj blok, on je bio emitiran u mrežu kako bi bio dodan postojećim lancima blokova. Ako ne uspije biti dodan, njegov status bit će promijenjen u "nije prihvaćen" i on neće biti potrošiv. S vremena na vrijeme tako nešto se može desiti ako neki drugi nod generira blok u približno isto vrijeme. + + + + TransactionDescDialog + + + Transaction details + Detalji transakcije + + + + This pane shows a detailed description of the transaction + Ova panela prikazuje detaljni opis transakcije + + + + TransactionTableModel + + + Date + Datum + + + + Type + Tip + + + + Address + Adresa + + + + Amount + Iznos + + + + Open for %n block(s) + Otvoren za %n blokaOtvoren za %n blokovaOtvoren za %n blokova + + + + Open until %1 + Otvoren do %1 + + + + Offline (%1 confirmations) + Nije na mreži (%1 potvrda) + + + + Unconfirmed (%1 of %2 confirmations) + Nepotvrđen (%1 od %2 potvrda) + + + + Confirmed (%1 confirmations) + Potvrđen (%1 potvrda) + + + + Mined balance will be available in %n more blocks + Saldo iskovanih novčićća bit de dostupan nakon %n dodatnog blokaSaldo iskovanih novčićća bit de dostupan nakon %n dodatnih blokovaSaldo iskovanih novčićća bit de dostupan nakon %n dodatnih blokova + + + + This block was not received by any other nodes and will probably not be accepted! + Generirano - Upozorenje: ovaj blok nije bio primljen od strane bilo kojeg drugog noda i vjerojatno neće biti prihvaćen! + + + + Generated but not accepted + Generirano, ali nije prihvaćeno + + + + Received with + Primljeno s + + + + Received from + Primljeno od + + + + Sent to + Poslano za + + + + Payment to yourself + Plaćanje samom sebi + + + + Mined + Rudareno + + + + (n/a) + (n/d) + + + + Transaction status. Hover over this field to show number of confirmations. + Status transakcije + + + + Date and time that the transaction was received. + Datum i vrijeme kad je transakcija primljena + + + + Type of transaction. + Vrsta transakcije. + + + + Destination address of transaction. + Odredište transakcije + + + + Amount removed from or added to balance. + Iznos odbijen od ili dodan k saldu. + + + + TransactionView + + + + All + Sve + + + + Today + Danas + + + + This week + Ovaj tjedan + + + + This month + Ovaj mjesec + + + + Last month + Prošli mjesec + + + + This year + Ove godine + + + + Range... + Raspon... + + + + Received with + Primljeno s + + + + Sent to + Poslano za + + + + To yourself + Tebi + + + + Mined + Rudareno + + + + Other + Ostalo + + + + Enter address or label to search + Unesite adresu ili oznaku za pretraživanje + + + + Min amount + Min iznos + + + + Copy address + Kopirati adresu + + + + Copy label + Kopirati oznaku + + + + Copy amount + Kopiraj iznos + + + + Edit label + Izmjeniti oznaku + + + + Show transaction details + + + + + Export Transaction Data + Izvoz podataka transakcija + + + + Comma separated file (*.csv) + Datoteka podataka odvojenih zarezima (*.csv) + + + + Confirmed + Potvrđeno + + + + Date + Datum + + + + Type + Tip + + + + Label + Oznaka + + + + Address + Adresa + + + + Amount + Iznos + + + + ID + ID + + + + Error exporting + Izvoz pogreške + + + + Could not write to file %1. + Ne mogu pisati u datoteku %1. + + + + Range: + Raspon: + + + + to + za + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Kopiraj trenutno odabranu adresu u međuspremnik + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Slanje... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Minimiziraj u sistemsku traku umjesto u traku programa + + + + Show only a tray icon after minimizing the window + Prikaži samo ikonu u sistemskoj traci nakon minimiziranja prozora + + + + M&inimize on close + + + + + 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. + Minimizirati umjesto izaći iz aplikacije kada je prozor zatvoren. Kada je ova opcija omogućena, aplikacija će biti zatvorena tek nakon odabira Izlaz u izborniku. + + + + bitcoin-core + + + Bitcoin version + Bitcoin verzija + + + + Usage: + Upotreba: + + + + Send command to -server or bitcoind + Pošalji komandu usluzi -server ili bitcoind + + + + List commands + Prikaži komande + + + + Get help for a command + Potraži pomoć za komandu + + + + Options: + Postavke: + + + + Specify configuration file (default: bitcoin.conf) + Odredi konfiguracijsku datoteku (ugrađeni izbor: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Odredi proces ID datoteku (ugrađeni izbor: bitcoin.pid) + + + + Generate coins + Generiraj novčiće + + + + Don't generate coins + Ne generiraj novčiće + + + + Specify data directory + Odredi direktorij za datoteke + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Odredi vremenski prozor za spajanje na mrežu (u milisekundama) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Slušaj na <port>u (default: 8333 ili testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Održavaj najviše <n> veza sa članovima (default: 125) + + + + Connect only to the specified node + Poveži se samo sa određenim nodom + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Prag za odspajanje članova koji se čudno ponašaju (default: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Broj sekundi koliko se članovima koji se čudno ponašaju neće dopustiti da se opet spoje (default: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maksimalni buffer za primanje po vezi, <n>*1000 bajta (default: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maksimalni buffer za slanje po vezi, <n>*1000 bajta (default: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Prihvati komande iz tekst moda i JSON-RPC + + + + Run in the background as a daemon and accept commands + Izvršavaj u pozadini kao uslužnik i prihvaćaj komande + + + + Use the test network + Koristi test mrežu + + + + Output extra debugging information + Dodaj sve dodatne informacije debuggiranja na izlaz + + + + Prepend debug output with timestamp + Dodaj izlaz debuga na početak sa vremenskom oznakom + + + + Send trace/debug info to console instead of debug.log file + Šalji trace/debug informacije na konzolu umjesto u debug.log datoteku + + + + Send trace/debug info to debugger + Pošalji trace/debug informacije u debugger + + + + Username for JSON-RPC connections + Korisničko ime za JSON-RPC veze + + + + Password for JSON-RPC connections + Lozinka za JSON-RPC veze + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Prihvaćaj JSON-RPC povezivanje na portu broj <port> (ugrađeni izbor: 8332) + + + + Allow JSON-RPC connections from specified IP address + Dozvoli JSON-RPC povezivanje s određene IP adrese + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Pošalji komande nodu na adresi <ip> (ugrađeni izbor: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + Podesi memorijski prostor za ključeve na <n> (ugrađeni izbor: 100) + + + + Rescan the block chain for missing wallet transactions + Ponovno pretraži lanac blokova za transakcije koje nedostaju + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + SSL postavke: (za detalje o podešavanju SSL opcija vidi Bitcoin Wiki) + + + + Use OpenSSL (https) for JSON-RPC connections + Koristi OpenSSL (https) za JSON-RPC povezivanje + + + + Server certificate file (default: server.cert) + Uslužnikov SSL certifikat (ugrađeni izbor: server.cert) + + + + Server private key (default: server.pem) + Uslužnikov privatni ključ (ugrađeni izbor: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Prihvaljivi načini šifriranja (ugrađeni izbor: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + Ova poruka za pomoć + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Program ne može pristupiti direktoriju s datotekama %s. Bitcoin program je vjerojatno već pokrenut. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Učitavanje adresa... + + + + Error loading blkindex.dat + Greška kod učitavanja blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Greška kod učitavanja wallet.dat: Novčanik pokvaren + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Greška kod učitavanja wallet.dat: Novčanik zahtjeva noviju verziju Bitcoina + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Novčanik je trebao prepravak: ponovo pokrenite Bitcoin + + + + Error loading wallet.dat + Greška kod učitavanja wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Greška: priprema transakcije nije uspjela + + + + Sending... + Slanje... + + + + 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. + Generirani novčići moraju pričekati nastanak 120 blokova prije nego što ih je moguće potrošiti. Kad ste generirali taj blok, on je bio emitiran u mrežu kako bi bio dodan postojećim lancima blokova. Ako ne uspije biti dodan, njegov status bit će promijenjen u "nije prihvatljiv" i on neće biti potrošiv. S vremena na vrijeme tako nešto se može desiti ako neki drugi nod približno istovremeno generira blok. + + + + Invalid amount + + + + + Insufficient funds + Nedovoljna sredstva + + + + Loading block index... + Učitavanje indeksa blokova... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + Naknada posredniku po KB-u koja će biti dodana svakoj transakciji koju pošalješ + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Učitavanje novčanika... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Rescaniranje + + + + Done loading + Učitavanje gotovo + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Upozorenje: Molimo provjerite jesu li datum i vrijeme na vašem računalu točni. Ako vaš sat ide krivo, Bitcoin neće raditi ispravno. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts new file mode 100644 index 0000000..e69453c --- /dev/null +++ b/src/qt/locale/bitcoin_hu.ts @@ -0,0 +1,2534 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + A Bitcoinról + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> verzió + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + Címjegyzék + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Ezekkel a Bitcoin-címekkel fogadhatod kifizetéseket. Érdemes lehet minden egyes kifizető számára külön címet létrehozni, hogy könnyebben nyomon követhesd, kitől kaptál már pénzt. + + + + Double-click to edit address or label + Dupla-katt a cím vagy a címke szerkesztéséhez + + + + Create a new address + Új cím létrehozása + + + + Copy the currently selected address to the system clipboard + A kiválasztott cím másolása a vágólapra + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + A kiválasztott cím törlése a listáról. Csak a küldő címek törölhetőek. + + + + &Delete + &Törlés + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Címjegyzék adatainak exportálása + + + + Comma separated file (*.csv) + Vesszővel elválasztott fájl (*. csv) + + + + Error exporting + Hiba exportálás közben + + + + Could not write to file %1. + %1 nevű fájl nem írható. + + + + AddressTableModel + + + Label + Címke + + + + Address + Cím + + + + (no label) + (nincs címke) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Add meg a jelszót + + + + New passphrase + Új jelszó + + + + Repeat new passphrase + Új jelszó újra + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Írd be az új jelszót a tárcához.<br/>Használj legalább 10<br/>véletlenszerű karaktert</b> vagy <b>legalább nyolc szót</b>. + + + + Encrypt wallet + Tárca kódolása + + + + This operation needs your wallet passphrase to unlock the wallet. + A tárcád megnyitásához a műveletnek szüksége van a tárcád jelszavára. + + + + Unlock wallet + Tárca megnyitása + + + + This operation needs your wallet passphrase to decrypt the wallet. + A tárcád dekódolásához a műveletnek szüksége van a tárcád jelszavára. + + + + Decrypt wallet + Tárca dekódolása + + + + Change passphrase + Jelszó megváltoztatása + + + + Enter the old and new passphrase to the wallet. + Írd be a tárca régi és új jelszavát. + + + + Confirm wallet encryption + Biztosan kódolni akarod a tárcát? + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + FIGYELEM: Ha kódolod a tárcát, és elveszíted a jelszavad, akkor <b>AZ ÖSSZES BITCOINODAT IS EL FOGOD VESZÍTENI!</b> +Biztosan kódolni akarod a tárcát? + + + + + Wallet encrypted + Tárca kódolva + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + Tárca kódolása sikertelen. + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Tárca kódolása belső hiba miatt sikertelen. A tárcád nem lett kódolva. + + + + + The supplied passphrases do not match. + A megadott jelszavak nem egyeznek. + + + + Wallet unlock failed + Tárca megnyitása sikertelen + + + + + + The passphrase entered for the wallet decryption was incorrect. + Hibás jelszó. + + + + Wallet decryption failed + Dekódolás sikertelen. + + + + Wallet passphrase was succesfully changed. + Jelszó megváltoztatva. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin-tárca + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Szinkronizálás a hálózattal... + + + + &Overview + &Áttekintés + + + + Show general overview of wallet + Tárca általános áttekintése + + + + &Transactions + &Tranzakciók + + + + Browse transaction history + Tranzakciótörténet megtekintése + + + + &Address Book + Cím&jegyzék + + + + Edit the list of stored addresses and labels + Tárolt címek és címkék listájának szerkesztése + + + + &Receive coins + Érmék &fogadása + + + + Show the list of addresses for receiving payments + Kiizetést fogadó címek listája + + + + &Send coins + Érmék &küldése + + + + Prove you control an address + + + + + E&xit + &Kilépés + + + + Quit application + Kilépés + + + + &About %1 + &A %1-ról + + + + Show information about Bitcoin + Információk a Bitcoinról + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + &Opciók... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Exportálás... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + Tárca kódolása vagy dekódolása + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + Tárcakódoló jelszó megváltoztatása + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Fájl + + + + &Settings + &Beállítások + + + + &Help + &Súgó + + + + Tabs toolbar + Fül eszköztár + + + + Actions toolbar + Parancsok eszköztár + + + + + [testnet] + [teszthálózat] + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + %n aktív kapcsolat a Bitcoin-hálózattal%n aktív kapcsolat a Bitcoin-hálózattal + + + + Downloaded %1 blocks of transaction history. + %1 blokk letöltve a tranzakciótörténetből. + + + + %n second(s) ago + %n másodperccel ezelőtt%n másodperccel ezelőtt + + + + %n minute(s) ago + %n perccel ezelőtt%n perccel ezelőtt + + + + %n hour(s) ago + %n órával ezelőtt%n órával ezelőtt + + + + %n day(s) ago + %n nappal ezelőtt%n nappal ezelőtt + + + + Up to date + Naprakész + + + + Catching up... + Frissítés... + + + + Last received block was generated %1. + Az utolsóként kapott blokk generálva: %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Ez a tranzakció túllépi a mérethatárt, de %1 tranzakciós díj ellenében így is elküldheted. Ezt a plusz összeget a tranzakcióidat feldolgozó csomópontok kapják, így magát a hálózatot támogatod vele. Hajlandó vagy megfizetni a díjat? + + + + Confirm transaction fee + + + + + Sent transaction + Tranzakció elküldve. + + + + Incoming transaction + Beérkező tranzakció + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Dátum: %1 +Összeg: %2 +Típus: %3 +Cím: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Tárca <b>kódolva</b> és jelenleg <b>nyitva</b>. + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Tárca <b>kódolva</b> és jelenleg <b>zárva</b>. + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Megjelenítés + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Válaszd ki az interfészen és érmék küldésekor megjelenítendő alapértelmezett alegységet. + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Cím szerkesztése + + + + &Label + Cím&ke + + + + The label associated with this address book entry + A címhez tartozó címke + + + + &Address + &Cím + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Az ehhez a címjegyzék-bejegyzéshez tartozó cím. Ez csak a küldő címeknél módosítható. + + + + New receiving address + Új fogadó cím + + + + New sending address + Új küldő cím + + + + Edit receiving address + Fogadó cím szerkesztése + + + + Edit sending address + Küldő cím szerkesztése + + + + The entered address "%1" is already in the address book. + A megadott "%1" cím már szerepel a címjegyzékben. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Tárca feloldása sikertelen + + + + New key generation failed. + Új kulcs generálása sikertelen + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Használat: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + Indítás lekicsinyítve + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Tranzakciós &díj fizetése + + + + Main + + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + Válassz egy címet a címjegyzékből + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Cím beillesztése a vágólapról + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adj meg egy Bitcoin-címet (pl.: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L ) + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + &UPnP port-feltérképezés + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + A Bitcoin-kliens portjának automatikus megnyitása a routeren. Ez csak akkor működik, ha a routered támogatja az UPnP-t és az engedélyezve is van rajta. + + + + &Connect through SOCKS4 proxy: + &Csatlakozás SOCKS4 proxyn keresztül: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + SOCKS4 proxyn keresztüli csatlakozás a Bitcoin hálózatához (pl. Tor-on keresztüli csatlakozás esetén) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + Proxy IP címe (pl.: 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Proxy portja (pl.: 1234) + + + + OptionsDialog + + + Options + Opciók + + + + OverviewPage + + + Form + Űrlap + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Egyenleg: + + + + Number of transactions: + Tranzakciók száma: + + + + Unconfirmed: + Megerősítetlen: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Legutóbbi tranzakciók</b> + + + + Your current balance + Aktuális egyenleged + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Még megerősítésre váró, a jelenlegi egyenlegbe be nem számított tranzakciók + + + + Total number of transactions in wallet + Tárca összes tranzakcióinak száma + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + Üzenet: + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Érmék küldése + + + + Send to multiple recipients at once + Küldés több címzettnek egyszerre + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + Egyenleg: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Küldés megerősítése + + + + &Send + &Küldés + + + + <b>%1</b> to %2 (%3) + <b>%1</b> %2-re (%3) + + + + Confirm send coins + Küldés megerősítése + + + + Are you sure you want to send %1? + Valóban el akarsz küldeni %1-t? + + + + and + és + + + + The recepient address is not valid, please recheck. + A címzett címe érvénytelen, kérlek, ellenőrizd. + + + + The amount to pay must be larger than 0. + A fizetendő összegnek nagyobbnak kell lennie 0-nál. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Űrlap + + + + A&mount: + Összeg: + + + + Pay &To: + Címzett: + + + + + Enter a label for this address to add it to your address book + Milyen címkével kerüljön be ez a cím a címtáradba? + + + + + &Label: + Címke: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Címzett címe (pl.: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L ) + + + + Choose address from address book + Válassz egy címet a címjegyzékből + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Cím beillesztése a vágólapról + + + + Alt+P + Alt+P + + + + Remove this recipient + Címzett eltávolítása + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adj meg egy Bitcoin-címet (pl.: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L ) + + + + TransactionDesc + + + Open for %1 blocks + Megnyitva %1 blokkra + + + + Open until %1 + Megnyitva %1-ig + + + + %1/offline? + %1/offline? + + + + %1/unconfirmed + %1/megerősítetlen + + + + %1 confirmations + %1 megerősítés + + + + <b>Status:</b> + <b>Állapot:</b> + + + + , has not been successfully broadcast yet + , még nem sikerült elküldeni. + + + + , broadcast through %1 node + , %1 csomóponton keresztül elküldve. + + + + , broadcast through %1 nodes + , elküldve %1 csomóponton keresztül. + + + + <b>Date:</b> + <b>Dátum:</b> + + + + <b>Source:</b> Generated<br> + <b>Forrás:</b> Generálva <br> + + + + + <b>From:</b> + <b>Űrlap:</b> + + + + unknown + ismeretlen + + + + + + <b>To:</b> + <b>Címzett:</b> + + + + (yours, label: + (tiéd, címke: + + + + (yours) + (tiéd) + + + + + + + <b>Credit:</b> + <b>Jóváírás</b> + + + + (%1 matures in %2 more blocks) + (%1, %2 múlva készül el) + + + + (not accepted) + (elutasítva) + + + + + + <b>Debit:</b> + <b>Terhelés</b> + + + + <b>Transaction fee:</b> + <b>Tranzakciós díj:</b> + + + + <b>Net amount:</b> + <b>Nettó összeg:</b> + + + + Message: + Üzenet: + + + + Comment: + Megjegyzés: + + + + Transaction ID: + + + + + 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. + A frissen generált érméket csak 120 blokkal később tudod elkölteni. Ez a blokk nyomban szétküldésre került a hálózatba, amint legeneráltad, hogy hozzáadhassák a blokklánchoz. Ha nem kerül be a láncba, úgy az állapota "elutasítva"-ra módosul, és nem költheted el az érméket. Ez akkor következhet be időnként, ha egy másik csomópont mindössze néhány másodperc különbséggel generált le egy blokkot a tiédhez képest. + + + + TransactionDescDialog + + + Transaction details + Tranzakció részletei + + + + This pane shows a detailed description of the transaction + Ez a mező a tranzakció részleteit mutatja + + + + TransactionTableModel + + + Date + Dátum + + + + Type + Típus + + + + Address + Cím + + + + Amount + Összeg + + + + Open for %n block(s) + %n blokkra megnyitva%n blokkra megnyitva + + + + Open until %1 + %1-ig megnyitva + + + + Offline (%1 confirmations) + Offline (%1 megerősítés) + + + + Unconfirmed (%1 of %2 confirmations) + Megerősítetlen (%1 %2 megerősítésből) + + + + Confirmed (%1 confirmations) + Megerősítve (%1 megerősítés) + + + + Mined balance will be available in %n more blocks + %n blokk múlva lesz elérhető a bányászott egyenleg.%n blokk múlva lesz elérhető a bányászott egyenleg. + + + + This block was not received by any other nodes and will probably not be accepted! + Ezt a blokkot egyetlen másik csomópont sem kapta meg, így valószínűleg nem lesz elfogadva! + + + + Generated but not accepted + Legenerálva, de még el nem fogadva. + + + + Received with + Erre a címre + + + + Received from + + + + + Sent to + Erre a címre + + + + Payment to yourself + Magadnak kifizetve + + + + Mined + Kibányászva + + + + (n/a) + (nincs) + + + + Transaction status. Hover over this field to show number of confirmations. + Tranzakció állapota. Húzd ide a kurzort, hogy lásd a megerősítések számát. + + + + Date and time that the transaction was received. + Tranzakció fogadásának dátuma és időpontja. + + + + Type of transaction. + Tranzakció típusa. + + + + Destination address of transaction. + A tranzakció címzettjének címe. + + + + Amount removed from or added to balance. + Az egyenleghez jóváírt vagy ráterhelt összeg. + + + + TransactionView + + + + All + Mind + + + + Today + Mai + + + + This week + Ezen a héten + + + + This month + Ebben a hónapban + + + + Last month + Múlt hónapban + + + + This year + Ebben az évben + + + + Range... + Tartomány ... + + + + Received with + Erre a címre + + + + Sent to + Erre a címre + + + + To yourself + Magadnak + + + + Mined + Kibányászva + + + + Other + Más + + + + Enter address or label to search + Írd be a keresendő címet vagy címkét + + + + Min amount + Minimális összeg + + + + Copy address + Cím másolása + + + + Copy label + Címke másolása + + + + Copy amount + + + + + Edit label + Címke szerkesztése + + + + Show transaction details + + + + + Export Transaction Data + Tranzakció adatainak exportálása + + + + Comma separated file (*.csv) + Vesszővel elválasztott fájl (*.csv) + + + + Confirmed + Megerősítve + + + + Date + Dátum + + + + Type + Típus + + + + Label + Címke + + + + Address + Cím + + + + Amount + Összeg + + + + ID + Azonosító + + + + Error exporting + Hiba lépett fel exportálás közben + + + + Could not write to file %1. + %1 fájlba való kiírás sikertelen. + + + + Range: + Tartomány: + + + + to + meddig + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + A kiválasztott cím másolása a vágólapra + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Küldés ... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Kicsinyítés a tálcára az eszköztár helyett + + + + Show only a tray icon after minimizing the window + Kicsinyítés után csak eszköztár-ikont mutass + + + + M&inimize on close + + + + + 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. + Az alkalmazásból való kilépés helyett az eszköztárba kicsinyíti az alkalmazást az ablak bezárásakor. Ez esetben az alkalmazás csak a Kilépés menüponttal zárható be. + + + + bitcoin-core + + + Bitcoin version + Bitcoin verzió + + + + Usage: + Használat: + + + + Send command to -server or bitcoind + Parancs küldése a -serverhez vagy a bitcoindhez + + + + + List commands + Parancsok kilistázása + + + + + Get help for a command + Segítség egy parancsról + + + + + Options: + Opciók + + + + + Specify configuration file (default: bitcoin.conf) + Konfigurációs fájl (alapértelmezett: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + pid-fájl (alapértelmezett: bitcoind.pid) + + + + + Generate coins + Érmék generálása + + + + + Don't generate coins + Bitcoin-generálás leállítása + + + + + Specify data directory + Adatkönyvtár + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Csatlakozás időkerete (milliszekundumban) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + Csatlakozás csak a megadott csomóponthoz + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Parancssoros és JSON-RPC parancsok elfogadása + + + + + Run in the background as a daemon and accept commands + Háttérben futtatás daemonként és parancsok elfogadása + + + + + Use the test network + Teszthálózat használata + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + Felhasználói név JSON-RPC csatlakozásokhoz + + + + + Password for JSON-RPC connections + Jelszó JSON-RPC csatlakozásokhoz + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + JSON-RPC csatlakozásokhoz figyelendő <port> (alapértelmezett: 8332) + + + + + Allow JSON-RPC connections from specified IP address + JSON-RPC csatlakozások engedélyezése meghatározott IP-címről + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Parancsok küldése <ip> címen működő csomóponthoz (alapértelmezett: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + Kulcskarika mérete <n> (alapértelmezett: 100) + + + + + Rescan the block chain for missing wallet transactions + Blokklánc újraszkennelése hiányzó tárca-tranzakciók után + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL-opciók: (lásd a Bitcoin Wiki SSL-beállítási instrukcióit) + + + + + Use OpenSSL (https) for JSON-RPC connections + OpenSSL (https) használata JSON-RPC csatalkozásokhoz + + + + + Server certificate file (default: server.cert) + Szervertanúsítvány-fájl (alapértelmezett: server.cert) + + + + + Server private key (default: server.pem) + Szerver titkos kulcsa (alapértelmezett: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Elfogadható rejtjelkulcsok (alapértelmezett: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH ) + + + + + Warning: Disk space is low + + + + + This help message + Ez a súgó-üzenet + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Az %s adatkönyvtár nem zárható. A Bitcoin valószínűleg fut már. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Címek betöltése... + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Hiba: nem sikerült létrehozni a tranzakciót + + + + Sending... + Küldés... + + + + 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. + Hiba: a tranzakciót elutasították. Ezt az okozhatja, ha már elköltöttél valamennyi érmét a tárcádból - például ha a wallet.dat-od egy másolatát használtad, és így az elköltés csak abban lett jelölve, de itt nem. + + + + Invalid amount + + + + + Insufficient funds + Nincs elég bitcoinod. + + + + Loading block index... + Blokkindex betöltése... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Tárca betöltése... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Újraszkennelés... + + + + Done loading + Betöltés befejezve. + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Figyelem: Ellenőrizd, hogy helyesen van-e beállítva a gépeden a dátum és az idő. A Bitcoin nem fog megfelelően működni, ha rosszul van beállítvaaz órád. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts new file mode 100644 index 0000000..92d3b7c --- /dev/null +++ b/src/qt/locale/bitcoin_it.ts @@ -0,0 +1,2540 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Info su Bitcoin + + + + <b>Bitcoin</b> version + Versione di <b>Bitcoin</b> + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Bitcoin Developers + +Questo è un software sperimentale. + +Distribuito sotto la licenza software MIT/X11, vedi il file license.txt incluso oppure su http://www.opensource.org/licenses/mit-license.php. + +Questo prodotto include software sviluppato dal progetto OpenSSL per l'uso del Toolkit OpenSSL (http://www.openssl.org/), software crittografico scritto da Eric Young (eay@cryptsoft.com) e software UPnP scritto da Thomas Bernard. + + + + AddressBookPage + + + Address Book + Rubrica + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Questi sono i tuoi indirizzi Bitcoin per ricevere pagamenti. Potrai darne uno diverso ad ognuno per tenere così traccia di chi ti sta pagando. + + + + Double-click to edit address or label + Fai doppio click per modificare o cancellare l'etichetta + + + + Create a new address + Crea un nuovo indirizzo + + + + Copy the currently selected address to the system clipboard + Copia l'indirizzo attualmente selezionato nella clipboard + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Mostra il codice &QR + + + + Sign a message to prove you own this address + Firma un messaggio per dimostrare di possedere questo indirizzo + + + + &Sign Message + &Firma il messaggio + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Cancella l'indirizzo attualmente selezionato dalla lista. Solo indirizzi d'invio possono essere cancellati. + + + + &Delete + &Cancella + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Esporta gli indirizzi della rubrica + + + + Comma separated file (*.csv) + Testo CSV (*.csv) + + + + Error exporting + Errore nell'esportazione + + + + Could not write to file %1. + Impossibile scrivere sul file %1. + + + + AddressTableModel + + + Label + Etichetta + + + + Address + Indirizzo + + + + (no label) + (nessuna etichetta) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Inserisci la passphrase + + + + New passphrase + Nuova passphrase + + + + Repeat new passphrase + Ripeti la passphrase + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Inserisci la passphrase per il portamonete.<br/>Per piacere usare unapassphrase di <b>10 o più caratteri casuali</b>, o <b>otto o più parole</b>. + + + + Encrypt wallet + Cifra il portamonete + + + + This operation needs your wallet passphrase to unlock the wallet. + Quest'operazione necessita della passphrase per sbloccare il portamonete. + + + + Unlock wallet + Sblocca il portamonete + + + + This operation needs your wallet passphrase to decrypt the wallet. + Quest'operazione necessita della passphrase per decifrare il portamonete, + + + + Decrypt wallet + Decifra il portamonete + + + + Change passphrase + Cambia la passphrase + + + + Enter the old and new passphrase to the wallet. + Inserisci la vecchia e la nuova passphrase per il portamonete. + + + + Confirm wallet encryption + Conferma la cifratura del portamonete + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ATTENZIONE: se si cifra il portamonete e si perde la frase d'ordine, <b>SI PERDERANNO TUTTI I PROPRI BITCOIN</b>! +Si è sicuri di voler cifrare il portamonete? + + + + + Wallet encrypted + Portamonete cifrato + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin verrà ora chiuso per finire il processo di crittazione. Ricorda che criptare il tuo portamonete non può fornire una protezione totale contro furti causati da malware che dovessero infettare il tuo computer. + + + + + Warning: The Caps Lock key is on. + Attenzione: tasto Blocco maiuscole attivo. + + + + + + + Wallet encryption failed + Cifratura del portamonete fallita + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Cifratura del portamonete fallita a causa di un errore interno. Il portamonete non è stato cifrato. + + + + + The supplied passphrases do not match. + Le passphrase inserite non corrispondono. + + + + Wallet unlock failed + Sblocco del portamonete fallito + + + + + + The passphrase entered for the wallet decryption was incorrect. + La passphrase inserita per la decifrazione del portamonete è errata. + + + + Wallet decryption failed + Decifrazione del portamonete fallita + + + + Wallet passphrase was succesfully changed. + Passphrase del portamonete modificata con successo. + + + + BitcoinGUI + + + Bitcoin Wallet + Portamonete di bitcoin + + + + Sign &message... + + + + + Show/Hide &Bitcoin + Mostra/Nascondi &Bitcoin + + + + Synchronizing with network... + Sto sincronizzando con la rete... + + + + &Overview + &Sintesi + + + + Show general overview of wallet + Mostra lo stato generale del portamonete + + + + &Transactions + &Transazioni + + + + Browse transaction history + Cerca nelle transazioni + + + + &Address Book + &Rubrica + + + + Edit the list of stored addresses and labels + Modifica la lista degli indirizzi salvati e delle etichette + + + + &Receive coins + &Ricevi monete + + + + Show the list of addresses for receiving payments + Mostra la lista di indirizzi su cui ricevere pagamenti + + + + &Send coins + &Invia monete + + + + Prove you control an address + Dimostra di controllare un indirizzo + + + + E&xit + &Esci + + + + Quit application + Chiudi applicazione + + + + &About %1 + &Informazioni su %1 + + + + Show information about Bitcoin + Mostra informazioni su Bitcoin + + + + About &Qt + Informazioni su &Qt + + + + Show information about Qt + Mostra informazioni su Qt + + + + &Options... + &Opzioni... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + ~%n blocco rimanente~%n blocchi rimanenti + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Scaricati %1 di %2 blocchi dello storico delle transazioni ( il %3% ) + + + + &Export... + &Esporta... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Mostra o nascondi la finestra Bitcoin + + + + Export the data in the current tab to a file + Esporta i dati nella tabella corrente su un file + + + + Encrypt or decrypt wallet + Cifra o decifra il portamonete + + + + Backup wallet to another location + Backup portamonete in un'altra locazione + + + + Change the passphrase used for wallet encryption + Cambia la passphrase per la cifratura del portamonete + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &File + + + + &Settings + &Impostazioni + + + + &Help + &Aiuto + + + + Tabs toolbar + Barra degli strumenti "Tabs" + + + + Actions toolbar + Barra degli strumenti "Azioni" + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Bitcoin client + + + + %n active connection(s) to Bitcoin network + %n connessione attiva alla rete Bitcoin%n connessioni attive alla rete Bitcoin + + + + Downloaded %1 blocks of transaction history. + Scaricati %1 blocchi dello storico transazioni. + + + + %n second(s) ago + %n secondo fa%n secondi fa + + + + %n minute(s) ago + %n minuto fa%n minuti fa + + + + %n hour(s) ago + %n ora fa%n ore fa + + + + %n day(s) ago + %n giorno fa%n giorni fa + + + + Up to date + Aggiornato + + + + Catching up... + In aggiornamento... + + + + Last received block was generated %1. + L'ultimo blocco ricevuto è stato generato %1 + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Questa transazione è superiore al limite di dimensione. È comunque possibile inviarla con una commissione di %1, che va ai nodi che processano la tua transazione e contribuisce a sostenere la rete. Vuoi pagare la commissione? + + + + Confirm transaction fee + + + + + Sent transaction + Transazione inviata + + + + Incoming transaction + Transazione ricevuta + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Data: %1 +Quantità: %2 +Tipo: %3 +Indirizzo: %4 + + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Il portamonete è <b>cifrato</b> e attualmente <b>sbloccato</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Il portamonete è <b>cifrato</b> e attualmente <b>bloccato</b> + + + + Backup Wallet + Backup Portamonete + + + + Wallet Data (*.dat) + Dati Portamonete (*.dat) + + + + Backup Failed + Backup fallito + + + + There was an error trying to save the wallet data to the new location. + C'è stato un errore tentanto di salvare i dati del portamonete in un'altra locazione + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Mostra + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Scegli l'unità di suddivisione di default per l'interfaccia e per l'invio di monete + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Modifica l'indirizzo + + + + &Label + &Etichetta + + + + The label associated with this address book entry + L'etichetta associata a questo indirizzo nella rubrica + + + + &Address + &Indirizzo + + + + The address associated with this address book entry. This can only be modified for sending addresses. + L'indirizzo associato a questa voce della rubrica. Si può modificare solo negli indirizzi di spedizione. + + + + New receiving address + Nuovo indirizzo di ricezione + + + + New sending address + Nuovo indirizzo d'invio + + + + Edit receiving address + Modifica indirizzo di ricezione + + + + Edit sending address + Modifica indirizzo d'invio + + + + The entered address "%1" is already in the address book. + L'indirizzo inserito "%1" è già in rubrica. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Impossibile sbloccare il portamonete. + + + + New key generation failed. + Generazione della nuova chiave non riuscita. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Utilizzo: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + Parti in icona + + + + + Show splash screen on startup (default: 1) + Mostra finestra di presentazione all'avvio (default: 1) + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Paga la &commissione + + + + Main + Principale + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Commissione di transazione per kB; è opzionale e contribuisce ad assicurare che le transazioni siano elaborate velocemente. Le transazioni sono per la maggior parte da 1 kB. Commissione raccomandata 0,01. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Puoi firmare messeggi con i tuoi indirizzi per dimostrare che sono tuoi. Fai attenzione a non firmare niente di vago, visto che gli attacchi di phishing potrebbero cercare di spingerti a mettere la tua firma su di loro. Firma solo dichiarazioni completamente dettagliate con cui sei d'accordo. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + L'indirizzo per firmare il messaggio con (esempio 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Scegli l'indirizzo dalla rubrica + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Incollare l'indirizzo dagli appunti + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Inserisci qui il messaggio che vuoi firmare + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Clicca "Firma il messaggio" per ottenere la firma + + + + Sign a message to prove you own this address + Firma un messaggio per dimostrare di possedere questo indirizzo + + + + &Sign Message + &Firma il messaggio + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Inserisci un indirizzo Bitcoin (ad esempio 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Errore nel firmare + + + + %1 is not a valid address. + %1 non è un indirizzo valido. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + La chiave privata per %1 non è disponibile. + + + + Sign failed + Firma non riuscita + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Mappa le porte tramite l'&UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Apri automaticamente la porta del client Bitcoin sul router. Questo funziona solo se il router supporta UPnP ed è abilitato. + + + + &Connect through SOCKS4 proxy: + &Collegati tramite SOCKS4 proxy: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Connettiti alla rete Bitcon attraverso un proxy SOCKS4 (ad esempio quando ci si collega via Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + Indirizzo IP del proxy (ad esempio 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Porta del proxy (es. 1234) + + + + OptionsDialog + + + Options + Opzioni + + + + OverviewPage + + + Form + Modulo + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Saldo + + + + Number of transactions: + Numero di transazioni: + + + + Unconfirmed: + Non confermato: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Transazioni recenti</b> + + + + Your current balance + Saldo attuale + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Totale delle transazioni in corso di conferma, che non sono ancora incluse nel saldo attuale + + + + Total number of transactions in wallet + Numero delle transazioni effettuate + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + Codice QR + + + + Request Payment + Richiedi pagamento + + + + Amount: + Importo: + + + + BTC + BTC + + + + Label: + Etichetta: + + + + Message: + Messaggio: + + + + &Save As... + &Salva come... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + L'URI risulta troppo lungo, prova a ridurre il testo nell'etichetta / messaggio. + + + + Save QR Code + + + + + PNG Images (*.png) + Immagini PNG (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Spedisci Bitcoin + + + + Send to multiple recipients at once + Spedisci a diversi beneficiari in una volta sola + + + + &Add Recipient + + + + + Remove all transaction fields + Rimuovi tutti i campi della transazione + + + + Clear &All + + + + + Balance: + Saldo: + + + + 123.456 BTC + 123,456 BTC + + + + Confirm the send action + Conferma la spedizione + + + + &Send + &Spedisci + + + + <b>%1</b> to %2 (%3) + <b>%1</b> to %2 (%3) + + + + Confirm send coins + Conferma la spedizione di bitcoin + + + + Are you sure you want to send %1? + Si è sicuri di voler spedire %1? + + + + and + e + + + + The recepient address is not valid, please recheck. + L'indirizzo del beneficiario non è valido, per cortesia controlla. + + + + The amount to pay must be larger than 0. + L'importo da pagare dev'essere maggiore di 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Modulo + + + + A&mount: + &Importo: + + + + Pay &To: + Paga &a: + + + + + Enter a label for this address to add it to your address book + Inserisci un'etichetta per questo indirizzo, per aggiungerlo nella rubrica + + + + &Label: + &Etichetta + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + L'indirizzo del beneficiario cui inviare il pagamento (ad esempio 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Scegli l'indirizzo dalla rubrica + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Incollare l'indirizzo dagli appunti + + + + Alt+P + Alt+P + + + + Remove this recipient + Rimuovere questo beneficiario + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Inserisci un indirizzo Bitcoin (ad esempio 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Aperto per %1 blocchi + + + + Open until %1 + Aperto fino a %1 + + + + %1/offline? + %1/offline? + + + + %1/unconfirmed + %1/non confermato + + + + %1 confirmations + %1 conferme + + + + <b>Status:</b> + <b>Stato:</b> + + + + , has not been successfully broadcast yet + , non è stato ancora trasmesso con successo + + + + , broadcast through %1 node + , trasmesso attraverso %1 nodo + + + + , broadcast through %1 nodes + , trasmesso attraverso %1 nodi + + + + <b>Date:</b> + <b>Data:</b> + + + + <b>Source:</b> Generated<br> + <b>Fonte:</b> Generato<br> + + + + + <b>From:</b> + <b>Da:</b> + + + + unknown + sconosciuto + + + + + + <b>To:</b> + <b>Per:</b> + + + + (yours, label: + (vostro, etichetta: + + + + (yours) + (vostro) + + + + + + + <b>Credit:</b> + <b>Credito:</b> + + + + (%1 matures in %2 more blocks) + (%1 matura in altri %2 blocchi) + + + + (not accepted) + (non accettate) + + + + + + <b>Debit:</b> + <b>Debito:</b> + + + + <b>Transaction fee:</b> + <b>Commissione:</b> + + + + <b>Net amount:</b> + <b>Importo netto:</b> + + + + Message: + Messaggio: + + + + Comment: + Commento: + + + + Transaction ID: + ID della transazione: + + + + 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. + Bisogna attendere 120 blocchi prima di spendere I bitcoin generati. Quando è stato generato questo blocco, è stato trasmesso alla rete per aggiungerlo alla catena di blocchi. Se non riesce a entrare nella catena, verrà modificato in "non accettato" e non sarà spendibile. Questo può accadere a volte, se un altro nodo genera un blocco entro pochi secondi del tuo. + + + + TransactionDescDialog + + + Transaction details + Dettagli sulla transazione + + + + This pane shows a detailed description of the transaction + Questo pannello mostra una descrizione dettagliata della transazione + + + + TransactionTableModel + + + Date + Data + + + + Type + Tipo + + + + Address + Indirizzo + + + + Amount + Importo + + + + Open for %n block(s) + Aperto per %n bloccoAperto per %n blocchi + + + + Open until %1 + Aperto fino a %1 + + + + Offline (%1 confirmations) + Offline (%1 conferme) + + + + Unconfirmed (%1 of %2 confirmations) + Non confermati (%1 su %2 conferme) + + + + Confirmed (%1 confirmations) + Confermato (%1 conferme) + + + + Mined balance will be available in %n more blocks + Il saldo generato sarà disponibile tra %n altro bloccoIl saldo generato sarà disponibile tra %n altri blocchi + + + + This block was not received by any other nodes and will probably not be accepted! + Questo blocco non è stato ricevuto da altri nodi e probabilmente non sarà accettato! + + + + Generated but not accepted + Generati, ma non accettati + + + + Received with + Ricevuto tramite + + + + Received from + Ricevuto da + + + + Sent to + Spedito a + + + + Payment to yourself + Pagamento a te stesso + + + + Mined + Ottenuto dal mining + + + + (n/a) + (N / a) + + + + Transaction status. Hover over this field to show number of confirmations. + Stato della transazione. Passare con il mouse su questo campo per vedere il numero di conferme. + + + + Date and time that the transaction was received. + Data e ora in cui la transazione è stata ricevuta. + + + + Type of transaction. + Tipo di transazione. + + + + Destination address of transaction. + Indirizzo di destinazione della transazione. + + + + Amount removed from or added to balance. + Importo rimosso o aggiunto al saldo. + + + + TransactionView + + + + All + Tutti + + + + Today + Oggi + + + + This week + Questa settimana + + + + This month + Questo mese + + + + Last month + Il mese scorso + + + + This year + Quest'anno + + + + Range... + Intervallo... + + + + Received with + Ricevuto tramite + + + + Sent to + Spedito a + + + + To yourself + A te + + + + Mined + Ottenuto dal mining + + + + Other + Altro + + + + Enter address or label to search + Inserisci un indirizzo o un'etichetta da cercare + + + + Min amount + Importo minimo + + + + Copy address + Copia l'indirizzo + + + + Copy label + Copia l'etichetta + + + + Copy amount + Copia l'importo + + + + Edit label + Modifica l'etichetta + + + + Show transaction details + + + + + Export Transaction Data + Esporta i dati della transazione + + + + Comma separated file (*.csv) + Testo CSV (*.csv) + + + + Confirmed + Confermato + + + + Date + Data + + + + Type + Tipo + + + + Label + Etichetta + + + + Address + Indirizzo + + + + Amount + Importo + + + + ID + ID + + + + Error exporting + Errore nell'esportazione + + + + Could not write to file %1. + Impossibile scrivere sul file %1. + + + + Range: + Intervallo: + + + + to + a + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Copia l'indirizzo attualmente selezionato nella clipboard + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Invio... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Minimizza sul tray invece che sulla barra delle applicazioni + + + + Show only a tray icon after minimizing the window + Mostra solo un'icona nel tray quando si minimizza la finestra + + + + M&inimize on close + + + + + 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. + Riduci ad icona, invece di uscire dall'applicazione quando la finestra viene chiusa. Quando questa opzione è attivata, l'applicazione verrà chiusa solo dopo aver selezionato Esci nel menu. + + + + bitcoin-core + + + Bitcoin version + Versione di Bitcoin + + + + Usage: + Utilizzo: + + + + Send command to -server or bitcoind + Manda il comando a -server o bitcoind + + + + + List commands + Lista comandi + + + + + Get help for a command + Aiuto su un comando + + + + + Options: + Opzioni: + + + + + Specify configuration file (default: bitcoin.conf) + Specifica il file di configurazione (di default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + Specifica il file pid (default: bitcoind.pid) + + + + + Generate coins + Genera Bitcoin + + + + + Don't generate coins + Non generare Bitcoin + + + + + Specify data directory + Specifica la cartella dati + + + + + Set database cache size in megabytes (default: 25) + Imposta la dimensione cache del database in megabyte (default: 25) + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Specifica il timeout di connessione (in millisecondi) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Ascolta le connessioni JSON-RPC su <porta> (default: 8333 o testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Mantieni al massimo <n> connessioni ai peer (default: 125) + + + + Connect only to the specified node + Connetti solo al nodo specificato + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Soglia di disconnessione dei peer di cattiva qualità (default: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Numero di secondi di sospensione che i peer di cattiva qualità devono trascorrere prima di riconnettersi (default: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Buffer di ricezione massimo per connessione, <n>*1000 byte (default: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Buffer di invio massimo per connessione, <n>*1000 byte (default: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Accetta da linea di comando e da comandi JSON-RPC + + + + + Run in the background as a daemon and accept commands + Esegui in background come demone e accetta i comandi + + + + + Use the test network + Utilizza la rete di prova + + + + + Output extra debugging information + Produci informazioni extra utili al debug + + + + Prepend debug output with timestamp + Anteponi all'output di debug una marca temporale + + + + Send trace/debug info to console instead of debug.log file + Invia le informazioni di trace/debug alla console invece che al file debug.log + + + + Send trace/debug info to debugger + Invia le informazioni di trace/debug al debugger + + + + Username for JSON-RPC connections + Nome utente per connessioni JSON-RPC + + + + + Password for JSON-RPC connections + Password per connessioni JSON-RPC + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Attendi le connessioni JSON-RPC su <porta> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + Consenti connessioni JSON-RPC dall'indirizzo IP specificato + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Inviare comandi al nodo in esecuzione su <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + Aggiorna il wallet all'ultimo formato + + + + Set key pool size to <n> (default: 100) + Impostare la quantità di chiavi di riserva a <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + Ripeti analisi della catena dei blocchi per cercare le transazioni mancanti dal portamonete + + + + + How many blocks to check at startup (default: 2500, 0 = all) + Quanti blocchi da controllare all'avvio (default: 2500, 0 = tutti) + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +Opzioni SSL: (vedi il wiki di Bitcoin per le istruzioni di configurazione SSL) + + + + + Use OpenSSL (https) for JSON-RPC connections + Utilizzare OpenSSL (https) per le connessioni JSON-RPC + + + + + Server certificate file (default: server.cert) + File certificato del server (default: server.cert) + + + + + Server private key (default: server.pem) + Chiave privata del server (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Cifrari accettabili (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + Questo messaggio di aiuto + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Non è possibile ottenere i dati sulla directory %s. Probabilmente Bitcoin è già in esecuzione. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Caricamento indirizzi... + + + + Error loading blkindex.dat + Errore caricamento blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Errore caricamento wallet.dat: Wallet corrotto + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Errore caricamento wallet.dat: il wallet richiede una versione nuova di Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Il portamonete deve essere riscritto: riavviare Bitcoin per completare + + + + Error loading wallet.dat + Errore caricamento wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Errore: creazione della transazione fallita + + + + Sending... + Invio... + + + + 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. + Errore: la transazione è stata rifiutata. Ciò accade se alcuni bitcoin nel portamonete sono stati già spesi, ad esempio se è stata usata una copia del file wallet.dat e i bitcoin sono stati spesi dalla copia ma non segnati come spesi qui. + + + + Invalid amount + + + + + Insufficient funds + Fondi insufficienti + + + + Loading block index... + Caricamento dell'indice del blocco... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + Accetta connessioni da fuori (default: 1) + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + Commissione per KB da aggiungere alle transazioni in uscita + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Caricamento portamonete... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Ripetere la scansione... + + + + Done loading + Caricamento completato + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + Errore + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Attenzione: si prega di controllare che la data del computer e l'ora siano corrette. Se il vostro orologio è sbagliato Bitcoin non funziona correttamente. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts new file mode 100644 index 0000000..f14b5ec --- /dev/null +++ b/src/qt/locale/bitcoin_lt.ts @@ -0,0 +1,2510 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Apie Bitcoiną + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> versija + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Autorystės teisės© 2009-2012 Bitcoin Developers +DĖMESIO: programa eksperimentinė! + +Platinama pagal licenziją MIT/X11, papildomą informaciją rasite faile license.txt arba dokumente pagal nuorodą: http://www.opensource.org/licenses/mit-license.php. + +Šiame produkte yra projekto OpenSSL (http://www.openssl.org/), Eriko Jango (eay@cryptsoft.com) parašyti kriptografinės funkcijos ir algoritmai ir UPnP darbui skirtos funkcijos parašytos Tomo Bernardo. + + + + + AddressBookPage + + + Address Book + Adresų knygelė + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Čia yra Jūsų adresai skirti mokėjimams gauti. Jūs galite skirtingiems žmonėms duoti skirtingus adresus. Tai Jums palengvins kontroliuoti mokėjimus bei padidins anonimiškumą. + + + + + Double-click to edit address or label + Tam, kad pakeisti ar redaguoti adresą arba žymę turite objektą dukart spragtelti pele. + + + + Create a new address + Sukurti naują adresą + + + + Copy the currently selected address to the system clipboard + Kopijuoti esamą adresą į mainų atmintį + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Rodyti &QR kodą + + + + Sign a message to prove you own this address + Registruotis žinute įrodančia, kad turite šį adresą + + + + &Sign Message + &S Registruotis žinute + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Pašalinti iš sąrašo pažymėtą adresą(gali būti pašalinti tiktai adresų knygelės įrašai). + + + + &Delete + &D Pašalinti + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Eksportuoti adresų knygelės duomenis + + + + Comma separated file (*.csv) + Kableliais išskirtas failas (*.csv) + + + + Error exporting + Eksportavimo klaida + + + + Could not write to file %1. + Nepavyko įrašyti į failą %1. + + + + AddressTableModel + + + Label + Žymė + + + + Address + Adresas + + + + (no label) + (nėra žymės) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Įvesti slaptažodį + + + + New passphrase + Naujas slaptažodis + + + + Repeat new passphrase + Pakartoti naują slaptažodį + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Įveskite naują slaptažodį piniginei <br/> Prašome naudoti slaptažodį iš <b> 10 ar daugiau atsitiktinių simbolių </b> arba <b> aštuonių ar daugiau žodžių </b>. + + + + Encrypt wallet + Užšifruoti piniginę + + + + This operation needs your wallet passphrase to unlock the wallet. + Ši operacija reikalauja jūsų piniginės slaptažodžio jai atrakinti. + + + + Unlock wallet + Atrakinti piniginę + + + + This operation needs your wallet passphrase to decrypt the wallet. + Ši operacija reikalauja jūsų piniginės slaptažodžio jai iššifruoti. + + + + Decrypt wallet + Iššifruoti piniginę + + + + Change passphrase + Pakeisti slaptažodį + + + + Enter the old and new passphrase to the wallet. + Įveskite seną ir naują piniginės slaptažodžius + + + + Confirm wallet encryption + Patvirtinkite piniginės užšifravimą + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ĮSPĖJIMAS: Jei užšifruosite savo piniginę ir prarasite savo slaptažodį, Jūs <b> PRARASITE VISUS SAVO BITKOINUS, </b>! +Ar jūs tikrai norite užšifruoti savo piniginę? + + + + + Wallet encrypted + Piniginė užšifruota + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin dabar užsidarys šifravimo proceso pabaigai. Atminkite, kad piniginės šifravimas negali pilnai apsaugoti bitcoinų vagysčių kai tinkle esančios kenkėjiškos programos patenka į jūsų kompiuterį. + + + + + Warning: The Caps Lock key is on. + ĮSPĖJIMAS: Įjungtos didžiosios raidės + + + + + + + Wallet encryption failed + Nepavyko užšifruoti piniginę + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Dėl vidinės klaidos nepavyko užšifruoti piniginę.Piniginė neužšifruota. + + + + + The supplied passphrases do not match. + Įvestas slaptažodis nesutampa + + + + Wallet unlock failed + Nepavyko atrakinti piniginę + + + + + + The passphrase entered for the wallet decryption was incorrect. + Neteisingai įvestas slaptažodis piniginės iššifravimui + + + + Wallet decryption failed + Nepavyko iššifruoti piniginę + + + + Wallet passphrase was succesfully changed. + Sėkmingai pakeistas piniginės slaptažodis + + + + BitcoinGUI + + + Bitcoin Wallet + Bitkoinų piniginė + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Sinchronizavimas su tinklu ... + + + + &Overview + &O Apžvalga + + + + Show general overview of wallet + Rodyti piniginės bendrą apžvalgą + + + + &Transactions + &T Sandoriai + + + + Browse transaction history + Apžvelgti sandorių istoriją + + + + &Address Book + &Adresų knygelė + + + + Edit the list of stored addresses and labels + Redaguoti išsaugotus adresus bei žymes + + + + &Receive coins + &R Gautos monetos + + + + Show the list of addresses for receiving payments + Parodyti adresų sąraša mokėjimams gauti + + + + &Send coins + &Siųsti monetas + + + + Prove you control an address + Įrodyti, kad jūs valdyti adresą + + + + E&xit + &x išėjimas + + + + Quit application + Išjungti programą + + + + &About %1 + &Apie %1 + + + + Show information about Bitcoin + Rodyti informaciją apie Bitkoiną + + + + About &Qt + Apie &Qt + + + + Show information about Qt + Rodyti informaciją apie Qt + + + + &Options... + &Opcijos... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Eksportas... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + Užšifruoti ar iššifruoti piniginę + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + Pakeisti slaptažodį naudojamą piniginės užšifravimui + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Failas + + + + &Settings + Nu&Statymai + + + + &Help + &H Pagelba + + + + Tabs toolbar + Tabs įrankių juosta + + + + Actions toolbar + Veiksmų įrankių juosta + + + + + [testnet] + [testavimotinklas] + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + %n Bitcoin tinklo aktyvus ryšys%n Bitcoin tinklo aktyvūs ryšiai%n Bitcoin tinklo aktyvūs ryšiai + + + + Downloaded %1 blocks of transaction history. + Atsisiuntė %1 iš %2 sandorių istorijos blokų + + + + %n second(s) ago + Prieš %n sekundęPrieš %n sekundesPrieš %n sekundžių + + + + %n minute(s) ago + Prieš %n minutęPrieš %n minutesPrieš %n minutčių + + + + %n hour(s) ago + Prieš %n valandąPrieš %n valandasPrieš %n valandų + + + + %n day(s) ago + Prieš %n dienąPrieš %n dienasPrieš %n dienų + + + + Up to date + Iki šiol + + + + Catching up... + Gaudo... + + + + Last received block was generated %1. + Paskutinis gautas blokas buvo sukurtas %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Šis sandoris viršija leistiną dydį. Jūs galite įvykdyti jį papildomai sumokėję %1 mokesčių, kurie bus išsiųsti tais pačiais mazgais kuriais vyko sandoris ir padės palaikyti tinklą. Ar jūs norite apmokėti papildomą mokestį? + + + + Confirm transaction fee + + + + + Sent transaction + Sandoris nusiųstas + + + + Incoming transaction + Ateinantis sandoris + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Data: %1 +Suma: %2 +Tipas: %3 +Adresas: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Piniginė <b>užšifruota</b> ir šiuo metu <b>atrakinta</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Piniginė <b>užšifruota</b> ir šiuo metu <b>užrakinta</b> + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Ekranas + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Rodomų ir siunčiamų monetų kiekio matavimo vienetai + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Redaguoti adresą + + + + &Label + &L Žymė + + + + The label associated with this address book entry + Žymė yra susieta su šios adresų knygelęs turiniu + + + + &Address + &Adresas + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Adresas yra susietas su šios adresų knygelęs turiniu. Tai gali būti keičiama tik siuntimo adresams. + + + + New receiving address + Naujas gavimo adresas + + + + New sending address + Naujas siuntimo adresas + + + + Edit receiving address + Taisyti gavimo adresą + + + + Edit sending address + Taisyti siuntimo adresą + + + + The entered address "%1" is already in the address book. + Įvestas adresas "%1"yra adresų knygelėje + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Neįmanoma atrakinti piniginės + + + + New key generation failed. + Naujas raktas nesukurtas + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Naudojimas: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + Pradžia sumažinta + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + &f Mokėti sandorio mokestį + + + + Main + Pagrindinis + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Neprivaloma sandorio mokestis už KB, kuris padeda įsitikinti, kad jūsų sandoriai tvarkomi greitai. Daugelis sandorių yra tik 1KB dydžio. Rekomenduojamas 0,01 mokestis. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + Pasirinkite adresą iš adresų knygelės + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Įvesti adresą iš mainų atminties + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Įveskite pranešimą, kurį norite pasirašyti čia + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Spragtelėkite "Registruotis žinutę" tam, kad gauti parašą + + + + Sign a message to prove you own this address + Registruotis žinute įrodymuii, kad turite šį adresą + + + + &Sign Message + &S Registravimosi žinutė + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Įveskite bitkoinų adresą (pvz. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Klaida pasirašant + + + + %1 is not a valid address. + %1 tai negaliojantis adresas + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Privataus rakto %1 nėra + + + + Sign failed + Registravimas nepavyko + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Prievado struktūra naudojant & UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Automatiškai atidaryti Bitcoin kliento maršrutizatoriaus prievadą. Tai veikia tik tada, kai jūsų maršrutizatorius palaiko UPnP ir ji įjungta. + + + + &Connect through SOCKS4 proxy: + &C Jungtis per socks4 proxy: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Jungtis į Bitkoin tinklą per socks4 proxy (pvz. jungiantis per Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + IP adresas proxy (pvz. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Proxy prievadas (pvz. 1234) + + + + OptionsDialog + + + Options + Opcijos + + + + OverviewPage + + + Form + Forma + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Balansas + + + + Number of transactions: + Sandorių kiekis + + + + Unconfirmed: + Nepatvirtinti: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Naujausi sandoris</b> + + + + Your current balance + Jūsų einamasis balansas + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Iš viso sandorių, įskaitant tuos kurie dar turi būti patvirtinti, ir jie dar nėra įskaičiuotii į einamosios sąskaitos balansą + + + + Total number of transactions in wallet + Bandras sandorių kiekis piniginėje + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + QR kodas + + + + Request Payment + Prašau išmokėti + + + + Amount: + Suma: + + + + BTC + BTC + + + + Label: + Žymė: + + + + Message: + Žinutė: + + + + &Save As... + &S išsaugoti kaip... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Siųsti monetas + + + + Send to multiple recipients at once + Siųsti keliems gavėjams vienu metu + + + + &Add Recipient + + + + + Remove all transaction fields + Pašalinti visus sandorio laukus + + + + Clear &All + + + + + Balance: + Balansas: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Patvirtinti siuntimo veiksmą + + + + &Send + &Siųsti + + + + <b>%1</b> to %2 (%3) + <b>%1</b> to %2 (%3) + + + + Confirm send coins + Patvirtinti siuntimui monetas + + + + Are you sure you want to send %1? + Ar esate įsitikinę, kad norite siųsti %1? + + + + and + ir + + + + The recepient address is not valid, please recheck. + Negaliojantis gavėjo adresas. Patikrinkite. + + + + The amount to pay must be larger than 0. + Apmokėjimo suma turi būti didesnė negu 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Forma + + + + A&mount: + Su&ma: + + + + Pay &To: + Mokėti &T gavėjui: + + + + + Enter a label for this address to add it to your address book + Įveskite žymę šiam adresui kad galėtumėte įtraukti ją į adresų knygelę + + + + &Label: + &L žymė: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adresas mokėjimo siuntimui (pvz. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Pasirinkite adresą iš adresų knygelės + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Įvesti adresą iš mainų atminties + + + + Alt+P + Alt+P + + + + Remove this recipient + Pašalinti šitą gavėją + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Įveskite bitkoinų adresą (pvz. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Atidaryta %1 blokams + + + + Open until %1 + Atidaryta iki %1 + + + + %1/offline? + %1/atjungtas? + + + + %1/unconfirmed + %1/nepatvirtintas + + + + %1 confirmations + %1 patvirtinimai + + + + <b>Status:</b> + <b>Būsena:</b> + + + + , has not been successfully broadcast yet + , transliavimas dar nebuvo sėkmingas + + + + , broadcast through %1 node + , transliuota per %1 mazgą + + + + , broadcast through %1 nodes + , transliuota per %1 mazgus + + + + <b>Date:</b> + <b>Data:</b> + + + + <b>Source:</b> Generated<br> + <b>Šaltinis:</b> Sukurta<br> + + + + + <b>From:</b> + <b>Nuo:</b> + + + + unknown + nežinomas + + + + + + <b>To:</b> + <b>Skirta:</b> + + + + (yours, label: + (jūsų, žymė: + + + + (yours) + (jūsų) + + + + + + + <b>Credit:</b> + <b>Kreditas:</b> + + + + (%1 matures in %2 more blocks) + (%1 apmokėtinas %2 daugiau blokais) + + + + (not accepted) + (nepriimta) + + + + + + <b>Debit:</b> + <b>Debitas:</b> + + + + <b>Transaction fee:</b> + <b>Sandorio mokestis:</b> + + + + <b>Net amount:</b> + <b>Neto suma:</b> + + + + Message: + Žinutė: + + + + Comment: + Komentaras: + + + + Transaction ID: + Sandorio ID: + + + + 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. + Išgautos monetos turi sulaukti 120 blokų, kol jos gali būti naudojamos. Kai sukūrėte šį bloką, jis buvo transliuojamas tinkle ir turėjo būti įtrauktas į blokų grandinę. Jei nepavyksta patekti į grandinę, bus pakeista į "nepriėmė", o ne "vartojamas". Tai kartais gali atsitikti, jei kitas mazgas per keletą sekundžių sukuria bloką po jūsų bloko. + + + + TransactionDescDialog + + + Transaction details + Sandorio išsami informacija + + + + This pane shows a detailed description of the transaction + Šis langas sandorio detalų aprašymą + + + + TransactionTableModel + + + Date + Data + + + + Type + Tipas + + + + Address + Adresas + + + + Amount + Suma + + + + Open for %n block(s) + Atidaryta %n blokuiAtidaryta %n blokamsAtidaryta %n blokų + + + + Open until %1 + Atidaryta kol %n + + + + Offline (%1 confirmations) + Atjungta (%1 patvirtinimai) + + + + Unconfirmed (%1 of %2 confirmations) + Nepatvirtintos (%1 iš %2 patvirtinimų) + + + + Confirmed (%1 confirmations) + Patvirtinta (%1 patvirtinimai) + + + + Mined balance will be available in %n more blocks + Išgautas balansas bus pasiekiamas po %n blokoIšgautas balansas bus pasiekiamas po %n blokųIšgautas balansas bus pasiekiamas po %n blokų + + + + This block was not received by any other nodes and will probably not be accepted! + Šis blokas negautas nė vienu iš mazgų ir matomai nepriimtas + + + + Generated but not accepted + Išgauta bet nepriimta + + + + Received with + Gauta su + + + + Received from + Gauta iš + + + + Sent to + Siųsta + + + + Payment to yourself + Mokėjimas sau + + + + Mined + Išgauta + + + + (n/a) + nepasiekiama + + + + Transaction status. Hover over this field to show number of confirmations. + Sandorio būklė. Užvedus pelės žymeklį ant šios srities matysite patvirtinimų skaičių. + + + + Date and time that the transaction was received. + Sandorio gavimo data ir laikas + + + + Type of transaction. + Sandorio tipas + + + + Destination address of transaction. + Sandorio paskirties adresas + + + + Amount removed from or added to balance. + Suma pridėta ar išskaičiuota iš balanso + + + + TransactionView + + + + All + Visi + + + + Today + Šiandien + + + + This week + Šią savaitę + + + + This month + Šį mėnesį + + + + Last month + Paskutinį mėnesį + + + + This year + Šiais metais + + + + Range... + Grupė + + + + Received with + Gauta su + + + + Sent to + Išsiųsta + + + + To yourself + Skirta sau + + + + Mined + Išgauta + + + + Other + Kita + + + + Enter address or label to search + Įveskite adresą ar žymę į paiešką + + + + Min amount + Minimali suma + + + + Copy address + Kopijuoti adresą + + + + Copy label + Kopijuoti žymę + + + + Copy amount + Kopijuoti sumą + + + + Edit label + Taisyti žymę + + + + Show transaction details + + + + + Export Transaction Data + Sandorio duomenų eksportavimas + + + + Comma separated file (*.csv) + Kableliais atskirtų duomenų failas (*.csv) + + + + Confirmed + Patvirtintas + + + + Date + Data + + + + Type + Tipas + + + + Label + Žymė + + + + Address + Adresas + + + + Amount + Suma + + + + ID + ID + + + + Error exporting + Eksportavimo klaida + + + + Could not write to file %1. + Neįmanoma įrašyti į failą %1. + + + + Range: + Grupė: + + + + to + skirta + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Kopijuoti pasirinktą adresą į sistemos mainų atmintį + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Siunčiama + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &M sumažinti langą bet ne užduočių juostą + + + + Show only a tray icon after minimizing the window + Po programos lango sumažinimo rodyti tik programos ikoną. + + + + M&inimize on close + + + + + 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. + Uždarant langą neuždaryti programos. Kai ši parinktis įjungta, programa bus uždaryta tik pasirinkus meniu komandą Baigti. + + + + bitcoin-core + + + Bitcoin version + Bitcoin versija + + + + Usage: + Naudojimas: + + + + Send command to -server or bitcoind + Siųsti komandą serveriui arba bitcoind + + + + List commands + Komandų sąrašas + + + + Get help for a command + Suteikti pagalba komandai + + + + Options: + Opcijos: + + + + Specify configuration file (default: bitcoin.conf) + Nurodyti konfigūracijos failą (pagal nutylėjimąt: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Nurodyti pid failą (pagal nutylėjimą: bitcoind.pid) + + + + Generate coins + Sukurti monetas + + + + Don't generate coins + Neišgavinėti monetų + + + + Specify data directory + Nustatyti duomenų direktoriją + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Nustatyti sujungimo trukmę (milisekundėmis) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Sujungimo klausymas prijungčiai <port> (pagal nutylėjimą: 8333 arba testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Palaikyti ne daugiau <n> jungčių kolegoms (pagal nutylėjimą: 125) + + + + Connect only to the specified node + Prisijungti tik prie nurodyto mazgo + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Atjungimo dėl netinkamo kolegų elgesio riba (pagal nutylėjimą: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Sekundžių kiekis eikiamas palaikyti ryšį dėl lygiarangių nestabilumo (pagal nutylėjimą: 86.400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maksimalus buferis priėmimo sujungimui <n>*1000 bitų (pagal nutylėjimą: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maksimalus buferis siuntimo sujungimui <n>*1000 bitų (pagal nutylėjimą: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Priimti komandinę eilutę ir JSON-RPC komandas + + + + Run in the background as a daemon and accept commands + Dirbti fone kaip šešėlyje ir priimti komandas + + + + Use the test network + Naudoti testavimo tinklą + + + + Output extra debugging information + Išėjimo papildomas derinimo informacija + + + + Prepend debug output with timestamp + Prideėti laiko žymę derinimo rezultatams + + + + Send trace/debug info to console instead of debug.log file + Siųsti atsekimo/derinimo info į konsolę vietoj debug.log failo + + + + Send trace/debug info to debugger + Siųsti sekimo/derinimo info derintojui + + + + Username for JSON-RPC connections + Vartotojo vardas JSON-RPC jungimuisi + + + + Password for JSON-RPC connections + Slaptažodis JSON-RPC sujungimams + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Klausymas JSON-RPC sujungimui prijungčiai <port> (pagal nutylėjimą: 8332) + + + + Allow JSON-RPC connections from specified IP address + Leisti JSON-RPC tik iš nurodytų IP adresų + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Siųsti komandą mazgui dirbančiam <ip> (pagal nutylėjimą: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + Nustatyti rakto apimties dydį <n> (pagal nutylėjimą: 100) + + + + Rescan the block chain for missing wallet transactions + Ieškoti prarastų piniginės sandorių blokų grandinėje + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + SSL opcijos (žr.e Bitcoin Wiki for SSL setup instructions) + + + + Use OpenSSL (https) for JSON-RPC connections + Naudoti OpenSSL (https) jungimuisi JSON-RPC + + + + Server certificate file (default: server.cert) + Serverio sertifikato failas (pagal nutylėjimą: server.cert) + + + + Server private key (default: server.pem) + Serverio privatus raktas (pagal nutylėjimą: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Priimtini šifrai (pagal nutylėjimą: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + Pagelbos žinutė + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Negali gauti duomenų katalogo %s rakto. Bitcoin tikriausiai jau veikia. + + + + Bitcoin + + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Užkraunami adresai... + + + + Error loading blkindex.dat + blkindex.dat pakrovimo klaida + + + + Error loading wallet.dat: Wallet corrupted + wallet.dat pakrovimo klaida, wallet.dat sugadintas + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + wallet.dat pakrovimo klaida, wallet.dat reikalauja naujasnės Bitcoin versijos + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Piniginė turi būti prrašyta: įvykdymui perkraukite Bitcoin + + + + Error loading wallet.dat + wallet.dat pakrovimo klaida + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + KLAIDA:nepavyko sudaryti sandorio + + + + Sending... + Siunčiama + + + + 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. + Klaida: sandoris buvo atmestas.Tai gali įvykti, jei kai kurios monetos iš jūsų piniginėje jau buvo panaudotos, pvz. jei naudojote wallet.dat kopiją ir monetos buvo išleistos kopijoje, bet nepažymėtos kaip skirtos išleisti čia. + + + + Invalid amount + + + + + Insufficient funds + + + + + Loading block index... + Užkraunami blokų indeksai... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Užkraunama piniginė... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Peržiūra + + + + Done loading + Pakrovimas baigtas + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Įspėjimas: Patikrinkite, kad kompiuterio data ir laikas yra teisingi.Jei Jūsų laikrodis neteisingai nustatytas Bitcoin, veiks netinkamai. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts new file mode 100644 index 0000000..8f32f6b --- /dev/null +++ b/src/qt/locale/bitcoin_nb.ts @@ -0,0 +1,2521 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Om Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> versjon + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Bitcoin Utviklerne + +Dette er eksperimentell programvare. + +Distribuert under MIT/X11 programvarelisensen, se medfølgende fil license.txt eller http://www.opensource.org/licenses/mit-license.php. + +Dette produktet inneholder programvare utviklet av OpenSSL prosjektet for bruk i OpenSSL Toolkit (http://www.openssl.org/) og kryptografisk programvare skrevet av Eric Young (eay@cryptsoft.com) og UPnP programvare skrevet av Thomas Bernard. + + + + AddressBookPage + + + Address Book + Adressebok + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Dette er dine Bitcoin adresser for å motta betalinger. Du kan gi en separat adresse til hver avsender slik at du kan holde oversikt over hvem som betaler deg. + + + + Double-click to edit address or label + Dobbeltklikk for å redigere adresse eller merkelapp + + + + Create a new address + Lag en ny adresse + + + + Copy the currently selected address to the system clipboard + Kopier den valgte adressen til systemets utklippstavle + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Vis &QR Kode + + + + Sign a message to prove you own this address + Signér en melding for å bevise at du eier denne adressen + + + + &Sign Message + &Signér Melding + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Slett den valgte adressen fra listen. Bare adresser for sending kan slettes. + + + + &Delete + &Slett + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Eksporter adressebok + + + + Comma separated file (*.csv) + Kommaseparert fil (*.csv) + + + + Error exporting + Feil ved eksportering + + + + Could not write to file %1. + Kunne ikke skrive til filen %1. + + + + AddressTableModel + + + Label + Merkelapp + + + + Address + Adresse + + + + (no label) + (ingen merkelapp) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Angi adgangsfrase + + + + New passphrase + Ny adgangsfrase + + + + Repeat new passphrase + Gjenta ny adgangsfrase + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Skriv inn den nye adgangsfrasen for lommeboken.<br/>Vennligst bruk en adgangsfrase med <b>10 eller flere tilfeldige tegn</b>, eller <b>åtte eller flere ord</b>. + + + + Encrypt wallet + Krypter lommebok + + + + This operation needs your wallet passphrase to unlock the wallet. + Denne operasjonen krever adgangsfrasen til lommeboken for å låse den opp. + + + + Unlock wallet + Lås opp lommebok + + + + This operation needs your wallet passphrase to decrypt the wallet. + Denne operasjonen krever adgangsfrasen til lommeboken for å dekryptere den. + + + + Decrypt wallet + Dekrypter lommebok + + + + Change passphrase + Endre adgangsfrase + + + + Enter the old and new passphrase to the wallet. + Skriv inn gammel og ny adgangsfrase for lommeboken. + + + + Confirm wallet encryption + Bekreft kryptering av lommebok + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ADVARSEL: Hvis du krypterer lommeboken og mister adgangsfrasen vil du <b>MISTE ALLE DINE BITCOINS</b>! +Er du sikker på at du vil kryptere lommeboken? + + + + + Wallet encrypted + Lommebok kryptert + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin vil nå lukkes for å fullføre krypteringsprosessen. Husk at kryptering av lommeboken ikke fullt ut kan beskytte dine bitcoins fra å bli stjålet om skadevare infiserer datamaskinen. + + + + + Warning: The Caps Lock key is on. + Advarsel: Caps lock tasten er på. + + + + + + + Wallet encryption failed + Kryptering av lommebok feilet + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Kryptering av lommebok feilet på grunn av en intern feil. Din lommebok ble ikke kryptert. + + + + + The supplied passphrases do not match. + De angitte adgangsfrasene er ulike. + + + + Wallet unlock failed + Opplåsing av lommebok feilet + + + + + + The passphrase entered for the wallet decryption was incorrect. + Adgangsfrasen angitt for dekryptering av lommeboken var feil. + + + + Wallet decryption failed + Dekryptering av lommebok feilet + + + + Wallet passphrase was succesfully changed. + Lommebokens adgangsfrase ble endret. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin Lommebok + + + + Sign &message... + + + + + Show/Hide &Bitcoin + Gjem/vis &Bitcoin + + + + Synchronizing with network... + Synkroniserer med nettverk... + + + + &Overview + &Oversikt + + + + Show general overview of wallet + Vis generell oversikt over lommeboken + + + + &Transactions + &Transaksjoner + + + + Browse transaction history + Vis transaksjonshistorikk + + + + &Address Book + &Adressebok + + + + Edit the list of stored addresses and labels + Rediger listen over adresser og deres merkelapper + + + + &Receive coins + &Motta bitcoins + + + + Show the list of addresses for receiving payments + Vis listen over adresser for mottak av betalinger + + + + &Send coins + &Send bitcoins + + + + Prove you control an address + Bevis at du kontrollerer en adresse + + + + E&xit + &Avslutt + + + + Quit application + Avslutt applikasjonen + + + + &About %1 + &Om %1 + + + + Show information about Bitcoin + Vis informasjon om Bitcoin + + + + About &Qt + Om &Qt + + + + Show information about Qt + Vis informasjon om Qt + + + + &Options... + &Innstillinger... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + ~%n blokk gjenstår~%n blokker gjenstår + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Lastet ned %1 av %2 blokker med transaksjonshistorikk (%3% ferdig). + + + + &Export... + &Eksporter... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Vis eller gjem Bitcoinvinduet + + + + Export the data in the current tab to a file + Eksporter data fra nåværende fane til fil + + + + Encrypt or decrypt wallet + Krypter eller dekrypter lommebok + + + + Backup wallet to another location + Sikkerhetskopiér lommebok til annet sted + + + + Change the passphrase used for wallet encryption + Endre adgangsfrasen brukt for kryptering av lommebok + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Fil + + + + &Settings + &Innstillinger + + + + &Help + &Hjelp + + + + Tabs toolbar + Verktøylinje for faner + + + + Actions toolbar + Verktøylinje for handlinger + + + + + [testnet] + [testnett] + + + + + Bitcoin client + Bitcoinklient + + + + %n active connection(s) to Bitcoin network + %n aktiv forbindelse til Bitcoin-nettverket%n aktive forbindelser til Bitcoin-nettverket + + + + Downloaded %1 blocks of transaction history. + Lastet ned %1 blokker med transaksjonshistorikk. + + + + %n second(s) ago + for %n sekund sidenfor %n sekunder siden + + + + %n minute(s) ago + for %n minutt sidenfor %n minutter siden + + + + %n hour(s) ago + for %n time sidenfor %n timer siden + + + + %n day(s) ago + for %n dag sidenfor %n dager siden + + + + Up to date + Ajour + + + + Catching up... + Kommer ajour... + + + + Last received block was generated %1. + Siste mottatte blokk ble generert %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Denne transaksjonen overstiger størrelsesbegrensningen. Du kan likevel sende den med et gebyr på %1, som går til nodene som prosesserer transaksjonen din og støtter nettverket. Vil du betale gebyret? + + + + Confirm transaction fee + + + + + Sent transaction + Sendt transaksjon + + + + Incoming transaction + Innkommende transaksjon + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Dato: %1 +Beløp: %2 +Type: %3 +Adresse: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Lommeboken er <b>kryptert</b> og for tiden <b>ulåst</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Lommeboken er <b>kryptert</b> og for tiden <b>låst</b> + + + + Backup Wallet + Sikkerhetskopiér Lommebok + + + + Wallet Data (*.dat) + Lommeboksdata (*.dat) + + + + Backup Failed + Sikkerhetskopiering feilet + + + + There was an error trying to save the wallet data to the new location. + En feil oppstod ved lagring av lommebok til nytt sted + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Visning + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Velg standard underenhet som skal vises i grensesnittet og ved sending av mynter + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Rediger adresse + + + + &Label + &Merkelapp + + + + The label associated with this address book entry + Merkelappen koblet til denne adressen i adresseboken + + + + &Address + &Adresse + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Adressen til denne oppføringen i adresseboken. Denne kan kun endres for utsendingsadresser. + + + + New receiving address + Ny mottaksadresse + + + + New sending address + Ny utsendingsadresse + + + + Edit receiving address + Rediger mottaksadresse + + + + Edit sending address + Rediger utsendingsadresse + + + + The entered address "%1" is already in the address book. + Den oppgitte adressen "%1" er allerede i adresseboken. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Kunne ikke låse opp lommeboken. + + + + New key generation failed. + Generering av ny nøkkel feilet. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Bruk: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + Sett språk, for eksempel "nb_NO" (standardverdi: fra operativsystem) + + + + Start minimized + Start minimert + + + + + Show splash screen on startup (default: 1) + Vis splashskjerm ved oppstart (standardverdi: 1) + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Betal transaksjons&gebyr + + + + Main + Hoved + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Valgfritt transaksjonsgebyr per kB som sikrer at dine transaksjoner blir raskt prosessert. De fleste transaksjoner er 1 kB. Et gebyr på 0.01 er anbefalt. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Du kan signere meldinger med dine adresser for å bevise at du eier dem. Ikke signér vage meldinger da phishing-angrep kan prøve å lure deg til å signere din identitet over til andre. Signér kun fullt detaljerte utsagn som du er enig i. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adressen meldingen skal signeres med (f.eks. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Velg adresse fra adresseboken + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Lim inn adresse fra utklippstavlen + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Skriv inn meldingen du vil signere her + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Klikk "Signér Melding" for signatur + + + + Sign a message to prove you own this address + Signér en melding for å bevise at du eier denne adressen + + + + &Sign Message + &Signér Melding + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Skriv inn en Bitcoin adresse (f.eks. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Feil ved signering + + + + %1 is not a valid address. + %1 er ikke en gyldig adresse + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Privat nøkkel for %1 er ikke tilgjengelig. + + + + Sign failed + Signering feilet + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Sett opp port vha. &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Åpne automatisk Bitcoin klientporten på ruteren. Dette virker kun om din ruter støtter UPnP og dette er påslått. + + + + &Connect through SOCKS4 proxy: + &Koble til gjennom SOCKS4 proxy: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Koble til Bitcoin nettverket gjennom en SOCKS4 mellomtjener (f.eks. for tilkobling gjennom Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + IP-adresse for mellomtjener (f.eks. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Port for mellomtjener (f.eks. 1234) + + + + OptionsDialog + + + Options + Innstillinger + + + + OverviewPage + + + Form + Skjema + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Saldo: + + + + Number of transactions: + Antall transaksjoner: + + + + Unconfirmed: + Ubekreftet + + + + Wallet + Lommebok + + + + <b>Recent transactions</b> + <b>Siste transaksjoner</b> + + + + Your current balance + Din nåværende saldo + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Totalt antall ubekreftede transaksjoner som ikke telles med i saldo enda + + + + Total number of transactions in wallet + Totalt antall transaksjoner i lommeboken + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + QR Kode + + + + Request Payment + Etterspør Betaling + + + + Amount: + Beløp: + + + + BTC + BTC + + + + Label: + Merkelapp: + + + + Message: + Melding: + + + + &Save As... + &Lagre Som... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + Resulterende URI for lang, prøv å redusere teksten for merkelapp / melding. + + + + Save QR Code + + + + + PNG Images (*.png) + PNG bilder (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Send Bitcoins + + + + Send to multiple recipients at once + Send til flere enn én mottaker + + + + &Add Recipient + + + + + Remove all transaction fields + Fjern alle transaksjonsfelter + + + + Clear &All + + + + + Balance: + Saldo: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Bekreft sending + + + + &Send + &Send + + + + <b>%1</b> to %2 (%3) + <b>%1</b> til %2 (%3) + + + + Confirm send coins + Bekreft sending av bitcoins + + + + Are you sure you want to send %1? + Er du sikker på at du vil sende %1? + + + + and + og + + + + The recepient address is not valid, please recheck. + Mottaksadressen er ugyldig, prøv igjen. + + + + The amount to pay must be larger than 0. + Beløpen som skal betales må være over 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Skjema + + + + A&mount: + &Beløp: + + + + Pay &To: + Betal &Til: + + + + + Enter a label for this address to add it to your address book + Skriv inn en merkelapp for denne adressen for å legge den til i din adressebok + + + + &Label: + &Merkelapp: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adressen betalingen skal sendes til (f.eks. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Velg adresse fra adresseboken + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Lim inn adresse fra utklippstavlen + + + + Alt+P + Alt+P + + + + Remove this recipient + Fjern denne mottakeren + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Skriv inn en Bitcoin adresse (f.eks. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Åpen for %1 blokker + + + + Open until %1 + Åpen til %1 + + + + %1/offline? + %1/frakoblet? + + + + %1/unconfirmed + %1/ubekreftet + + + + %1 confirmations + %1 bekreftelser + + + + <b>Status:</b> + <b>Status:</b> + + + + , has not been successfully broadcast yet + , har ikke blitt kringkastet uten problemer enda. + + + + , broadcast through %1 node + , kringkast gjennom %1 node + + + + , broadcast through %1 nodes + , kringkast gjennom %1 noder + + + + <b>Date:</b> + <b>Dato:</b> + + + + <b>Source:</b> Generated<br> + <b>Kilde:</b> Generert<br> + + + + + <b>From:</b> + <b>Fra:</b> + + + + unknown + ukjent + + + + + + <b>To:</b> + <b>Til:</b> + + + + (yours, label: + (din, merkelapp: + + + + (yours) + (din) + + + + + + + <b>Credit:</b> + <b>Kredit:</b> + + + + (%1 matures in %2 more blocks) + (%1 modnes om %2 flere blokker) + + + + (not accepted) + (ikke akseptert) + + + + + + <b>Debit:</b> + <b>Debet:</b> + + + + <b>Transaction fee:</b> + <b>Transaksjonsgebyr:</b> + + + + <b>Net amount:</b> + <b>Nettobeløp:</b> + + + + Message: + Melding: + + + + Comment: + Kommentar: + + + + Transaction ID: + Transaksjons-ID: + + + + 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. + Genererte mynter må vente 120 blokker før de kan brukes. Da du genererte denne blokken ble den kringkastet på nettverket for å bli lagt til i kjeden av blokker. Hvis den ikke kommer med i kjeden vil den endre seg til "ikke akseptert og pengene vil ikke kunne brukes. Dette vil noen ganger skje hvis en annen node genererer en blokk noen sekunder i tid fra din egen. + + + + TransactionDescDialog + + + Transaction details + Transaksjonsdetaljer + + + + This pane shows a detailed description of the transaction + Her vises en detaljert beskrivelse av transaksjonen + + + + TransactionTableModel + + + Date + Dato + + + + Type + Type + + + + Address + Adresse + + + + Amount + Beløp + + + + Open for %n block(s) + Åpen for %n blokkÅpen for %n blokker + + + + Open until %1 + Åpen til %1 + + + + Offline (%1 confirmations) + Frakoblet (%1 bekreftelser) + + + + Unconfirmed (%1 of %2 confirmations) + Ubekreftet (%1 av %2 bekreftelser) + + + + Confirmed (%1 confirmations) + Bekreftet (%1 bekreftelser) + + + + Mined balance will be available in %n more blocks + Utvunnet saldo vil bli tilgjengelig om %n blokkUtvunnet saldo vil bli tilgjengelig om %n blokker + + + + This block was not received by any other nodes and will probably not be accepted! + Denne blokken har ikke blitt mottatt av noen andre noder og vil sannsynligvis ikke bli akseptert! + + + + Generated but not accepted + Generert men ikke akseptert + + + + Received with + Mottatt med + + + + Received from + Mottatt fra + + + + Sent to + Sendt til + + + + Payment to yourself + Betaling til deg selv + + + + Mined + Utvunnet + + + + (n/a) + - + + + + Transaction status. Hover over this field to show number of confirmations. + Transaksjonsstatus. Hold muspekeren over dette feltet for å se antall bekreftelser. + + + + Date and time that the transaction was received. + Dato og tid for da transaksjonen ble mottat. + + + + Type of transaction. + Type transaksjon. + + + + Destination address of transaction. + Mottaksadresse for transaksjonen + + + + Amount removed from or added to balance. + Beløp fjernet eller lagt til saldo. + + + + TransactionView + + + + All + Alle + + + + Today + I dag + + + + This week + Denne uken + + + + This month + Denne måneden + + + + Last month + Forrige måned + + + + This year + Dette året + + + + Range... + Intervall... + + + + Received with + Mottatt med + + + + Sent to + Sendt til + + + + To yourself + Til deg selv + + + + Mined + Utvunnet + + + + Other + Andre + + + + Enter address or label to search + Skriv inn adresse eller merkelapp for søk + + + + Min amount + Minimumsbeløp + + + + Copy address + Kopier adresse + + + + Copy label + Kopier merkelapp + + + + Copy amount + Kopiér beløp + + + + Edit label + Rediger merkelapp + + + + Show transaction details + + + + + Export Transaction Data + Eksporter transaksjonsdata + + + + Comma separated file (*.csv) + Kommaseparert fil (*.csv) + + + + Confirmed + Bekreftet + + + + Date + Dato + + + + Type + Type + + + + Label + Merkelapp + + + + Address + Adresse + + + + Amount + Beløp + + + + ID + ID + + + + Error exporting + Feil ved eksport + + + + Could not write to file %1. + Kunne ikke skrive til filen %1. + + + + Range: + Intervall: + + + + to + til + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Kopier den valgte adressen til systemets utklippstavle + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Sender... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Minimer til systemkurv istedenfor oppgavelinjen + + + + Show only a tray icon after minimizing the window + Vis kun ikon i systemkurv etter minimering av vinduet + + + + M&inimize on close + + + + + 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. + Minimerer vinduet istedenfor å avslutte applikasjonen når vinduet lukkes. Når dette er slått på avsluttes applikasjonen kun ved å velge avslutt i menyen. + + + + bitcoin-core + + + Bitcoin version + Bitcoin versjon + + + + Usage: + Bruk: + + + + Send command to -server or bitcoind + Send kommando til -server eller bitcoind + + + + List commands + List opp kommandoer + + + + Get help for a command + Vis hjelpetekst for en kommando + + + + Options: + Innstillinger: + + + + Specify configuration file (default: bitcoin.conf) + Angi konfigurasjonsfil (standardverdi: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Angi pid-fil (standardverdi: bitcoind.pid) + + + + Generate coins + Generér bitcoins + + + + Don't generate coins + Ikke generér bitcoins + + + + Specify data directory + Angi mappe for datafiler + + + + Set database cache size in megabytes (default: 25) + Sett størrelse på mellomlager for database i megabytes (standardverdi: 25) + + + + Set database disk log size in megabytes (default: 100) + Sett størrelse på disklogg for database i megabytes (standardverdi: 100) + + + + Specify connection timeout (in milliseconds) + Angi tidsavbrudd for forbindelse (i millisekunder) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Lytt etter tilkoblinger på <port> (standardverdi: 8333 eller testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Hold maks <n> koblinger åpne til andre noder (standardverdi: 125) + + + + Connect only to the specified node + Koble kun til angitt node + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Grenseverdi for å koble fra noder med dårlig oppførsel (standardverdi: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Antall sekunder noder med dårlig oppførsel hindres fra å koble til på nytt (standardverdi: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maksimum mottaksbuffer per tilkobling, <n>*1000 bytes (standardverdi: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maksimum sendebuffer per tilkobling, <n>*1000 bytes (standardverdi: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Ta imot kommandolinje- og JSON-RPC-kommandoer + + + + Run in the background as a daemon and accept commands + Kjør i bakgrunnen som daemon og ta imot kommandoer + + + + Use the test network + Bruk testnettverket + + + + Output extra debugging information + Gi ut ekstra debuginformasjon + + + + Prepend debug output with timestamp + Sett tidsstempel på debugmeldinger + + + + Send trace/debug info to console instead of debug.log file + Send spor/debug informasjon til konsollet istedenfor debug.log filen + + + + Send trace/debug info to debugger + Send spor/debug informasjon til debugger + + + + Username for JSON-RPC connections + Brukernavn for JSON-RPC forbindelser + + + + Password for JSON-RPC connections + Passord for JSON-RPC forbindelser + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Lytt etter JSON-RPC tilkoblinger på <port> (standardverdi: 8332) + + + + Allow JSON-RPC connections from specified IP address + Tillat JSON-RPC tilkoblinger fra angitt IP-adresse + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Send kommandoer til node på <ip> (standardverdi: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Eksekvér kommando når beste blokk endrer seg (%s i kommandoen erstattes med blokkens hash) + + + + Upgrade wallet to latest format + Oppgradér lommebok til nyeste format + + + + Set key pool size to <n> (default: 100) + Angi størrelse på nøkkel-lager til <n> (standardverdi: 100) + + + + Rescan the block chain for missing wallet transactions + Se gjennom blokk-kjeden etter manglende lommeboktransaksjoner + + + + How many blocks to check at startup (default: 2500, 0 = all) + Hvor mange blokker som skal sjekkes ved oppstart (standardverdi: 2500, 0 = alle) + + + + How thorough the block verification is (0-6, default: 1) + Hvor grundig verifisering av blokker gjøres (0-6, standardverdi: 1) + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL innstillinger: (se Bitcoin Wiki for instruksjoner om SSL oppsett) + + + + Use OpenSSL (https) for JSON-RPC connections + Bruk OpenSSL (https) for JSON-RPC forbindelser + + + + Server certificate file (default: server.cert) + Servers sertifikat (standardverdi: server.cert) + + + + Server private key (default: server.pem) + Servers private nøkkel (standardverdi: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Akseptable krypteringsmetoder (standardverdi: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + Denne hjelpemeldingen + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Kunne ikke låse datamappen %s. Bitcoin kjører sannsynligvis allerede. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Laster adresser... + + + + Error loading blkindex.dat + Feil ved lasting av blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Feil ved lasting av wallet.dat: Lommeboken er skadet + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Feil ved lasting av wallet.dat: Lommeboken krever en nyere versjon av Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Lommeboken måtte skrives om: start Bitcoin på nytt for å fullføre + + + + Error loading wallet.dat + Feil ved lasting av wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + Feil: Lommebok låst, kan ikke opprette transaksjon + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Feil: Denne transaksjonen krever et gebyr på minst %s pga. beløpet, kompleksiteten, eller bruk av nylig mottatte midler + + + + Error: Transaction creation failed + Feil: Opprettelse av transaksjon feilet + + + + Sending... + Sender... + + + + 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. + Feil: Transaksjonen ble avvist. Dette kan skje hvis noen av myntene i lommeboken allerede var brukt, f.eks. hvis du kopierte wallet.dat og mynter ble brukt i kopien uten å bli markert brukt her. + + + + Invalid amount + Ugyldig beløp + + + + Insufficient funds + Utilstrekkelige midler + + + + Loading block index... + Laster blokkindeks... + + + + Add a node to connect to and attempt to keep the connection open + Legg til node for tilkobling og hold forbindelsen åpen + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + Finn andre noder via internet relay chat (standardverdi: 0) + + + + Accept connections from outside (default: 1) + Ta imot innkommende forbindelser fra nettet (standardverdi: 1) + + + + Find peers using DNS lookup (default: 1) + Finn andre noder gjennom DNS-oppslag (standardverdi: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Bruk Universal Plug and Play for å sette opp lytteporten (standardverdi :1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Bruk Universal Plug and Play for å sette opp lytteporten (standardverdi :0) + + + + Fee per KB to add to transactions you send + Gebyr per KB for transaksjoner du sender + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Laster lommebok... + + + + Cannot downgrade wallet + Kan ikke nedgradere lommebok + + + + Cannot initialize keypool + Kan ikke initialisere nøkkellager + + + + Cannot write default address + Kan ikke skrive standardadresse + + + + Rescanning... + Leser gjennom... + + + + Done loading + Ferdig med lasting + + + + To use the %s option + For å bruke %s opsjonen + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, du må sette et rpcpassord i konfigurasjonsfilen: + %s +Det anbefales at du bruker følgende tilfeldige passord: +rpcuser=bitcoinrpc +rpcpassword=%s +(du trenger ikke huske dette passordet) +Hvis filen ikke finnes, opprett den med leserettighet kun for eier av filen. + + + + + Error + Feil + + + + An error occured while setting up the RPC port %i for listening: %s + En feil oppstod ved oppsett av RPC port %i for lytting: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Du må sette rpcpassword=<passord> i konfigurasjonsfilen: +%s +Hvis filen ikke finnes, opprett den med leserettighet kun for eier av filen. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Advarsel: Vennligst sjekk at dato og klokke er riktig innstilt på datamaskinen. Hvis klokken er feil vil ikke Bitcoin fungere ordentlig. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts new file mode 100644 index 0000000..8ffa769 --- /dev/null +++ b/src/qt/locale/bitcoin_nl.ts @@ -0,0 +1,2546 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Over Bitcoin + + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> versie + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Bitcoin Ontwikkelaars + +Dit is experimentele software. + +Gedistribueerd onder de MIT/X11 software licentie, zie het bijgevoegde bestand license.txt of http://www.opensource.org/licenses/mit-license.php. + +Dit product bevat software ontwikkeld door het OpenSSL Project voor gebruik in de OpenSSL Toolkit (http://www.openssl.org/) en cryptografische software gemaakt door Eric Young (eay@cryptsoft.com) en UPnP software geschreven door Thomas Bernard. + + + + AddressBookPage + + + Address Book + Adresboek + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Dit zijn uw Bitcoin-adressen om betalingen te ontvangen. U kunt er voor kiezen om een adres aan te maken voor elke afzender. Op deze manier kunt u bijhouden wie al aan u betaald heeft. + + + + Double-click to edit address or label + Dubbelklik om adres of label te wijzigen + + + + Create a new address + Maak een nieuw adres aan + + + + Copy the currently selected address to the system clipboard + Kopieer het huidig geselecteerde adres naar het klembord + + + + &New Address + &Nieuw Adres + + + + &Copy Address + &Kopiëer Adres + + + + Show &QR Code + Toon &QR-Code + + + + Sign a message to prove you own this address + Onderteken een bericht om te bewijzen dat u dit adres bezit + + + + &Sign Message + &Onderteken Bericht + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Verwijder het huidige geselecteerde adres van de lijst. Alleen zend-adressen kunnen verwijderd worden, niet uw ontvangstadressen. + + + + &Delete + &Verwijder + + + + Copy &Label + Kopiëer &Label + + + + &Edit + &Bewerk + + + + Export Address Book Data + Exporteer Gegevens van het Adresboek + + + + Comma separated file (*.csv) + Kommagescheiden bestand (*.csv) + + + + Error exporting + Fout bij exporteren + + + + Could not write to file %1. + Kon niet schrijven naar bestand %1. + + + + AddressTableModel + + + Label + Label + + + + Address + Adres + + + + (no label) + (geen label) + + + + AskPassphraseDialog + + + Passphrase Dialog + Wachtwoorddialoogscherm + + + + Enter passphrase + Huidig wachtwoord + + + + New passphrase + Nieuwe wachtwoord + + + + Repeat new passphrase + Herhaal wachtwoord + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Vul een nieuw wachtwoord in voor uw portemonnee. <br/> Gebruik een wachtwoord van <b>10 of meer lukrake karakters</b>, of <b> acht of meer woorden</b> . + + + + Encrypt wallet + Versleutel portemonnee + + + + This operation needs your wallet passphrase to unlock the wallet. + Deze operatie vereist uw portemonneewachtwoord om de portemonnee te openen. + + + + Unlock wallet + Open portemonnee + + + + This operation needs your wallet passphrase to decrypt the wallet. + Deze operatie vereist uw portemonneewachtwoord om de portemonnee te ontsleutelen + + + + Decrypt wallet + Ontsleutel portemonnee + + + + Change passphrase + Wijzig wachtwoord + + + + Enter the old and new passphrase to the wallet. + Vul uw oude en nieuwe portemonneewachtwoord in. + + + + Confirm wallet encryption + Bevestig versleuteling van de portemonnee + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + WAARSCHUWING: Wanneer uw portemonnee wordt versleuteld en u verliest uw wachtwoord, dan verliest u <b>AL UW BITCOINS</b>! +Bent u er zeker van uw dat u uw portemonnee wilt versleutelen? + + + + + Wallet encrypted + Portemonnee versleuteld + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin zal nu afsluiten om het versleutelingsproces te voltooien. Onthoud dat het versleutelen van uw portemonnee u niet volledig kan beschermen: Malware kan uw computer infecteren en uw bitcoins stelen. + + + + + Warning: The Caps Lock key is on. + Waarschuwing: De Caps-Lock-toets staat aan. + + + + + + + Wallet encryption failed + Portemonneeversleuteling mislukt + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Portemonneeversleuteling mislukt door een interne fout, Uw portemonnee is niet versleuteld. + + + + + The supplied passphrases do not match. + De opgegeven wachtwoorden komen niet overeen + + + + Wallet unlock failed + Portemonnee openen mislukt + + + + + + The passphrase entered for the wallet decryption was incorrect. + Het opgegeven wachtwoord voor de portemonnee-ontsleuteling is niet correct. + + + + Wallet decryption failed + Portemonnee-ontsleuteling mislukt + + + + Wallet passphrase was succesfully changed. + Portemonneewachtwoord is succesvol gewijzigd + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin-portemonnee + + + + Sign &message... + &Onderteken bericht... + + + + Show/Hide &Bitcoin + &Toon/Verberg Bitcoin + + + + Synchronizing with network... + Synchroniseren met netwerk... + + + + &Overview + &Overzicht + + + + Show general overview of wallet + Toon algemeen overzicht van de portemonnee + + + + &Transactions + &Transacties + + + + Browse transaction history + Blader door transactieverleden + + + + &Address Book + &Adresboek + + + + Edit the list of stored addresses and labels + Bewerk de lijst van opgeslagen adressen en labels + + + + &Receive coins + &Ontvang munten + + + + Show the list of addresses for receiving payments + Toon lijst van adressen om betalingen mee te ontvangen + + + + &Send coins + &Verstuur munten + + + + Prove you control an address + Bewijs dat u een adres bezit + + + + E&xit + &Afsluiten + + + + Quit application + Programma afsluiten + + + + &About %1 + &Over %1 + + + + Show information about Bitcoin + Laat informatie zien over Bitcoin + + + + About &Qt + Over &Qt + + + + Show information about Qt + Toon informatie over Qt + + + + &Options... + O&pties... + + + + &Encrypt Wallet... + &Versleutel Portemonnee... + + + + &Backup Wallet... + &Backup Portemonnee... + + + + &Change Passphrase... + &Wijzig Wachtwoord + + + + ~%n block(s) remaining + ~%n blok resterend~%n blokken resterend + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + %1 van %2 blokken van transactiehistorie opgehaald (%3% klaar). + + + + &Export... + &Exporteer... + + + + Send coins to a Bitcoin address + Verstuur munten naar een Bitcoinadres + + + + Modify configuration options for Bitcoin + Wijzig instellingen van Bitcoin + + + + Show or hide the Bitcoin window + Toon of verberg Bitcoin venster + + + + Export the data in the current tab to a file + Exporteer de data in de huidige tab naar een bestand + + + + Encrypt or decrypt wallet + Versleutel of ontsleutel portemonnee + + + + Backup wallet to another location + &Backup portemonnee naar een andere locatie + + + + Change the passphrase used for wallet encryption + wijzig het wachtwoord voor uw portemonneversleuteling + + + + &Debug window + &Debugscherm + + + + Open debugging and diagnostic console + Open debugging en diagnostische console + + + + &Verify message... + &Verifiëer bericht... + + + + Verify a message signature + Verifiëer een handtekening van een bericht + + + + &File + &Bestand + + + + &Settings + &Instellingen + + + + &Help + &Hulp + + + + Tabs toolbar + Tab-werkbalk + + + + Actions toolbar + Actie-werkbalk + + + + + [testnet] + [testnetwerk] + + + + + Bitcoin client + Bitcoin client + + + + %n active connection(s) to Bitcoin network + %n actieve connectie naar Bitcoinnetwerk%n actieve connecties naar Bitcoinnetwerk + + + + Downloaded %1 blocks of transaction history. + %1 blokken van transactiehistorie opgehaald. + + + + %n second(s) ago + %n seconde geleden%n seconden geleden + + + + %n minute(s) ago + %n minuut geleden%n minuten geleden + + + + %n hour(s) ago + %n uur geleden%n uur geleden + + + + %n day(s) ago + %n dag geleden%n dagen geleden + + + + Up to date + Bijgewerkt + + + + Catching up... + Aan het bijwerken... + + + + Last received block was generated %1. + Laatst ontvangen blok is %1 gegenereerd. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Deze transactie overschrijdt de groottelimiet. Om de transactie alsnog te versturen kunt u transactiekosten betalen van %1. Deze transactiekosten gaan naar de nodes die uw transactie verwerken en het helpt op deze manier bij het ondersteunen van het netwerk. Wilt u de transactiekosten betalen? + + + + Confirm transaction fee + Bevestig transactiekosten + + + + Sent transaction + Verzonden transactie + + + + Incoming transaction + Binnenkomende transactie + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Datum: %1 +Bedrag: %2 +Type: %3 +Adres: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Portemonnee is <b>versleuteld</b> en momenteel <b>geopend</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Portemonnee is <b>versleuteld</b> en momenteel <b>gesloten</b> + + + + Backup Wallet + Backup Portemonnee + + + + Wallet Data (*.dat) + Portemonnee-data (*.dat) + + + + Backup Failed + Backup Mislukt + + + + There was an error trying to save the wallet data to the new location. + Er is een fout opgetreden bij het wegschrijven van de portemonnee-data naar de nieuwe locatie. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + Er is een fatale fout opgetreden. Bitcoin kan niet meer veilig doorgaan en zal nu afgesloten worden. + + + + ClientModel + + + Network Alert + Netwerkwaarschuwing + + + + DisplayOptionsPage + + + Display + Beeldscherm + + + + default + standaard + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + De taal van de gebruikersinterface kan hier ingesteld worden. Deze instelling zal pas van kracht worden nadat Bitcoin herstart wordt. + + + + User Interface &Language: + &Taal Gebruikersinterface: + + + + &Unit to show amounts in: + &Eenheid om bedrag in te tonen: + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Kies de standaard onderverdelingseenheid om weer te geven in uw programma, en voor het versturen van munten + + + + &Display addresses in transaction list + Toon &adressen in de transactielijst + + + + Whether to show Bitcoin addresses in the transaction list + Of Bitcoinadressen getoond worden in de transactielijst + + + + Warning + Waarschuwing + + + + This setting will take effect after restarting Bitcoin. + Deze instelling zal pas van kracht worden na het herstarten van Bitcoin. + + + + EditAddressDialog + + + Edit Address + Bewerk Adres + + + + &Label + &Label + + + + The label associated with this address book entry + Het label dat geassocieerd is met dit adres + + + + &Address + &Adres + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Het adres dat geassocieerd is met deze adresboek-opgave. Dit kan alleen worden veranderd voor zend-adressen. + + + + New receiving address + Nieuw ontvangstadres + + + + New sending address + Nieuw adres om naar te verzenden + + + + Edit receiving address + Bewerk ontvangstadres + + + + Edit sending address + Bewerk adres om naar te verzenden + + + + The entered address "%1" is already in the address book. + Het opgegeven adres "%1" bestaat al in uw adresboek. + + + + The entered address "%1" is not a valid Bitcoin address. + Het opgegeven adres "%1" is een ongeldig Bitcoinadres + + + + Could not unlock wallet. + Kon de portemonnee niet openen. + + + + New key generation failed. + Genereren nieuwe sleutel mislukt. + + + + HelpMessageBox + + + + Bitcoin-Qt + Bitcoin-Qt + + + + version + versie + + + + Usage: + Gebruik: + + + + options + opties + + + + UI options + gebruikersinterfaceopties + + + + Set language, for example "de_DE" (default: system locale) + Stel taal in, bijvoorbeeld ''de_DE" (standaard: systeeminstellingen) + + + + Start minimized + Geminimaliseerd starten + + + + + Show splash screen on startup (default: 1) + Laat laadscherm zien bij het opstarten. (standaard: 1) + + + + MainOptionsPage + + + 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. + Ontkoppel blok- en adresdatabases bij afsluiten. Dit betekent dat ze verplaatst kunnen worden naar een andere map, maar het vertraagt het afsluiten. De portemonnee wordt altijd ontkoppeld. + + + + Pay transaction &fee + Betaal &transactiekosten + + + + Main + Algemeen + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Optionele transactiekosten per kB die helpen om uw transacties snel te verwerken. De meeste transacties zijn 1 kB. Transactiekosten van 0,01 wordt aangeraden + + + + &Start Bitcoin on system login + &Start Bitcoin bij het inloggen in het systeem + + + + Automatically start Bitcoin after logging in to the system + Start Bitcoin automatisch na inloggen in het systeem + + + + &Detach databases at shutdown + &Ontkoppel databases bij afsluiten + + + + MessagePage + + + Sign Message + Onderteken Bericht + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + U kunt berichten ondertekenen met een van uw adressen om te bewijzen dat u dit adres bezit. Pas op dat u geen onduidelijke dingen ondertekent, want phishingaanvallen zouden u voor de gek kunnen houden om zo uw identiteit te stelen. Onderteken alleen berichten waarmee u het volledig eens bent. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Het adres om het bericht mee te ondertekenen. (Vb.: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Kies adres uit adresboek + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Plak adres vanuit klembord + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Typ hier het bericht dat u wilt ondertekenen + + + + Copy the current signature to the system clipboard + Kopieer de huidige handtekening naar het systeemklembord + + + + &Copy Signature + &Kopiëer Handtekening + + + + Reset all sign message fields + Verwijder alles in de invulvelden + + + + Clear &All + Verwijder &Alles + + + + Click "Sign Message" to get signature + Klik "Onderteken Bericht" om de handtekening te verkrijgen + + + + Sign a message to prove you own this address + Onderteken een bericht om te bewijzen dat u dit adres bezit + + + + &Sign Message + O&nderteken Bericht + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Vul een Bitcoinadres in (bijv. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Fout bij het ondertekenen + + + + %1 is not a valid address. + %1 is geen geldig adres. + + + + %1 does not refer to a key. + %1 verwijst niet naar een sleutel. + + + + Private key for %1 is not available. + Geheime sleutel voor %1 is niet beschikbaar. + + + + Sign failed + Ondertekenen mislukt + + + + NetworkOptionsPage + + + Network + Netwerk + + + + Map port using &UPnP + Portmapping via &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Open de Bitcoin-poort automatisch op de router. Dit werkt alleen als de router UPnP ondersteunt en het aanstaat. + + + + &Connect through SOCKS4 proxy: + &Verbind via SOCKS4 proxy: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Verbind met het Bitcoin-netwerk door een SOCKS4 proxy (bijv. wanneer Tor gebruikt wordt) + + + + Proxy &IP: + Proxy &IP: + + + + &Port: + &Poort: + + + + IP address of the proxy (e.g. 127.0.0.1) + IP-adres van de proxy (bijv. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Poort waarop de proxy luistert (bijv. 1234) + + + + OptionsDialog + + + Options + Opties + + + + OverviewPage + + + Form + Vorm + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + De weergegeven informatie kan verouderd zijn. Uw portemonnee synchroniseert automaticsh met het Bitcoinnetwerk nadat een verbinding is gelegd, maar dit proces is nog niet voltooid. + + + + Balance: + Saldo: + + + + Number of transactions: + Aantal transacties: + + + + Unconfirmed: + Onbevestigd: + + + + Wallet + Portemonnee + + + + <b>Recent transactions</b> + <b>Recente transacties</b> + + + + Your current balance + Uw huidige saldo + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Totaal van de transacties die nog moeten worden bevestigd en nog niet zijn meegeteld in uw huidige saldo + + + + Total number of transactions in wallet + Totaal aantal transacties in uw portemonnee + + + + + out of sync + niet gesynchroniseerd + + + + QRCodeDialog + + + QR Code Dialog + QR-codescherm + + + + QR Code + QR-code + + + + Request Payment + Vraag betaling aan + + + + Amount: + Bedrag: + + + + BTC + BTC + + + + Label: + Label: + + + + Message: + Bericht: + + + + &Save As... + &Opslaan Als... + + + + Error encoding URI into QR Code. + Fout tijdens encoderen URI in QR-code + + + + Resulting URI too long, try to reduce the text for label / message. + Resulterende URI te lang, probeer de tekst korter te maken voor het label/bericht. + + + + Save QR Code + Sla QR-code op + + + + PNG Images (*.png) + PNG-Afbeeldingen (*.png) + + + + RPCConsole + + + Bitcoin debug window + Bitcoin debugscherm + + + + Client name + Clientnaam + + + + + + + + + + + + N/A + N.v.t. + + + + Client version + Clientversie + + + + &Information + &Informatie + + + + Client + Client + + + + Startup time + Opstarttijd + + + + Network + Netwerk + + + + Number of connections + Aantal connecties + + + + On testnet + Op testnet + + + + Block chain + Blokkenketen + + + + Current number of blocks + Huidig aantal blokken + + + + Estimated total blocks + Geschat totaal aantal blokken + + + + Last block time + Tijd laatste blok + + + + Debug logfile + Debug-logbestand + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + Open het Bitcoin-debug-logbestand van de huidige datamap. Dit kan een paar seconden duren voor grote logbestanden. + + + + &Open + &Open + + + + &Console + &Console + + + + Build date + Bouwdatum + + + + Clear console + Maak console leeg + + + + Welcome to the Bitcoin RPC console. + Welkom bij de Bitcoin RPC-console. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Gebruik de pijltjestoetsen om door de geschiedenis te navigeren, en <b>Ctrl-L</b> om het scherm leeg te maken. + + + + Type <b>help</b> for an overview of available commands. + Typ <b>help</b> voor een overzicht van de beschikbare commando's. + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Verstuur munten + + + + Send to multiple recipients at once + Verstuur aan verschillende ontvangers ineens + + + + &Add Recipient + Voeg &Ontvanger Toe + + + + Remove all transaction fields + Verwijder alle transactievelden + + + + Clear &All + Verwijder &Alles + + + + Balance: + Saldo: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Bevestig de verstuuractie + + + + &Send + &Verstuur + + + + <b>%1</b> to %2 (%3) + <b>%1</b> aan %2 (%3) + + + + Confirm send coins + Bevestig versturen munten + + + + Are you sure you want to send %1? + Weet u zeker dat u %1 wil versturen? + + + + and + en + + + + The recepient address is not valid, please recheck. + Het ontvangstadres is niet geldig, controleer uw opgave. + + + + The amount to pay must be larger than 0. + Het ingevoerde bedrag moet groter zijn dan 0. + + + + The amount exceeds your balance. + Bedrag is hoger dan uw huidige saldo + + + + The total exceeds your balance when the %1 transaction fee is included. + Totaal overschrijdt uw huidige saldo wanneer de %1 transactiekosten worden meegerekend + + + + Duplicate address found, can only send to each address once per send operation. + Dubbel adres gevonden, u kunt slechts eenmaal naar een bepaald adres verzenden per verstuurtransactie + + + + Error: Transaction creation failed. + Fout: Aanmaak transactie mislukt + + + + 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. + Fout: De transactie was afgewezen. Dit kan gebeuren als u eerder uitgegeven munten opnieuw wilt versturen, zoals wanneer u een kopie van uw portemonneebestand (wallet.dat) heeft gebruikt en in de kopie deze munten zijn uitgegeven, maar in de huidige portemonnee deze nog niet als zodanig zijn gemarkeerd. + + + + SendCoinsEntry + + + Form + Vorm + + + + A&mount: + Bedra&g: + + + + Pay &To: + Betaal &Aan: + + + + + Enter a label for this address to add it to your address book + Vul een label in voor dit adres om het toe te voegen aan uw adresboek + + + + &Label: + &Label: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Het adres waaraan u wilt betalen (bijv. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Kies adres uit adresboek + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Plak adres vanuit klembord + + + + Alt+P + Alt+P + + + + Remove this recipient + Verwijder deze ontvanger + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Vul een Bitcoinadres in (bijv. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Openen voor %1 blokken + + + + Open until %1 + Openen totdat %1 + + + + %1/offline? + %1/niet verbonden? + + + + %1/unconfirmed + %1/onbevestigd + + + + %1 confirmations + %1 bevestigingen + + + + <b>Status:</b> + <b>Status:</b> + + + + , has not been successfully broadcast yet + , is nog niet succesvol uitgezonden + + + + , broadcast through %1 node + , uitgezonden naar %1 node + + + + , broadcast through %1 nodes + , uitgezonden naar %1 nodes + + + + <b>Date:</b> + <b>Datum:</b> + + + + <b>Source:</b> Generated<br> + <b>Bron:</b>Gegenereerd<br> + + + + + <b>From:</b> + <b>Van:</b> + + + + unknown + onbekend + + + + + + <b>To:</b> + <b> Aan:</b> + + + + (yours, label: + (Uw adres, label: + + + + (yours) + (uw) + + + + + + + <b>Credit:</b> + <b>Bij:</b> + + + + (%1 matures in %2 more blocks) + (%1 komt beschikbaar na %2 blokken) + + + + (not accepted) + (niet geaccepteerd) + + + + + + <b>Debit:</b> + <b>Af:</b> + + + + <b>Transaction fee:</b> + <b>Transactiekosten:</b> + + + + <b>Net amount:</b> + <b>Netto bedrag:</b> + + + + Message: + Bericht: + + + + Comment: + Opmerking: + + + + Transaction ID: + Transactie-ID: + + + + 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. + Gegeneerde munten moeten 120 blokken wachten voor ze kunnen worden uitgegeven. Uw net gegenereerde blok is uitgezonden aan het netwerk om te worden toegevoegd aan de blokkenketen. Als het niet wordt geaccepteerd in de keten, zal het blok als "ongeldig" worden aangemerkt en kan het niet worden uitgegeven. Dit kan soms gebeuren als een andere node net iets sneller een blok heeft gegenereerd; een paar seconden voor het uwe. + + + + TransactionDescDialog + + + Transaction details + Transactiedetails + + + + This pane shows a detailed description of the transaction + Dit venster laat een uitgebreide beschrijving van de transactie zien + + + + TransactionTableModel + + + Date + Datum + + + + Type + Type + + + + Address + Adres + + + + Amount + Bedrag + + + + Open for %n block(s) + Open gedurende %n blokOpen gedurende %n blokken + + + + Open until %1 + Open tot %1 + + + + Offline (%1 confirmations) + Niet verbonden (%1 bevestigingen) + + + + Unconfirmed (%1 of %2 confirmations) + Onbevestigd (%1 van %2 bevestigd) + + + + Confirmed (%1 confirmations) + Bevestigd (%1 bevestigingen) + + + + Mined balance will be available in %n more blocks + Ontgonnen saldo komt beschikbaar na %n blokOntgonnen saldo komt beschikbaar na %n blokken + + + + This block was not received by any other nodes and will probably not be accepted! + Dit blok is niet ontvangen bij andere nodes en zal waarschijnlijk niet worden geaccepteerd! + + + + Generated but not accepted + Gegenereerd maar niet geaccepteerd + + + + Received with + Ontvangen met + + + + Received from + Ontvangen van + + + + Sent to + Verzonden aan + + + + Payment to yourself + Betaling aan uzelf + + + + Mined + Ontgonnen + + + + (n/a) + (nvt) + + + + Transaction status. Hover over this field to show number of confirmations. + Transactiestatus. Houd de muiscursor boven dit veld om het aantal bevestigingen te laten zien. + + + + Date and time that the transaction was received. + Datum en tijd waarop deze transactie is ontvangen. + + + + Type of transaction. + Type transactie. + + + + Destination address of transaction. + Ontvangend adres van transactie + + + + Amount removed from or added to balance. + Bedrag verwijderd van of toegevoegd aan saldo + + + + TransactionView + + + + All + Alles + + + + Today + Vandaag + + + + This week + Deze week + + + + This month + Deze maand + + + + Last month + Vorige maand + + + + This year + Dit jaar + + + + Range... + Bereik... + + + + Received with + Ontvangen met + + + + Sent to + Verzonden aan + + + + To yourself + Aan uzelf + + + + Mined + Ontgonnen + + + + Other + Anders + + + + Enter address or label to search + Vul adres of label in om te zoeken + + + + Min amount + Min. bedrag + + + + Copy address + Kopieer adres + + + + Copy label + Kopieer label + + + + Copy amount + Kopieer bedrag + + + + Edit label + Bewerk label + + + + Show transaction details + Toon transactiedetails + + + + Export Transaction Data + Exporteer transactiegegevens + + + + Comma separated file (*.csv) + Kommagescheiden bestand (*.csv) + + + + Confirmed + Bevestigd + + + + Date + Datum + + + + Type + Type + + + + Label + Label + + + + Address + Adres + + + + Amount + Bedrag + + + + ID + ID + + + + Error exporting + Fout bij exporteren + + + + Could not write to file %1. + Kon niet schrijven naar bestand %1. + + + + Range: + Bereik: + + + + to + naar + + + + VerifyMessageDialog + + + Verify Signed Message + Verifieer Ondertekend Bericht + + + + 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. + Voer het bericht en de handtekening hieronder in (let erop dat enters, spaties, tabs en andere onzichtbare karakters goed worden overgenomen) om het Bitcoin-adres te verkrijgen dat gebruikt is om het bericht te ondertekenen. + + + + Verify a message and obtain the Bitcoin address used to sign the message + Verifiëer een bericht en verkrijg het Bitcoinadres dat gebruikt is om het bericht te ondertekenen + + + + &Verify Message + &Verifiëer Bericht + + + + Copy the currently selected address to the system clipboard + Kopieer het huidig geselecteerde adres naar het klembord + + + + &Copy Address + &Kopiëer Adres + + + + Reset all verify message fields + Verwijder alles in de invulvelden + + + + Clear &All + Verwijder &Alles + + + + Enter Bitcoin signature + Voer Bitcoin-handtekening in + + + + Click "Verify Message" to obtain address + Klik "Verifiëer Bericht" om het adres te verkrijgen + + + + + Invalid Signature + Ongeldige Handtekening + + + + The signature could not be decoded. Please check the signature and try again. + De handtekening kon niet gedecodeerd worden. Controleer svp de handtekening en probeer het opnieuw. + + + + The signature did not match the message digest. Please check the signature and try again. + De handtekening correspondeerde niet met het bericht. Controleer svp de handtekening en probeer het opnieuw. + + + + Address not found in address book. + Adres niet gevonden in adresboek. + + + + Address found in address book: %1 + Adres gevonden in adresboek: %1 + + + + WalletModel + + + Sending... + Versturen... + + + + WindowOptionsPage + + + Window + Venster + + + + &Minimize to the tray instead of the taskbar + &Minimaliseer naar het systeemvak in plaats van de taakbalk + + + + Show only a tray icon after minimizing the window + Laat alleen een systeemvak-icoon zien wanneer het venster geminimaliseerd is + + + + M&inimize on close + Minimaliseer bij &sluiten van het venster + + + + 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. + Minimaliseer het venster in de plaats van de applicatie af te sluiten als het venster gesloten wordt. Wanneer deze optie aan staan, kan de applicatie alleen worden afgesloten door Afsluiten te kiezen in het menu. + + + + bitcoin-core + + + Bitcoin version + Bitcoinversie + + + + Usage: + Gebruik: + + + + Send command to -server or bitcoind + Stuur commando naar -server of bitcoind + + + + + List commands + List van commando's + + + + + Get help for a command + Toon hulp voor een commando + + + + + Options: + Opties: + + + + + Specify configuration file (default: bitcoin.conf) + Specifieer configuratiebestand (standaard: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + Specifieer pid-bestand (standaard: bitcoind.pid) + + + + + Generate coins + Genereer munten + + + + + Don't generate coins + Genereer geen munten + + + + + Specify data directory + Stel datamap in + + + + + Set database cache size in megabytes (default: 25) + Stel databankcachegrootte in in megabytes (standaard: 25) + + + + Set database disk log size in megabytes (default: 100) + Stel databankloggrootte in in megabytes (standaard: 100) + + + + Specify connection timeout (in milliseconds) + Specificeer de time-out tijd (in milliseconden) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Luister voor verbindingen op <poort> (standaard: 8333 of testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Onderhoud maximaal <n> verbindingen naar peers (standaard: 125) + + + + Connect only to the specified node + Verbind alleen met deze node + + + + + Connect to a node to retrieve peer addresses, and disconnect + Verbind naar een node om adressen van anderen op te halen, en verbreek vervolgens de verbinding + + + + Specify your own public address + Specificeer uw eigen publieke adres + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + Verbind slechts naar nodes in netwerk <net> (IPv4 of IPv6) + + + + Try to discover public IP address (default: 1) + Probeer om publieke IP-adres te achterhalen (standaard: 1) + + + + Bind to given address. Use [host]:port notation for IPv6 + Bind aan gegeven adres. Gebruik [host]:poort -notatie voor IPv6 + + + + Threshold for disconnecting misbehaving peers (default: 100) + Drempel om verbinding te verbreken naar zich misdragende peers (standaard: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Aantal seconden dat zich misdragende peers niet opnieuw mogen verbinden (standaard: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maximale ontvangstbuffer per connectie, <n>*1000 bytes (standaard: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maximale zendbuffer per connectie, <n>*1000 bytes (standaard: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + Ontkoppel blok- en adresdatabases. Verhoogt afsluittijd (standaard: 0) + + + + Accept command line and JSON-RPC commands + Aanvaard commandoregel en JSON-RPC commando's + + + + + Run in the background as a daemon and accept commands + Draai in de achtergrond als daemon en aanvaard commando's + + + + + Use the test network + Gebruik het testnetwerk + + + + + Output extra debugging information + Toon extra debuggingsinformatie + + + + Prepend debug output with timestamp + Voorzie de debuggingsuitvoer van een tijdsaanduiding + + + + Send trace/debug info to console instead of debug.log file + Stuur trace/debug-info naar de console in plaats van het debug.log bestand + + + + Send trace/debug info to debugger + Stuur trace/debug-info naar debugger + + + + Username for JSON-RPC connections + Gebruikersnaam voor JSON-RPC verbindingen + + + + + Password for JSON-RPC connections + Wachtwoord voor JSON-RPC verbindingen + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Luister voor JSON-RPC verbindingen op <poort> (standaard: 8332) + + + + + Allow JSON-RPC connections from specified IP address + Sta JSON-RPC verbindingen van opgegeven IP adres toe + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Verstuur commando's naar proces dat op <ip> draait (standaard: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Voer commando uit zodra het beste blok verandert (%s in cmd wordt vervangen door blockhash) + + + + Upgrade wallet to latest format + Vernieuw portemonnee naar nieuwste versie + + + + Set key pool size to <n> (default: 100) + Stel sleutelpoelgrootte in op <n> (standaard: 100) + + + + + Rescan the block chain for missing wallet transactions + Doorzoek de blokkenketen op ontbrekende portemonnee-transacties + + + + How many blocks to check at startup (default: 2500, 0 = all) + Het aantal blokken na te kijken bij opstarten (standaard: 2500, 0=alle) + + + + How thorough the block verification is (0-6, default: 1) + De grondigheid van de blokverificatie (0-6, standaard: 1) + + + + Imports blocks from external blk000?.dat file + Importeert blokken van extern blk000?.dat bestand + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL-opties: (zie de Bitcoin wiki voor SSL-instructies) + + + + Use OpenSSL (https) for JSON-RPC connections + Gebruik OpenSSL (https) voor JSON-RPC verbindingen + + + + + Server certificate file (default: server.cert) + Certificaat-bestand voor server (standaard: server.cert) + + + + + Server private key (default: server.pem) + Geheime sleutel voor server (standaard: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Aanvaardbare ciphers (standaard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + Waarschuwing: Weinig schijfruimte vrij + + + + This help message + Dit helpbericht + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Kan geen lock op de datamap %s verkrijgen. Bitcoin draait vermoedelijk reeds. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + Niet in staat om aan %s te binden op deze computer (bind gaf error %d, %s) + + + + Connect through socks proxy + Verbind via een socks-proxy + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + Selecteer de versie van de socks proxy om te gebruiken (4 of 5, 5 is standaard) + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + Gebruik geen proxy voor verbindingen naar netwerk <net> (IPv4 of IPv6) + + + + Allow DNS lookups for -addnode, -seednode and -connect + Sta DNS-naslag toe voor -addnode, -seednode en -connect + + + + Pass DNS requests to (SOCKS5) proxy + Stuur DNS-verzoeken via (SOCKS5)proxy + + + + Loading addresses... + Adressen aan het laden... + + + + Error loading blkindex.dat + Fout bij laden blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Fout bij laden wallet.dat: Portemonnee corrupt + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Fout bij laden wallet.dat: Portemonnee vereist een nieuwere versie van Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Portemonnee moest herschreven worden: Herstart Bitcoin om te voltooien + + + + Error loading wallet.dat + Fout bij laden wallet.dat + + + + Invalid -proxy address: '%s' + Ongeldig -proxy adres: '%s' + + + + Unknown network specified in -noproxy: '%s' + Onbekend netwerk gespecificeerd in -noproxy: '%s' + + + + Unknown network specified in -onlynet: '%s' + Onbekend netwerk gespecificeerd in -onlynet: '%s' + + + + Unknown -socks proxy version requested: %i + Onbekende -socks proxyversie aangegeven: %i + + + + Cannot resolve -bind address: '%s' + Kan -bind adres niet herleiden: '%s' + + + + Not listening on any port + Op geen enkele poort aan het luisteren + + + + Cannot resolve -externalip address: '%s' + Kan -externlip adres niet herleiden: '%s' + + + + Invalid amount for -paytxfee=<amount>: '%s' + Ongeldig bedrag voor -paytxfee=<bedrag>: '%s' + + + + Error: could not start node + Fout: Kon node niet starten + + + + Error: Wallet locked, unable to create transaction + Fout: Portemonnee gesloten, transactie maken niet mogelijk + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Fout: Deze transactie heeft transactiekosten nodig van tenminste %s, vanwege zijn grootte, ingewikkeldheid, of het gebruik van onlangs ontvangen munten + + + + Error: Transaction creation failed + Fout: Aanmaak transactie mislukt + + + + Sending... + Aan het versturen... + + + + 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. + Fout: De transactie was afgewezen. Dit kan gebeuren als u eerder uitgegeven munten opnieuw wilt versturen, zoals wanneer u een kopie van uw wallet.dat heeft gebruikt en in de kopie deze munten zijn gemarkeerd als uitgegeven, maar in de huidige nog niet. + + + + Invalid amount + Ongeldig aantal + + + + Insufficient funds + Ontoereikend saldo + + + + Loading block index... + Blokindex aan het laden... + + + + Add a node to connect to and attempt to keep the connection open + Voeg een knooppunt om te verbinden toe en probeer de verbinding open te houden + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + Niet in staat om aan %s te binden op deze computer. Bitcoin draait vermoedelijk reeds. + + + + Find peers using internet relay chat (default: 0) + Vind anderen door middel van Internet Relay Chat (standaard: 0) + + + + Accept connections from outside (default: 1) + Accepteer verbindingen van buitenaf (standaard: 1) + + + + Find peers using DNS lookup (default: 1) + Vind anderen door middel van een DNS-naslag (standaard: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Gebruik Universal Plug and Play om de inkomende poort te mappen (standaard: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Gebruik Universal Plug and Play om de inkomende poort te mappen (standaard: 0) + + + + Fee per KB to add to transactions you send + Kosten per KB om aan transacties toe te voegen die u verstuurt + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + Waarschuwing: -paytxfee is zeer hoog ingesteld. Dit zijn de transactiekosten die u betaalt bij het versturen van een transactie. + + + + Loading wallet... + Portemonnee aan het laden... + + + + Cannot downgrade wallet + Kan portemonnee niet downgraden + + + + Cannot initialize keypool + Kan sleutel-pool niet initialiseren + + + + Cannot write default address + Kan standaard adres niet schrijven + + + + Rescanning... + Opnieuw aan het scannen ... + + + + Done loading + Klaar met laden + + + + To use the %s option + Om de %s optie te gebruiken + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, je moet een rpcpassword instellen in het configuratie bestand: + %s +Het is aangeraden het volgende willekeurig wachtwoord te gebruiken: +rpccuser=bitcoinrpc +rpcpassword=%s +(het is niet nodig om het wachtwoord te onthouden) +Als het bestand niet bestaat, maak het aan, met een alleen-lezen permissie. + + + + + Error + Fout + + + + An error occured while setting up the RPC port %i for listening: %s + Er is een fout opgetreden tijdens het opzetten van de inkomende RPC-poort %i: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Je moet rpcpassword=<password> instellen in het configuratie bestand: +%s +Als het bestand niet bestaat, maak het dan aan, met een alleen-lezen permissie. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Waarschuwing: Controleer dat de datum en tijd op uw computer correct zijn ingesteld. Als uw klok fout staat zal Bitcoin niet correct werken. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts new file mode 100644 index 0000000..fe44a97 --- /dev/null +++ b/src/qt/locale/bitcoin_pl.ts @@ -0,0 +1,2517 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + O Bitcoin + + + + <b>Bitcoin</b> version + Wersja <b>Bitcoin</b> + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Bitcoin Developers + +Oprogramowanie eksperymentalne. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + +Pomóż w tłumaczeniu: +www.transifex.net/projects/p/bitcoin/ + + + + AddressBookPage + + + Address Book + Książka Adresowa + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Tutaj znajdują się twoje adresy Bitcoin do odbioru płatności. Możesz nadać oddzielne adresy dla każdego z wysyłających monety, żeby śledzić oddzielnie ich opłaty. + + + + Double-click to edit address or label + Kliknij dwukrotnie, aby edytować adres lub etykietę + + + + Create a new address + Utwórz nowy adres + + + + Copy the currently selected address to the system clipboard + Skopiuj aktualnie wybrany adres do schowka + + + + &New Address + &Nowy Adres + + + + &Copy Address + + + + + Show &QR Code + Pokaż Kod &QR + + + + Sign a message to prove you own this address + Podpisz wiadomość aby dowieść, że ten adres jest twój + + + + &Sign Message + Podpi&sz Wiadomość + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Usuń aktualnie wybrany adres z listy. Tylko adresy nadawcze mogą być usunięte. + + + + &Delete + &Usuń + + + + Copy &Label + + + + + &Edit + &Edytuj + + + + Export Address Book Data + Eksportuj książkę adresową + + + + Comma separated file (*.csv) + Plik *.CSV (rozdzielany przecinkami) + + + + Error exporting + Błąd podczas eksportowania + + + + Could not write to file %1. + Błąd zapisu do pliku %1. + + + + AddressTableModel + + + Label + Etykieta + + + + Address + Adres + + + + (no label) + (bez etykiety) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Wpisz hasło + + + + New passphrase + Nowe hasło + + + + Repeat new passphrase + Powtórz nowe hasło + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Wprowadź nowe hasło dla portfela.<br/>Proszę użyć hasła składającego się z <b>10 lub więcej losowych znaków</b> lub <b>ośmiu lub więcej słów</b>. + + + + Encrypt wallet + Zaszyfruj portfel + + + + This operation needs your wallet passphrase to unlock the wallet. + Ta operacja wymaga hasła do portfela ażeby odblokować portfel. + + + + Unlock wallet + Odblokuj portfel + + + + This operation needs your wallet passphrase to decrypt the wallet. + Ta operacja wymaga hasła do portfela ażeby odszyfrować portfel. + + + + Decrypt wallet + Odszyfruj portfel + + + + Change passphrase + Zmień hasło + + + + Enter the old and new passphrase to the wallet. + Podaj stare i nowe hasło do portfela. + + + + Confirm wallet encryption + Potwierdź szyfrowanie portfela + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + OSTRZEŻENIE: Jeśli zaszyfrujesz portfel i zgubisz hasło, wtedy <b>STRACISZ WSZYSTKIE SWOJE BITMONETY</b> +Czy na pewno chcesz zaszyfrować swój portfel? + + + + + Wallet encrypted + Portfel zaszyfrowany + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Program Bitcoin zamknie się aby dokończyć proces szyfrowania. Pamiętaj, że szyfrowanie portfela nie zabezpiecza w pełni Twoich bitcoinów przed kradzieżą przez wirusy lub trojany mogące zainfekować Twój komputer. + + + + + Warning: The Caps Lock key is on. + Ostrzeżenie: Caps Lock jest włączony. + + + + + + + Wallet encryption failed + Szyfrowanie portfela nie powiodło się + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Szyfrowanie portfela nie powiodło się z powodu wewnętrznego błędu. Twój portfel nie został zaszyfrowany. + + + + + The supplied passphrases do not match. + Podane hasła nie są takie same. + + + + Wallet unlock failed + Odblokowanie portfela nie powiodło się + + + + + + The passphrase entered for the wallet decryption was incorrect. + Wprowadzone hasło do odszyfrowania portfela jest niepoprawne. + + + + Wallet decryption failed + Odszyfrowywanie portfela nie powiodło się + + + + Wallet passphrase was succesfully changed. + Hasło do portfela zostało pomyślnie zmienione. + + + + BitcoinGUI + + + Bitcoin Wallet + Portfel Bitcoin + + + + Sign &message... + Podpisz wiado&mość... + + + + Show/Hide &Bitcoin + Pokaż/Ukryj &Bitcoin + + + + Synchronizing with network... + Synchronizacja z siecią... + + + + &Overview + P&odsumowanie + + + + Show general overview of wallet + Pokazuje ogólny zarys portfela + + + + &Transactions + &Transakcje + + + + Browse transaction history + Przeglądaj historię transakcji + + + + &Address Book + Książka &adresowa + + + + Edit the list of stored addresses and labels + Edytuj listę zapisanych adresów i i etykiet + + + + &Receive coins + Odbie&rz monety + + + + Show the list of addresses for receiving payments + Pokaż listę adresów do otrzymywania płatności + + + + &Send coins + Wy&syłka monet + + + + Prove you control an address + Udowodnij, że kontrolujesz adres + + + + E&xit + &Zakończ + + + + Quit application + Zamknij program + + + + &About %1 + &O %1 + + + + Show information about Bitcoin + Pokaż informację o Bitcoin + + + + About &Qt + O &Qt + + + + Show information about Qt + Pokazuje informacje o Qt + + + + &Options... + &Opcje... + + + + &Encrypt Wallet... + Zaszyfruj Portf&el + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + pozostał ~%n blokpozostało ~%n blokipozostało ~%n bloków + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Eksportuj... + + + + Send coins to a Bitcoin address + Wyślij monety na adres Bitcoin + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Pokaż lub ukryj okno Bitcoin + + + + Export the data in the current tab to a file + Eksportuj dane z aktywnej karty do pliku + + + + Encrypt or decrypt wallet + Zaszyfruj lub odszyfruj portfel + + + + Backup wallet to another location + Zapasowy portfel w innej lokalizacji + + + + Change the passphrase used for wallet encryption + Zmień hasło użyte do szyfrowania portfela + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Plik + + + + &Settings + P&referencje + + + + &Help + Pomo&c + + + + Tabs toolbar + Pasek zakładek + + + + Actions toolbar + Pasek akcji + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Bitcoin klient + + + + %n active connection(s) to Bitcoin network + %n aktywne połączenie do sieci Bitcoin%n aktywne połączenia do sieci Bitcoin%n aktywnych połączeń do sieci Bitcoin + + + + Downloaded %1 blocks of transaction history. + Pobrano %1 bloków z historią transakcji. + + + + %n second(s) ago + %n sekundę temu%n sekundy temu%n sekund temu + + + + %n minute(s) ago + %n minutę temu%n minuty temu%n minut temu + + + + %n hour(s) ago + %n godzinę temu%n godziny temu%n godzin temu + + + + %n day(s) ago + %n dzień temu%n dni temu%n dni temu + + + + Up to date + Aktualny + + + + Catching up... + Łapanie bloków... + + + + Last received block was generated %1. + Ostatnio otrzymany blok została wygenerowany %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Transakcja przekracza limit. Możesz wysłać ją płacąc prowizję %1, która zostaje przekazana do węzłów, które ją prześlą i pomoże wspierać sieć Bitcoin. Czy chcesz zapłacić prowizję? + + + + Confirm transaction fee + Potwierdź prowizję transakcyjną + + + + Sent transaction + Transakcja wysłana + + + + Incoming transaction + Transakcja przychodząca + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Data: %1 +Kwota: %2 +Typ: %3 +Adres: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Portfel jest <b>zaszyfrowany</b> i obecnie <b>niezablokowany</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Portfel jest <b>zaszyfrowany</b> i obecnie <b>zablokowany</b> + + + + Backup Wallet + Kopia Zapasowa Portfela + + + + Wallet Data (*.dat) + Dane Portfela (*.dat) + + + + Backup Failed + Kopia Zapasowa Nie Została Wykonana + + + + There was an error trying to save the wallet data to the new location. + Wystąpił błąd podczas próby zapisu portfela do nowej lokalizacji. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Wyświetlanie + + + + default + domyślny + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Wybierz podział jednostki pokazywany w interfejsie oraz podczas wysyłania monet + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + Ostrzeżenie + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Edytuj adres + + + + &Label + &Etykieta + + + + The label associated with this address book entry + Etykieta skojarzona z tym wpisem w książce adresowej + + + + &Address + &Adres + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Ten adres jest skojarzony z wpisem w książce adresowej. Może być zmodyfikowany jedynie dla adresów wysyłających. + + + + New receiving address + Nowy adres odbiorczy + + + + New sending address + Nowy adres wysyłania + + + + Edit receiving address + Edytuj adres odbioru + + + + Edit sending address + Edytuj adres wysyłania + + + + The entered address "%1" is already in the address book. + Wprowadzony adres "%1" już istnieje w książce adresowej. + + + + The entered address "%1" is not a valid Bitcoin address. + Wprowadzony adres "%1" nie jest poprawnym adresem Bitcoin. + + + + Could not unlock wallet. + Nie można było odblokować portfela. + + + + New key generation failed. + Tworzenie nowego klucza nie powiodło się. + + + + HelpMessageBox + + + + Bitcoin-Qt + Bitcoin-Qt + + + + version + wersja + + + + Usage: + Użycie: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + Ustaw Język, na przykład "pl_PL" (domyślnie: systemowy) + + + + Start minimized + Uruchom zminimalizowany + + + + Show splash screen on startup (default: 1) + Pokazuj okno powitalne przy starcie (domyślnie: 1) + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Płać prowizję za t&ransakcje + + + + Main + Główny + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Opcjonalna prowizja za transakcje za kB, wspomaga ona szybkość przebiegu transakcji. Większość transakcji jest 1 kB. Zalecana prowizja 0.01 . + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + Automatycznie uruchom Bitcoin po zalogowaniu do systemu + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Możesz podpisywać wiadomości swoimi adresami aby udowodnić, że jesteś ich właścicielem. Uważaj, aby nie podpisywać niczego co wzbudza Twoje podejrzenia, ponieważ ktoś może stosować phishing próbując nakłonić Cię do ich podpisania. Akceptuj i podpisuj tylko w pełni zrozumiałe komunikaty i wiadomości. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + Wybierz adres z książki adresowej + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Wklej adres ze schowka + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Wprowadź wiadomość, którą chcesz podpisać, tutaj + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Kliknij "Podpisz Wiadomość" żeby uzyskać podpis + + + + Sign a message to prove you own this address + Podpisz wiadomość aby dowieść, że ten adres jest twój + + + + &Sign Message + Podpi&sz Wiadomość + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Wprowadź adres Bitcoin (np. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Błąd podpisywania + + + + %1 is not a valid address. + %1 nie jest poprawnym adresem. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Klucz prywatny dla %1 jest niedostępny. + + + + Sign failed + Podpisywanie nie powiodło się. + + + + NetworkOptionsPage + + + Network + Sieć + + + + Map port using &UPnP + Mapuj port używając &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Automatycznie otwiera port klienta Bitcoin na routerze. Ta opcja dzieła tylko jeśli twój router wspiera UPnP i jest ono włączone. + + + + &Connect through SOCKS4 proxy: + Połącz przez proxy SO&CKS4: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Łączy się z siecią Bitcoin przez proxy SOCKS4 (np. kiedy łączysz się przez Tor) + + + + Proxy &IP: + Proxy &IP: + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + Adres IP serwera proxy (np. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Port proxy (np. 1234) + + + + OptionsDialog + + + Options + Opcje + + + + OverviewPage + + + Form + Formularz + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Saldo: + + + + Number of transactions: + Liczba transakcji: + + + + Unconfirmed: + Niepotwierdzony: + + + + Wallet + Portfel + + + + <b>Recent transactions</b> + <b>Ostatnie transakcje</b> + + + + Your current balance + Twoje obecne saldo + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Suma transakcji, które nie zostały jeszcze potwierdzone, i które nie zostały wliczone do twojego obecnego salda + + + + Total number of transactions in wallet + Całkowita liczba transakcji w portfelu + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + Okno Dialogowe Kodu QR + + + + QR Code + Kod QR + + + + Request Payment + Prośba o płatność + + + + Amount: + Kwota: + + + + BTC + BTC + + + + Label: + Etykieta: + + + + Message: + Wiadomość: + + + + &Save As... + Zapi&sz jako... + + + + Error encoding URI into QR Code. + Błąd kodowania URI w Kodzie QR. + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + Zapisz Kod QR + + + + PNG Images (*.png) + Obraz PNG (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + Nazwa klienta + + + + + + + + + + + + N/A + NIEDOSTĘPNE + + + + Client version + Wersja klienta + + + + &Information + + + + + Client + Klient + + + + Startup time + + + + + Network + Sieć + + + + Number of connections + Liczba połączeń + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + Aktualna liczba bloków + + + + Estimated total blocks + Szacowana ilość bloków + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + &Otwórz + + + + &Console + + + + + Build date + + + + + Clear console + Wyczyść konsole + + + + Welcome to the Bitcoin RPC console. + Witam w konsoli Bitcoin RPC + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Wyślij płatność + + + + Send to multiple recipients at once + Wyślij do wielu odbiorców na raz + + + + &Add Recipient + + + + + Remove all transaction fields + Wyczyść wszystkie pola transakcji + + + + Clear &All + + + + + Balance: + Saldo: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Potwierdź akcję wysyłania + + + + &Send + Wy&syłka + + + + <b>%1</b> to %2 (%3) + <b>%1</b> do %2 (%3) + + + + Confirm send coins + Potwierdź wysyłanie monet + + + + Are you sure you want to send %1? + Czy na pewno chcesz wysłać %1? + + + + and + i + + + + The recepient address is not valid, please recheck. + Adres odbiorcy jest niepoprawny, proszę go sprawdzić. + + + + The amount to pay must be larger than 0. + Kwota do zapłacenie musi być większa od 0. + + + + The amount exceeds your balance. + Kwota przekracza twoje saldo. + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Formularz + + + + A&mount: + Su&ma: + + + + Pay &To: + Płać &Do: + + + + + Enter a label for this address to add it to your address book + Wprowadź etykietę dla tego adresu by dodać go do książki adresowej + + + + &Label: + &Etykieta: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adres do wysłania należności do (np. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Wybierz adres z książki adresowej + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Wklej adres ze schowka + + + + Alt+P + Alt+P + + + + Remove this recipient + Usuń tego odbiorce + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Wprowadź adres Bitcoin (np. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Otwórz dla %1 bloków + + + + Open until %1 + Otwórz do %1 + + + + %1/offline? + %1/offline? + + + + %1/unconfirmed + %1/niezatwierdzone + + + + %1 confirmations + %1 potwierdzeń + + + + <b>Status:</b> + <b>Status:</b> + + + + , has not been successfully broadcast yet + , nie został jeszcze pomyślnie wyemitowany + + + + , broadcast through %1 node + , emitowany przez %1 węzeł + + + + , broadcast through %1 nodes + , emitowany przez %1 węzły + + + + <b>Date:</b> + <b>Data:</b> + + + + <b>Source:</b> Generated<br> + <b>Źródło:</b> Wygenerowano<br> + + + + + <b>From:</b> + <b>Od:</b> + + + + unknown + nieznany + + + + + + <b>To:</b> + <b>Do:</b> + + + + (yours, label: + (twoje, etykieta: + + + + (yours) + (twoje) + + + + + + + <b>Credit:</b> + <b>Przypisy:</b> + + + + (%1 matures in %2 more blocks) + + + + + (not accepted) + (niezaakceptowane) + + + + + + <b>Debit:</b> + <b>Debet:</b> + + + + <b>Transaction fee:</b> + <b>Prowizja transakcyjna:</b> + + + + <b>Net amount:</b> + <b>Kwota netto:</b> + + + + Message: + Wiadomość: + + + + Comment: + Komentarz: + + + + Transaction ID: + ID transakcji: + + + + 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. + Wygenerowane monety muszą zaczekać 120 bloków zanim będzie można je wydać. Kiedy wygenerowałeś ten blok, został on wyemitowany do sieci, aby dodać go do łańcucha bloków. Jeśli to się nie powiedzie nie zostanie on zaakceptowany i wygenerowanych monet nie będzie można wysyłać. Może się to czasami zdarzyć jeśli inny węzeł wygeneruje blok tuż przed tobą. + + + + TransactionDescDialog + + + Transaction details + Szczegóły transakcji + + + + This pane shows a detailed description of the transaction + Ten panel pokazuje szczegółowy opis transakcji + + + + TransactionTableModel + + + Date + Data + + + + Type + Typ + + + + Address + Adres + + + + Amount + Kwota + + + + Open for %n block(s) + Otwórz dla %n blokuOtwórz dla %n blokówOtwórz dla %n bloków + + + + Open until %1 + Otwórz do %1 + + + + Offline (%1 confirmations) + Offline (%1 potwierdzeń) + + + + Unconfirmed (%1 of %2 confirmations) + Niezatwierdzony (%1 z %2 potwierdzeń) + + + + Confirmed (%1 confirmations) + Zatwierdzony (%1 potwierdzeń) + + + + Mined balance will be available in %n more blocks + Wydobyta kwota będzie dostępna za %n blokWydobyta kwota będzie dostępna za %n blokówWydobyta kwota będzie dostępna za %n bloki + + + + This block was not received by any other nodes and will probably not be accepted! + Ten blok nie został odebrany przez jakikolwiek inny węzeł i prawdopodobnie nie zostanie zaakceptowany! + + + + Generated but not accepted + Wygenerowano ale nie zaakceptowano + + + + Received with + Otrzymane przez + + + + Received from + Odebrano od + + + + Sent to + Wysłano do + + + + Payment to yourself + Płatność do siebie + + + + Mined + Wydobyto + + + + (n/a) + (brak) + + + + Transaction status. Hover over this field to show number of confirmations. + Status transakcji. Najedź na pole, aby zobaczyć liczbę potwierdzeń. + + + + Date and time that the transaction was received. + Data i czas odebrania transakcji. + + + + Type of transaction. + Rodzaj transakcji. + + + + Destination address of transaction. + Adres docelowy transakcji. + + + + Amount removed from or added to balance. + Kwota usunięta z lub dodana do konta. + + + + TransactionView + + + + All + Wszystko + + + + Today + Dzisiaj + + + + This week + W tym tygodniu + + + + This month + W tym miesiącu + + + + Last month + W zeszłym miesiącu + + + + This year + W tym roku + + + + Range... + Zakres... + + + + Received with + Otrzymane przez + + + + Sent to + Wysłano do + + + + To yourself + Do siebie + + + + Mined + Wydobyto + + + + Other + Inne + + + + Enter address or label to search + Wprowadź adres albo etykietę żeby wyszukać + + + + Min amount + Min suma + + + + Copy address + Kopiuj adres + + + + Copy label + Kopiuj etykietę + + + + Copy amount + Kopiuj kwotę + + + + Edit label + Edytuj etykietę + + + + Show transaction details + Pokaż szczegóły transakcji + + + + Export Transaction Data + Eksportuj Dane Transakcyjne + + + + Comma separated file (*.csv) + CSV (rozdzielany przecinkami) + + + + Confirmed + Potwierdzony + + + + Date + Data + + + + Type + Typ + + + + Label + Etykieta + + + + Address + Adres + + + + Amount + Kwota + + + + ID + ID + + + + Error exporting + Błąd podczas eksportowania + + + + Could not write to file %1. + Błąd zapisu do pliku %1. + + + + Range: + Zakres: + + + + to + do + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Skopiuj aktualnie wybrany adres do schowka + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Wysyłanie... + + + + WindowOptionsPage + + + Window + Okno + + + + &Minimize to the tray instead of the taskbar + &Minimalizuj do paska przy zegarku zamiast do paska zadań + + + + Show only a tray icon after minimizing the window + Pokazuje tylko ikonę przy zegarku po zminimalizowaniu okna + + + + M&inimize on close + M&inimalizuj przy zamknięciu + + + + 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. + Minimalizuje zamiast zakończyć działanie programu przy zamykaniu okna. Kiedy ta opcja jest włączona, program zakończy działanie po wybieraniu Zamknij w menu. + + + + bitcoin-core + + + Bitcoin version + Wersja Bitcoin + + + + Usage: + Użycie: + + + + Send command to -server or bitcoind + Wyślij polecenie do -server lub bitcoind + + + + List commands + Lista poleceń + + + + Get help for a command + Uzyskaj pomoc do polecenia + + + + Options: + Opcje: + + + + Specify configuration file (default: bitcoin.conf) + Wskaż plik konfiguracyjny (domyślnie: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Wskaż plik pid (domyślnie: bitcoin.pid) + + + + Generate coins + Generuj monety + + + + Don't generate coins + Nie generuj monet + + + + Specify data directory + Wskaż folder danych + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Wskaż czas oczekiwania bezczynności połączenia (w milisekundach) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Nasłuchuj połączeń na <port> (domyślnie: 8333 lub testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Utrzymuj maksymalnie <n> połączeń z peerami (domyślnie: 125) + + + + Connect only to the specified node + Łącz tylko do wskazanego węzła + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + Łącz tylko z węzłami w sieci <net> (IPv4 lub IPv6) + + + + Try to discover public IP address (default: 1) + Próbuj odkryć publiczny adres IP (domyślnie: 1) + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maksymalny bufor odbioru na połączenie, <n>*1000 bajtów (domyślnie: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maksymalny bufor wysyłu na połączenie, <n>*1000 bajtów (domyślnie: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Akceptuj linię poleceń oraz polecenia JSON-RPC + + + + Run in the background as a daemon and accept commands + Uruchom w tle jako daemon i przyjmuj polecenia + + + + Use the test network + Użyj sieci testowej + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + Wyślij informację/raport do konsoli zamiast do pliku debug.log. + + + + Send trace/debug info to debugger + Wyślij informację/raport do debuggera. + + + + Username for JSON-RPC connections + Nazwa użytkownika dla połączeń JSON-RPC + + + + Password for JSON-RPC connections + Hasło do połączeń JSON-RPC + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Nasłuchuj połączeń JSON-RPC na <port> (domyślnie: 8332) + + + + Allow JSON-RPC connections from specified IP address + Przyjmuj połączenia JSON-RPC ze wskazanego adresu IP + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Wysyłaj polecenia do węzła działającego na <ip> (domyślnie: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + Ustaw rozmiar puli kluczy na <n> (domyślnie: 100) + + + + Rescan the block chain for missing wallet transactions + Przeskanuj blok łańcuchów żeby znaleźć zaginione transakcje portfela + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +opcje SSL: (sprawdź Bitcoin Wiki dla instrukcje konfiguracji SSL) + + + + Use OpenSSL (https) for JSON-RPC connections + Użyj OpenSSL (https) do połączeń JSON-RPC + + + + Server certificate file (default: server.cert) + Plik certyfikatu serwera (domyślnie: server.cert) + + + + Server private key (default: server.pem) + Klucz prywatny serwera (domyślnie: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Aceptowalne szyfry (domyślnie: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + Ostrzeżenie: mało miejsca na dysku + + + + This help message + Ta wiadomość pomocy + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Nie można zablokować folderu danych %s. Bitcoin prawdopodobnie już działa. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + Nie używaj proxy do połączeń z siecią <net> (IPv4 lub IPv6) + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Wczytywanie adresów... + + + + Error loading blkindex.dat + Błąd ładownia blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Błąd ładowania wallet.dat: Uszkodzony portfel + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Błąd ładowania wallet.dat: Portfel wymaga nowszej wersji Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Portfel wymaga przepisania: zrestartuj Bitcoina żeby ukończyć + + + + Error loading wallet.dat + Błąd ładowania wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + Nieprawidłowa kwota dla -paytxfee=<amount>: '%s' + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Błąd: Tworzenie transakcji nie powiodło się + + + + Sending... + Wysyłanie... + + + + 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. + Błąd: transakcja została odrzucona. Może się to zdarzyć, gdy monety z Twojego portfela zostały już wydane, na przykład gdy używałeś kopii wallet.dat i bitcoiny które tam wydałeś nie zostały jeszcze odjęte z portfela z którego teraz korzystasz. + + + + Invalid amount + Nieprawidłowa kwota + + + + Insufficient funds + Niewystarczające środki + + + + Loading block index... + Ładowanie indeksu bloku... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Wczytywanie portfela... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Ponowne skanowanie... + + + + Done loading + Wczytywanie zakończone + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + Błąd + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Ostrzeżenie: Proszę sprawdzić poprawność czasu i daty na tym komputerze. Jeśli czas jest zły Bitcoin może nie działać prawidłowo. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts new file mode 100644 index 0000000..64e2923 --- /dev/null +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -0,0 +1,2537 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Sobre o Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> versão + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Desenvolvedores do Bitcoin + +Esse software é experimental. + +Distribuído sob a licença de software MIT/X11, veja o arquivo de licença anexo license.txt ou http://www.opensource.org/licenses/mit-license.php. + +Esse produto inclui software desenvolvido pelo Projeto OpenSSL para uso no OpenSSL Toolkit (http://www.openssl.org/) e software criptográfico escrito por Eric Young (eay@cryptsoft.com) e software UPnP escrito por Thomas Bernard. + + + + AddressBookPage + + + Address Book + Catálogo de endereços + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Estes são os seus endereços Bitcoin para receber pagamentos. Você pode querer enviar um endereço diferente para cada remetente, para acompanhar quem está pagando. + + + + Double-click to edit address or label + Clique duas vezes para editar o endereço ou o etiqueta + + + + Create a new address + Criar um novo endereço + + + + Copy the currently selected address to the system clipboard + Copie o endereço selecionado para a área de transferência do sistema + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Mostrar &QR Code + + + + Sign a message to prove you own this address + Assine uma mensagem para provar que você é o dono desse endereço + + + + &Sign Message + &Assinar Mensagem + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Excluir o endereço selecionado da lista. Apenas endereços de envio podem ser excluídos. + + + + &Delete + &Excluir + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Exportação de dados do Catálogo de Endereços + + + + Comma separated file (*.csv) + Arquivo separado por vírgulas (*. csv) + + + + Error exporting + Erro ao exportar + + + + Could not write to file %1. + Could not write to file %1. + + + + AddressTableModel + + + Label + Rótulo + + + + Address + Endereço + + + + (no label) + (Sem rótulo) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Digite a frase de segurança + + + + New passphrase + Nova frase de segurança + + + + Repeat new passphrase + Repita a nova frase de segurança + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Digite a nova frase de seguraça da sua carteira. <br/> Por favor, use uma frase de <b>10 ou mais caracteres aleatórios,</b> ou <b>oito ou mais palavras.</b> + + + + Encrypt wallet + Criptografar carteira + + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operação precisa de sua frase de segurança para desbloquear a carteira. + + + + Unlock wallet + Desbloquear carteira + + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operação precisa de sua frase de segurança para descriptografar a carteira. + + + + Decrypt wallet + Descriptografar carteira + + + + Change passphrase + Alterar frase de segurança + + + + Enter the old and new passphrase to the wallet. + Digite a frase de segurança antiga e nova para a carteira. + + + + Confirm wallet encryption + Confirmar criptografia da carteira + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + AVISO: Se você criptografar sua carteira e perder sua senha, você vai <b>perder todos os seus BITCOINS!</b> Tem certeza de que deseja criptografar sua carteira? + + + + + Wallet encrypted + Carteira criptografada + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + O Bitcoin irá fechar agora para finalizar o processo de encriptação. Lembre-se de que encriptar sua carteira não protege totalmente suas bitcoins de serem roubadas por malwares que tenham infectado o seu computador. + + + + + Warning: The Caps Lock key is on. + Aviso: A tecla Caps Lock está ligada. + + + + + + + Wallet encryption failed + A criptografia da carteira falhou + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + A criptografia da carteira falhou devido a um erro interno. Sua carteira não estava criptografada. + + + + + The supplied passphrases do not match. + A frase de segurança fornecida não confere. + + + + Wallet unlock failed + A abertura da carteira falhou + + + + + + The passphrase entered for the wallet decryption was incorrect. + A frase de segurança digitada para a descriptografia da carteira estava incorreta. + + + + Wallet decryption failed + A descriptografia da carteira falhou + + + + Wallet passphrase was succesfully changed. + A frase de segurança da carteira foi alterada com êxito. + + + + BitcoinGUI + + + Bitcoin Wallet + Carteira Bitcoin + + + + Sign &message... + + + + + Show/Hide &Bitcoin + Exibir/Ocultar &Bitcoin + + + + Synchronizing with network... + Sincronizando com a rede... + + + + &Overview + &Visão geral + + + + Show general overview of wallet + Mostrar visão geral da carteira + + + + &Transactions + &Transações + + + + Browse transaction history + Navegar pelo histórico de transações + + + + &Address Book + &Catálogo de endereços + + + + Edit the list of stored addresses and labels + Editar a lista de endereços e rótulos + + + + &Receive coins + &Receber moedas + + + + Show the list of addresses for receiving payments + Mostrar a lista de endereços para receber pagamentos + + + + &Send coins + &Enviar moedas + + + + Prove you control an address + Prove que você controla um endereço + + + + E&xit + E&xit + + + + Quit application + Sair da aplicação + + + + &About %1 + &About %1 + + + + Show information about Bitcoin + Mostrar informação sobre Bitcoin + + + + About &Qt + Sobre &Qt + + + + Show information about Qt + Mostrar informações sobre o Qt + + + + &Options... + &Opções... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + ~%n bloco restante~%n blocos restantes + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Exportar... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Exibir ou ocultar a janela Bitcoin + + + + Export the data in the current tab to a file + Exportar os dados na aba atual para um arquivo + + + + Encrypt or decrypt wallet + Criptografar ou decriptogravar carteira + + + + Backup wallet to another location + Fazer cópia de segurança da carteira para uma outra localização + + + + Change the passphrase used for wallet encryption + Mudar a frase de segurança utilizada na criptografia da carteira + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Arquivo + + + + &Settings + E configurações + + + + &Help + &Ajuda + + + + Tabs toolbar + Barra de ferramentas + + + + Actions toolbar + Barra de ações + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Cliente Bitcoin + + + + %n active connection(s) to Bitcoin network + %n conexão ativa na rede Bitcoin%n conexões ativas na rede Bitcoin + + + + Downloaded %1 blocks of transaction history. + Carregados %1 blocos do histórico de transações. + + + + %n second(s) ago + %n segundo atrás%n segundos atrás + + + + %n minute(s) ago + %n minutos atrás%n minutos atrás + + + + %n hour(s) ago + %n hora atrás%n horas atrás + + + + %n day(s) ago + %n dia atrás%n dias atrás + + + + Up to date + Atualizado + + + + Catching up... + Recuperando o atraso ... + + + + Last received block was generated %1. + Last received block was generated %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + + + + Confirm transaction fee + + + + + Sent transaction + Sent transaction + + + + Incoming transaction + Incoming transaction + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Data: %1 +Quantidade: %2 +Tipo: %3 +Endereço: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Wallet is <b>encrypted</b> and currently <b>locked</b> + + + + Backup Wallet + Fazer cópia de segurança da Carteira + + + + Wallet Data (*.dat) + Dados da Carteira (*.dat) + + + + Backup Failed + Cópia de segurança Falhou + + + + There was an error trying to save the wallet data to the new location. + Houve um erro ao tentar salvar os dados da carteira para uma nova localização. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Display + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Choose the default subdivision unit to show in the interface, and when sending coins + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Edit Address + + + + &Label + &Label + + + + The label associated with this address book entry + The label associated with this address book entry + + + + &Address + &Address + + + + The address associated with this address book entry. This can only be modified for sending addresses. + The address associated with this address book entry. This can only be modified for sending addresses. + + + + New receiving address + New receiving address + + + + New sending address + New sending address + + + + Edit receiving address + Edit receiving address + + + + Edit sending address + Edit sending address + + + + The entered address "%1" is already in the address book. + The entered address "%1" is already in the address book. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Could not unlock wallet. + + + + New key generation failed. + New key generation failed. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Usage: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + Start minimized + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Pay transaction &fee + + + + Main + Principal + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Taxa opcional de transações por kB que ajuda a garantir que suas transações serão processadas rapidamente. A maior parte das transações é de 1 kB. Taxa de 0.01 recomendada. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Você pode assinar mensagens com seus endereços para provar que você é o dono deles. Seja cuidadoso para não assinar algo vago, pois ataques de pishing podem tentar te enganar para dar sua assinatura de identidade para eles. Apenas assine afirmações completamente detalhadas com as quais você concorda. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + O endereço a ser utilizado para assinar a mensagem (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Escolher endereço + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Paste address from clipboard + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Entre a mensagem que você quer assinar aqui + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Clique "Assinar Mensagem" para conseguir a assinatura + + + + Sign a message to prove you own this address + Assine uma mensagem para provar que você é o dono desse endereço + + + + &Sign Message + &Assinar Mensagem + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Erro ao assinar + + + + %1 is not a valid address. + %1 não é um endereço válido. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Chave privada para %1 não está disponível. + + + + Sign failed + Assinatura falhou + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Map port using &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + + &Connect through SOCKS4 proxy: + &Connect through SOCKS4 proxy: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + IP address of the proxy (e.g. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Port of the proxy (e.g. 1234) + + + + OptionsDialog + + + Options + Options + + + + OverviewPage + + + Form + Form + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Balance: + + + + Number of transactions: + Number of transactions: + + + + Unconfirmed: + Unconfirmed: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Recent transactions</b> + + + + Your current balance + Your current balance + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + + Total number of transactions in wallet + Total number of transactions in wallet + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + Código QR + + + + Request Payment + Requisitar Pagamento + + + + Amount: + Quantia: + + + + BTC + BTC + + + + Label: + Etiqueta: + + + + Message: + Message: + + + + &Save As... + &Salvar como... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + URI resultante muito longa. Tente reduzir o texto do rótulo ou da mensagem. + + + + Save QR Code + + + + + PNG Images (*.png) + Imagens PNG (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Send Coins + + + + Send to multiple recipients at once + Send to multiple recipients at once + + + + &Add Recipient + + + + + Remove all transaction fields + Remover todos os campos da transação + + + + Clear &All + + + + + Balance: + Balance: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Confirm the send action + + + + &Send + &Send + + + + <b>%1</b> to %2 (%3) + <b>%1</b> to %2 (%3) + + + + Confirm send coins + Confirm send coins + + + + Are you sure you want to send %1? + Are you sure you want to send %1? + + + + and + and + + + + The recepient address is not valid, please recheck. + The recepient address is not valid, please recheck. + + + + The amount to pay must be larger than 0. + The amount to pay must be larger than 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Form + + + + A&mount: + A&mount: + + + + Pay &To: + Pay &To: + + + + + Enter a label for this address to add it to your address book + Enter a label for this address to add it to your address book + + + + &Label: + &Label: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Choose address from address book + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Paste address from clipboard + + + + Alt+P + Alt+P + + + + Remove this recipient + Remove this recipient + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Open for %1 blocks + + + + Open until %1 + Open until %1 + + + + %1/offline? + %1/offline? + + + + %1/unconfirmed + %1/unconfirmed + + + + %1 confirmations + %1 confirmations + + + + <b>Status:</b> + <b>Status:</b> + + + + , has not been successfully broadcast yet + , has not been successfully broadcast yet + + + + , broadcast through %1 node + , broadcast through %1 node + + + + , broadcast through %1 nodes + , broadcast through %1 nodes + + + + <b>Date:</b> + <b>Date:</b> + + + + <b>Source:</b> Generated<br> + <b>Source:</b> Generated<br> + + + + + <b>From:</b> + <b>From:</b> + + + + unknown + unknown + + + + + + <b>To:</b> + <b>To:</b> + + + + (yours, label: + (yours, label: + + + + (yours) + (yours) + + + + + + + <b>Credit:</b> + <b>Credit:</b> + + + + (%1 matures in %2 more blocks) + (%1 matures in %2 more blocks) + + + + (not accepted) + (not accepted) + + + + + + <b>Debit:</b> + <b>Debit:</b> + + + + <b>Transaction fee:</b> + <b>Transaction fee:</b> + + + + <b>Net amount:</b> + <b>Net amount:</b> + + + + Message: + Message: + + + + Comment: + Comment: + + + + Transaction ID: + ID da Transação: + + + + 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. + 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. + + + + TransactionDescDialog + + + Transaction details + Transaction details + + + + This pane shows a detailed description of the transaction + This pane shows a detailed description of the transaction + + + + TransactionTableModel + + + Date + Date + + + + Type + Type + + + + Address + Address + + + + Amount + Amount + + + + Open for %n block(s) + Open for %n blockOpen for %n blocks + + + + Open until %1 + Open until %1 + + + + Offline (%1 confirmations) + Offline (%1 confirmations) + + + + Unconfirmed (%1 of %2 confirmations) + Unconfirmed (%1 of %2 confirmations) + + + + Confirmed (%1 confirmations) + Confirmed (%1 confirmations) + + + + Mined balance will be available in %n more blocks + Mined balance will be available in %n more blockMined balance will be available in %n more blocks + + + + This block was not received by any other nodes and will probably not be accepted! + This block was not received by any other nodes and will probably not be accepted! + + + + Generated but not accepted + Generated but not accepted + + + + Received with + Received with + + + + Received from + Recebido de + + + + Sent to + Sent to + + + + Payment to yourself + Payment to yourself + + + + Mined + Mined + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + Transaction status. Hover over this field to show number of confirmations. + + + + Date and time that the transaction was received. + Date and time that the transaction was received. + + + + Type of transaction. + Type of transaction. + + + + Destination address of transaction. + Destination address of transaction. + + + + Amount removed from or added to balance. + Amount removed from or added to balance. + + + + TransactionView + + + + All + All + + + + Today + Today + + + + This week + This week + + + + This month + This month + + + + Last month + Last month + + + + This year + This year + + + + Range... + Range... + + + + Received with + Received with + + + + Sent to + Sent to + + + + To yourself + To yourself + + + + Mined + Mined + + + + Other + Other + + + + Enter address or label to search + Enter address or label to search + + + + Min amount + Min amount + + + + Copy address + Copy address + + + + Copy label + Copy label + + + + Copy amount + Copiar quantia + + + + Edit label + Edit label + + + + Show transaction details + + + + + Export Transaction Data + Export Transaction Data + + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + + Confirmed + Confirmed + + + + Date + Date + + + + Type + Type + + + + Label + Label + + + + Address + Address + + + + Amount + Amount + + + + ID + ID + + + + Error exporting + Error exporting + + + + Could not write to file %1. + Could not write to file %1. + + + + Range: + Range: + + + + to + to + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Copie o endereço selecionado para a área de transferência do sistema + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Sending... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Minimize to the tray instead of the taskbar + + + + Show only a tray icon after minimizing the window + Show only a tray icon after minimizing the window + + + + M&inimize on close + + + + + 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. + 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. + + + + bitcoin-core + + + Bitcoin version + Bitcoin version + + + + Usage: + Usage: + + + + Send command to -server or bitcoind + Send command to -server or bitcoind + + + + + List commands + List commands + + + + + Get help for a command + Get help for a command + + + + + Options: + Options: + + + + + Specify configuration file (default: bitcoin.conf) + Specify configuration file (default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + Specify pid file (default: bitcoind.pid) + + + + + Generate coins + Generate coins + + + + + Don't generate coins + Don't generate coins + + + + + Specify data directory + Specify data directory + + + + + Set database cache size in megabytes (default: 25) + Definir o tamanho do cache do banco de dados em megabytes (padrão: 25) + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Specify connection timeout (in milliseconds) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Procurar por conexões em <port> (padrão: 8333 ou testnet:18333) + + + + Maintain at most <n> connections to peers (default: 125) + Manter no máximo <n> conexões aos peers (padrão: 125) + + + + Connect only to the specified node + Connect only to the specified node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Limite para desconectar peers mal comportados (padrão: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Número de segundos para impedir que peers mal comportados reconectem (padrão: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Buffer máximo a ser recebido por conexão, <n>*1000 bytes (padrão: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Buffer de envio máximo por conexão, <n>*1000 bytes (padrão: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Accept command line and JSON-RPC commands + + + + + Run in the background as a daemon and accept commands + Run in the background as a daemon and accept commands + + + + + Use the test network + Use the test network + + + + + Output extra debugging information + Produzir informação extra para debugging + + + + Prepend debug output with timestamp + Pré anexar a saída de debug com estampa de tempo + + + + Send trace/debug info to console instead of debug.log file + Mandar informação de trace/debug para o console em vez de para o arquivo debug.log + + + + Send trace/debug info to debugger + Mandar informação de trace/debug para o debugger + + + + Username for JSON-RPC connections + Username for JSON-RPC connections + + + + + Password for JSON-RPC connections + Password for JSON-RPC connections + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Listen for JSON-RPC connections on <port> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + Allow JSON-RPC connections from specified IP address + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Send commands to node running on <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + Atualizar carteira para o formato mais recente + + + + Set key pool size to <n> (default: 100) + Set key pool size to <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + Rescan the block chain for missing wallet transactions + + + + + How many blocks to check at startup (default: 2500, 0 = all) + Quantos blocos verificar ao iniciar (padrão: 2500, 0 = todos) + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + + Use OpenSSL (https) for JSON-RPC connections + Use OpenSSL (https) for JSON-RPC connections + + + + + Server certificate file (default: server.cert) + Server certificate file (default: server.cert) + + + + + Server private key (default: server.pem) + Server private key (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + This help message + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Loading addresses... + + + + Error loading blkindex.dat + Erro ao carregar blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Erro ao carregar wallet.dat: Carteira corrompida + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Erro ao carregar wallet.dat: Carteira requer uma versão mais nova do Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + A Carteira precisou ser reescrita: reinicie o Bitcoin para completar + + + + Error loading wallet.dat + Erro ao carregar wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + Erro: Carteira bloqueada, incapaz de criar transação + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Error: Transaction creation failed + + + + Sending... + Enviando... + + + + 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. + 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. + + + + Invalid amount + + + + + Insufficient funds + Insufficient funds + + + + Loading block index... + Loading block index... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + Fee per KB to add to transactions you send + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Loading wallet... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Rescanning... + + + + Done loading + Done loading + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts new file mode 100644 index 0000000..bd7f74b --- /dev/null +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -0,0 +1,2518 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Sobre o Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> versão + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Todos os direitos reservados © 2009-2012 Programadores Bitcoin + +Este é um programa experimental. + +Distribuído sobre uma licença de software MIT/X11, por favor verifique o ficheiro anexo license.txt ou http://www.opensource.org/licenses/mit-license.php. + +Este produto inclui software desenvolvido pelo Projecto OpenSSL para uso no OpenSSL Toolkit (http://www.openssl.org/), software criptográfico escrito por Eric Young (eay@cryptsoft.com) e software UPnP escrito por Thomas Bernard. + + + + AddressBookPage + + + Address Book + Livro de endereços + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Estes são os seus endereços Bitcoin para receber pagamentos. Poderá enviar um endereço diferente para cada remetente para poder identificar os pagamentos. + + + + Double-click to edit address or label + Clique duas vezes para editar o endereço ou o rótulo + + + + Create a new address + Criar um novo endereço + + + + Copy the currently selected address to the system clipboard + Copie o endereço selecionado para a área de transferência + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Mostrar &Código QR + + + + Sign a message to prove you own this address + Assine uma mensagem para provar que é dono deste endereço + + + + &Sign Message + &Assinar Mensagem + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Eliminar o endereço selecionado da lista. Apenas endereços de envio podem ser eliminados. + + + + &Delete + &Eliminar + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Exportar de dados do Livro de Endereços + + + + Comma separated file (*.csv) + Ficheiro separado por vírgulas (*.csv) + + + + Error exporting + Erro ao exportar + + + + Could not write to file %1. + Could not write to file %1. + + + + AddressTableModel + + + Label + Rótulo + + + + Address + Endereço + + + + (no label) + (Sem rótulo) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Escreva a frase de segurança + + + + New passphrase + Nova frase de segurança + + + + Repeat new passphrase + Repita a nova frase de segurança + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Escreva a nova frase de seguraça da sua carteira. <br/> Por favor, use uma frase de <b>10 ou mais caracteres aleatórios,</b> ou <b>oito ou mais palavras.</b> + + + + Encrypt wallet + Encriptar carteira + + + + This operation needs your wallet passphrase to unlock the wallet. + A sua frase de segurança é necessária para desbloquear a carteira. + + + + Unlock wallet + Desbloquear carteira + + + + This operation needs your wallet passphrase to decrypt the wallet. + A sua frase de segurança é necessária para desencriptar a carteira. + + + + Decrypt wallet + Desencriptar carteira + + + + Change passphrase + Alterar frase de segurança + + + + Enter the old and new passphrase to the wallet. + Escreva a frase de segurança antiga seguida da nova para a carteira. + + + + Confirm wallet encryption + Confirmar encriptação da carteira + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + AVISO: Se encriptar a carteira e perder a sua senha irá <b>perder todos os seus BITCOINS!</b> Tem a certeza de que deseja encriptar a carteira? + + + + + Wallet encrypted + Carteira encriptada + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + O cliente Bitcoin irá agora ser fechado para terminar o processo de encriptação. Recorde que a encriptação da sua carteira não protegerá totalmente os seus bitcoins de serem roubados por programas maliciosos que infectem o seu computador. + + + + + Warning: The Caps Lock key is on. + Atenção: A tecla Caps Lock está activa. + + + + + + + Wallet encryption failed + A encriptação da carteira falhou + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + A encriptação da carteira falhou devido a um erro interno. A carteira não foi encriptada. + + + + + The supplied passphrases do not match. + As frases de segurança fornecidas não coincidem. + + + + Wallet unlock failed + O desbloqueio da carteira falhou + + + + + + The passphrase entered for the wallet decryption was incorrect. + A frase de segurança introduzida para a desencriptação da carteira estava incorreta. + + + + Wallet decryption failed + A desencriptação da carteira falhou + + + + Wallet passphrase was succesfully changed. + A frase de segurança da carteira foi alterada com êxito. + + + + BitcoinGUI + + + Bitcoin Wallet + Carteira Bitcoin + + + + Sign &message... + + + + + Show/Hide &Bitcoin + Mostrar/Ocultar &Bitcoin + + + + Synchronizing with network... + Sincronizando com a rede... + + + + &Overview + &Visão geral + + + + Show general overview of wallet + Mostrar visão geral da carteira + + + + &Transactions + &Transações + + + + Browse transaction history + Navegar pelo histórico de transações + + + + &Address Book + &Livro de endereços + + + + Edit the list of stored addresses and labels + Editar a lista de endereços e rótulos + + + + &Receive coins + &Receber moedas + + + + Show the list of addresses for receiving payments + Mostrar a lista de endereços para receber pagamentos + + + + &Send coins + &Enviar moedas + + + + Prove you control an address + Prove que controla um endereço + + + + E&xit + S&air + + + + Quit application + Sair da aplicação + + + + &About %1 + &Acerca de %1 + + + + Show information about Bitcoin + Mostrar informação sobre Bitcoin + + + + About &Qt + Sobre &Qt + + + + Show information about Qt + Mostrar informação sobre Qt + + + + &Options... + &Opções... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + ~%n bloco restante~%n blocos restantes + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Recuperados %1 de %2 blocos do histórico de transações (%3% completo) + + + + &Export... + &Exportar... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + Mostrar ou Ocultar a janela Bitcoin + + + + Export the data in the current tab to a file + Exportar os dados no separador actual para um ficheiro + + + + Encrypt or decrypt wallet + Encriptar ou desencriptar carteira + + + + Backup wallet to another location + Faça uma cópia de segurança da carteira para outra localização + + + + Change the passphrase used for wallet encryption + Mudar a frase de segurança utilizada na encriptação da carteira + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Ficheiro + + + + &Settings + &Configurações + + + + &Help + &Ajuda + + + + Tabs toolbar + Barra de separadores + + + + Actions toolbar + Barra de ações + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Cliente Bitcoin + + + + %n active connection(s) to Bitcoin network + %n ligação ativa à rede Bitcoin%n ligações ativas à rede Bitcoin + + + + Downloaded %1 blocks of transaction history. + Recuperados %1 blocos do histórico de transações. + + + + %n second(s) ago + %n segundo%n segundos + + + + %n minute(s) ago + %n minutos%n minutos + + + + %n hour(s) ago + %n hora%n horas + + + + %n day(s) ago + %n dia%n dias + + + + Up to date + Atualizado + + + + Catching up... + Recuperando... + + + + Last received block was generated %1. + Último bloco recebido foi gerado há %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Esta transação tem um tamanho superior ao limite máximo. Poderá enviá-la pagando uma taxa de %1 que será entregue ao nó que processar a sua transação e ajudará a suportar a rede. Deseja pagar a taxa? + + + + Confirm transaction fee + + + + + Sent transaction + Transação enviada + + + + Incoming transaction + Transação recebida + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Data: %1 +Quantidade: %2 +Tipo: %3 +Endereço: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + A carteira está <b>encriptada</b> e atualmente <b>desbloqueada</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + A carteira está <b>encriptada</b> e atualmente <b>bloqueada</b> + + + + Backup Wallet + Cópia de Segurança da Carteira + + + + Wallet Data (*.dat) + Dados da Carteira (*.dat) + + + + Backup Failed + Cópia de Segurança Falhada + + + + There was an error trying to save the wallet data to the new location. + Ocorreu um erro ao tentar guardar os dados da carteira na nova localização. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Janela + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Escolha a subdivisão unitária a ser mostrada por defeito na aplicação e ao enviar moedas + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Editar Endereço + + + + &Label + &Rótulo + + + + The label associated with this address book entry + O rótulo a ser associado com esta entrada do livro de endereços + + + + &Address + &Endereço + + + + The address associated with this address book entry. This can only be modified for sending addresses. + O endereço associado com esta entrada do livro de endereços. Apenas poderá ser modificado para endereços de saída. + + + + New receiving address + Novo endereço de entrada + + + + New sending address + Novo endereço de saída + + + + Edit receiving address + &Ajuda + + + + Edit sending address + Editar endereço de saída + + + + The entered address "%1" is already in the address book. + O endereço introduzido "%1" já se encontra no livro de endereços. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Impossível desbloquear carteira. + + + + New key generation failed. + Falha ao gerar nova chave. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Utilização: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + Definir linguagem, por exemplo "pt_PT" (por defeito: linguagem do sistema) + + + + Start minimized + Iniciar minimizado + + + + Show splash screen on startup (default: 1) + Mostrar animação ao iniciar (por defeito: 1) + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Pagar &taxa de transação + + + + Main + Geral + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Taxa de transação opcional por kB que ajuda a assegurar que as suas transações serão processadas rapidamente. A maioria das transações tem 1 kB. Taxa de 0.01 recomendada. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Pode assinar mensagens com os seus endereços para provar que são seus. Tenha atenção ao assinar mensagens ambíguas, pois ataques de phishing podem tentar enganá-lo, de modo a assinar a sua identidade para os atacantes. Apenas assine declarações completamente detalhadas com as quais concorde. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + O endereço a utilizar para assinar a mensagem (p.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Escolher endereço + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Paste address from clipboard + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Escreva aqui a mensagem que deseja assinar + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Clique "Assinar mensagem" para aceder á assinatura + + + + Sign a message to prove you own this address + Assine uma mensagem para provar que é dono deste endereço + + + + &Sign Message + &Assinar Mensagem + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Introduza um endereço Bitcoin (p.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Erro ao assinar + + + + %1 is not a valid address. + %1 não é um endereço válido. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + A chave privada para %1 não está disponível. + + + + Sign failed + Falha ao assinar + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Mapear porta usando &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Abrir a porta do cliente bitcoin automaticamente no seu router. Isto penas funciona se o seu router suportar UPnP e este se encontrar ligado. + + + + &Connect through SOCKS4 proxy: + &Ligar através de proxy SOCKS4: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Ligar à rede Bitcoin através de um proxy SOCKS4 (p.ex. quando ligar através de Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + Endereço IP do proxy (p.ex. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Porta do proxy (p.ex. 1234) + + + + OptionsDialog + + + Options + Opções + + + + OverviewPage + + + Form + Formulário + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Saldo: + + + + Number of transactions: + Número de transações: + + + + Unconfirmed: + Não confirmado: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Transações recentes</b> + + + + Your current balance + O seu saldo actual + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Total de transações ainda não confirmadas, e que não estão contabilizadas ainda no seu saldo actual + + + + Total number of transactions in wallet + Número total de transações na carteira + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + Código QR + + + + Request Payment + Requisitar Pagamento + + + + Amount: + Quantia: + + + + BTC + BTC + + + + Label: + Rótulo: + + + + Message: + Message: + + + + &Save As... + &Salvar Como... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + URI resultante muito longo. Tente reduzir o texto do rótulo / mensagem. + + + + Save QR Code + + + + + PNG Images (*.png) + Imagens PNG (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Enviar Moedas + + + + Send to multiple recipients at once + Enviar para múltiplos destinatários de uma vez + + + + &Add Recipient + + + + + Remove all transaction fields + Remover todos os campos da transação + + + + Clear &All + + + + + Balance: + Saldo: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Confirme ação de envio + + + + &Send + &Enviar + + + + <b>%1</b> to %2 (%3) + <b>%1</b> para %2 (%3) + + + + Confirm send coins + Confirme envio de moedas + + + + Are you sure you want to send %1? + Tem a certeza que deseja enviar %1? + + + + and + e + + + + The recepient address is not valid, please recheck. + O endereço de destino não é válido, por favor verifique. + + + + The amount to pay must be larger than 0. + A quantia a pagar deverá ser maior que 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Formulário + + + + A&mount: + Q&uantia: + + + + Pay &To: + Pagar &A: + + + + + Enter a label for this address to add it to your address book + Escreva um rótulo para este endereço para o adicionar ao seu livro de endereços + + + + &Label: + &Rótulo: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + O endereço para onde enviar o pagamento (p.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Escolher endereço do livro de endereços + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Cole endereço da área de transferência + + + + Alt+P + Alt+P + + + + Remove this recipient + Remover este destinatário + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Introduza um endereço Bitcoin (p.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Aberto para %1 blocos + + + + Open until %1 + Aberto até %1 + + + + %1/offline? + %1/desligado? + + + + %1/unconfirmed + %1/não confirmada + + + + %1 confirmations + %1 confirmações + + + + <b>Status:</b> + <b>Estado:</b> + + + + , has not been successfully broadcast yet + , ainda não foi transmitida com sucesso + + + + , broadcast through %1 node + , transmitida através de %1 nó + + + + , broadcast through %1 nodes + , transmitida através de %1 nós + + + + <b>Date:</b> + <b>Data:</b> + + + + <b>Source:</b> Generated<br> + <b>Fonte:</b> Geradas<br> + + + + + <b>From:</b> + <b>De:</b> + + + + unknown + desconhecido + + + + + + <b>To:</b> + <b>Para:</b> + + + + (yours, label: + (seu, rótulo: + + + + (yours) + (seu) + + + + + + + <b>Credit:</b> + <b>Crédito:</b> + + + + (%1 matures in %2 more blocks) + (%1 matura daqui por %2 blocos) + + + + (not accepted) + (não aceite) + + + + + + <b>Debit:</b> + <b>Débito:</b> + + + + <b>Transaction fee:</b> + <b>Taxa de transação:</b> + + + + <b>Net amount:</b> + <b>Valor líquido:</b> + + + + Message: + Mensagem: + + + + Comment: + Comentário: + + + + Transaction ID: + ID da Transação: + + + + 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. + Moedas geradas deverão maturar por 120 blocos antes de poderem ser gastas. Quando gerou este bloco, ele foi transmitido para a rede para ser incluído na cadeia de blocos. Se a inclusão na cadeia de blocos falhar, irá mudar o estado para "não aceite" e as moedas não poderão ser gastas. Isto poderá acontecer ocasionalmente se outro nó da rede gerar um bloco a poucos segundos de diferença do seu. + + + + TransactionDescDialog + + + Transaction details + Detalhes da transação + + + + This pane shows a detailed description of the transaction + Esta janela mostra uma descrição detalhada da transação + + + + TransactionTableModel + + + Date + Data + + + + Type + Tipo + + + + Address + Endereço + + + + Amount + Quantia + + + + Open for %n block(s) + Aberto para %n blocoAberto para %n blocos + + + + Open until %1 + Aberto até %1 + + + + Offline (%1 confirmations) + Desligado (%1 confirmação) + + + + Unconfirmed (%1 of %2 confirmations) + Não confirmada (%1 de %2 confirmações) + + + + Confirmed (%1 confirmations) + Confirmada (%1 confirmação) + + + + Mined balance will be available in %n more blocks + Saldo minado estará disponível daqui por %n blocoSaldo minado estará disponível daqui por %n blocos + + + + This block was not received by any other nodes and will probably not be accepted! + Este bloco não foi recebido por outros nós e provavelmente não será aceite pela rede! + + + + Generated but not accepted + Gerado mas não aceite + + + + Received with + Recebido com + + + + Received from + Recebido de + + + + Sent to + Enviado para + + + + Payment to yourself + Pagamento ao próprio + + + + Mined + Minado + + + + (n/a) + (n/d) + + + + Transaction status. Hover over this field to show number of confirmations. + Estado da transação. Pairar por cima deste campo para mostrar o número de confirmações. + + + + Date and time that the transaction was received. + Data e hora a que esta transação foi recebida. + + + + Type of transaction. + Tipo de transação. + + + + Destination address of transaction. + Endereço de destino da transação. + + + + Amount removed from or added to balance. + Quantia retirada ou adicionada ao saldo. + + + + TransactionView + + + + All + Todas + + + + Today + Hoje + + + + This week + Esta semana + + + + This month + Este mês + + + + Last month + Mês passado + + + + This year + Este ano + + + + Range... + Período... + + + + Received with + Recebida com + + + + Sent to + Enviada para + + + + To yourself + Para si + + + + Mined + Minadas + + + + Other + Outras + + + + Enter address or label to search + Escreva endereço ou rótulo a procurar + + + + Min amount + Quantia mínima + + + + Copy address + Copiar endereço + + + + Copy label + Copiar rótulo + + + + Copy amount + Copiar quantia + + + + Edit label + Editar rótulo + + + + Show transaction details + + + + + Export Transaction Data + Exportar Dados das Transações + + + + Comma separated file (*.csv) + Ficheiro separado por vírgula (*.csv) + + + + Confirmed + Confirmada + + + + Date + Data + + + + Type + Tipo + + + + Label + Rótulo + + + + Address + Endereço + + + + Amount + Quantia + + + + ID + ID + + + + Error exporting + Erro ao exportar + + + + Could not write to file %1. + Impossível escrever para o ficheiro %1. + + + + Range: + Período: + + + + to + até + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Copie o endereço selecionado para a área de transferência do sistema + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Enviando... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &Minimizar para a bandeja e não para a barra de ferramentas + + + + Show only a tray icon after minimizing the window + Apenas mostrar o ícone da bandeja depois de minimizar a janela + + + + M&inimize on close + + + + + 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. + Minimize ao invés de sair da aplicação quando a janela é fechada. Com esta opção selecionada, a aplicação apenas será encerrada quando escolher Sair da aplicação no menú. + + + + bitcoin-core + + + Bitcoin version + Versão Bitcoin + + + + Usage: + Utilização: + + + + Send command to -server or bitcoind + Enviar comando para -server ou bitcoind + + + + List commands + Listar comandos + + + + Get help for a command + Obter ajuda para um comando + + + + Options: + Opções: + + + + Specify configuration file (default: bitcoin.conf) + Especificar ficheiro de configuração (por defeito: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Especificar ficheiro pid (por defeito: bitcoind.pid) + + + + Generate coins + Gerar moedas + + + + Don't generate coins + Não gerar moedas + + + + Specify data directory + Especificar pasta de dados + + + + Set database cache size in megabytes (default: 25) + Definir o tamanho da cache de base de dados em megabytes (por defeito: 25) + + + + Set database disk log size in megabytes (default: 100) + Definir o tamanho de registo do disco de base de dados em megabytes (por defeito: 100) + + + + Specify connection timeout (in milliseconds) + Especificar tempo de espera da ligação (em millisegundos) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Escute por ligações em <port> (por defeito: 8333 ou testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Manter no máximo <n> ligações a outros nós da rede (por defeito: 125) + + + + Connect only to the specified node + Apenas ligar ao nó especificado + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Tolerância para desligar nós mal-formados (por defeito: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Número de segundos a impedir que nós mal-formados se liguem de novo (por defeito: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Armazenamento intermédio de recepção por ligação, <n>*1000 bytes (por defeito: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Armazenamento intermédio de envio por ligação, <n>*1000 bytes (por defeito: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Aceitar comandos da consola e JSON-RPC + + + + Run in the background as a daemon and accept commands + Correr o processo como um daemon e aceitar comandos + + + + Use the test network + Utilizar a rede de testes - testnet + + + + Output extra debugging information + Produzir informação de depuração extraordinária + + + + Prepend debug output with timestamp + Preceder informação de depuração com selo temporal + + + + Send trace/debug info to console instead of debug.log file + Enviar informação de rastreio/depuração para a consola e não para o ficheiro debug.log + + + + Send trace/debug info to debugger + Enviar informação de rastreio/depuração para o depurador + + + + Username for JSON-RPC connections + Nome de utilizador para ligações JSON-RPC + + + + Password for JSON-RPC connections + Palavra-passe para ligações JSON-RPC + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Escutar por ligações JSON-RPC na porta <port> (por defeito: 8332) + + + + Allow JSON-RPC connections from specified IP address + Permitir ligações JSON-RPC do endereço IP especificado + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Enviar comandos para o nó a correr em <ip> (por defeito: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Executar comando quando mudar o melhor bloco (na consola, %s é substituído pela hash do bloco) + + + + Upgrade wallet to latest format + Atualize a carteira para o formato mais recente + + + + Set key pool size to <n> (default: 100) + Definir o tamanho da memória de chaves para <n> (por defeito: 100) + + + + Rescan the block chain for missing wallet transactions + Reexaminar a cadeia de blocos para transações em falta na carteira + + + + How many blocks to check at startup (default: 2500, 0 = all) + Verificar quantos blocos ao iniciar (por defeito: 2500, 0 = todos) + + + + How thorough the block verification is (0-6, default: 1) + Minuciosidade da verificação de blocos é (0-6, por defeito: 1) + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +Opções SSL: (ver a Wiki Bitcoin para instruções de configuração SSL) + + + + Use OpenSSL (https) for JSON-RPC connections + Usar OpenSSL (https) para ligações JSON-RPC + + + + Server certificate file (default: server.cert) + Ficheiro de certificado do servidor (por defeito: server.cert) + + + + Server private key (default: server.pem) + Chave privada do servidor (por defeito: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Cifras aceitáveis (por defeito: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + Esta mensagem de ajuda + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Impossível trancar a pasta de dados %s. Provavelmente o Bitcoin já está a ser executado. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + A carregar endereços... + + + + Error loading blkindex.dat + Erro ao carregar blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Erro ao carregar wallet.dat: Carteira danificada + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Erro ao carregar wallet.dat: A Carteira requer uma versão mais recente do Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + A Carteira precisou ser reescrita: reinicie o Bitcoin para completar + + + + Error loading wallet.dat + Erro ao carregar wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + Erro: Carteira bloqueada, incapaz de criar transação + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Erro: Esta transação requer uma taxa de transação mínima de %s devido á sua quantia, complexidade, ou uso de fundos recebidos recentemente + + + + Error: Transaction creation failed + Error: Transaction creation failed + + + + Sending... + Enviando... + + + + 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. + 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. + + + + Invalid amount + Quantia inválida + + + + Insufficient funds + Insufficient funds + + + + Loading block index... + A carregar índice de blocos... + + + + Add a node to connect to and attempt to keep the connection open + Adicione um nó ao qual se ligar e tentar manter a ligação aberta + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + Encontrar pares usando IRC (por defeito: 0) + + + + Accept connections from outside (default: 1) + Aceitar ligações externas (por defeito: 1) + + + + Find peers using DNS lookup (default: 1) + Encontrar pares usando procura DNS (por defeito: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Usar Universal Plug and Play para mapear porta de escuta (por defeito: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Usar Universal Plug and Play para mapear porta de escuta (por defeito: 0) + + + + Fee per KB to add to transactions you send + Fee per KB to add to transactions you send + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + A carregar carteira... + + + + Cannot downgrade wallet + Impossível mudar a carteira para uma versão anterior + + + + Cannot initialize keypool + Impossível inicializar keypool + + + + Cannot write default address + Impossível escrever endereço por defeito + + + + Rescanning... + Reexaminando... + + + + Done loading + Carregamento completo + + + + To use the %s option + Para usar a opção %s + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, deverá definir uma palavra-passe de RPC no ficheiro de configuração : + %s +É recomendado que use a seguinte palavra-passe aleatória: +rpcuser=bitcoinrpc +rpcpassword=%s +(não precisa recordar esta palavra-passe) +Se o ficheiro não existir, crie-o com permissões de leitura apenas para o dono. + + + + + Error + Erro + + + + An error occured while setting up the RPC port %i for listening: %s + Ocorreu um erro ao definir a porta de escuta %i do serviço RPC: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Deverá definir rpcpassword=<password> no ficheiro de configuração: +%s +Se o ficheiro não existir, crie-o com permissões de leitura apenas para o dono. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Atenção: Por favor verifique que a data e hora do seu computador estão correctas. Se o seu relógio não estiver certo o Bitcoin não irá funcionar correctamente. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts new file mode 100644 index 0000000..6b8bbd3 --- /dev/null +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -0,0 +1,2500 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Despre Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> versiunea + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + Listă de adrese + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Acestea sunt adresele dumneavoastră Bitcoin pentru a primi plăţi. Dacă doriţi, puteți da o adresa diferită fiecărui expeditor, pentru a putea ţine evidenţa plăţilor. + + + + Double-click to edit address or label + Dublu-click pentru a edita adresa sau eticheta + + + + Create a new address + Creaţi o adresă nouă + + + + Copy the currently selected address to the system clipboard + Copiați adresa selectată în clipboard + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Ștergeți adresa selectată din listă. Doar adresele de trimitere pot fi șterse. + + + + &Delete + &Șterge + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Exportă Lista de adrese + + + + Comma separated file (*.csv) + Fisier csv: valori separate prin virgulă (*.csv) + + + + Error exporting + Eroare la exportare. + + + + Could not write to file %1. + Eroare la scrierea în fişerul %1. + + + + AddressTableModel + + + Label + Etichetă + + + + Address + Adresă + + + + (no label) + (fără etichetă) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Introduceți fraza de acces. + + + + New passphrase + Frază de acces nouă + + + + Repeat new passphrase + Repetaţi noua frază de acces + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Introduceţi noua parolă a portofelului electronic.<br/>Vă rugăm să folosiţi <b>minimum 10 caractere aleatoare</b>, sau <b>minimum 8 cuvinte</b>. + + + + Encrypt wallet + Criptează portofelul + + + + This operation needs your wallet passphrase to unlock the wallet. + Aceasta operație are nevoie de un portofel deblocat. + + + + Unlock wallet + Deblochează portofelul + + + + This operation needs your wallet passphrase to decrypt the wallet. + Această operaţiune necesită parola pentru decriptarea portofelului electronic. + + + + Decrypt wallet + Decriptează portofelul. + + + + Change passphrase + Schimbă fraza de acces + + + + Enter the old and new passphrase to the wallet. + Introduceţi vechea parola a portofelului eletronic şi apoi pe cea nouă. + + + + Confirm wallet encryption + Confirmă criptarea portofelului. + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ATENŢIE: Dacă pierdeţi parola portofelului electronic dupa criptare, <b>VEŢI PIERDE ÎNTREAGA SUMĂ DE BITCOIN ACUMULATĂ</b>! +Sunteţi sigur că doriţi să criptaţi portofelul electronic? + + + + + Wallet encrypted + Portofel criptat + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + Criptarea portofelului a eșuat. + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Criptarea portofelului a eșuat din cauza unei erori interne. Portofelul tău nu a fost criptat. + + + + + The supplied passphrases do not match. + Fraza de acces introdusă nu se potrivește. + + + + Wallet unlock failed + Deblocarea portofelului electronic a eşuat. + + + + + + The passphrase entered for the wallet decryption was incorrect. + Parola introdusă pentru decriptarea portofelului electronic a fost incorectă. + + + + Wallet decryption failed + Decriptarea portofelului electronic a eşuat. + + + + Wallet passphrase was succesfully changed. + Parola portofelului electronic a fost schimbată. + + + + BitcoinGUI + + + Bitcoin Wallet + Portofel electronic Bitcoin + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Se sincronizează cu reţeaua... + + + + &Overview + &Detalii + + + + Show general overview of wallet + Afişează detalii despre portofelul electronic + + + + &Transactions + &Tranzacţii + + + + Browse transaction history + Istoricul tranzacţiilor + + + + &Address Book + &Lista de adrese + + + + Edit the list of stored addresses and labels + Editaţi lista de adrese şi etichete. + + + + &Receive coins + &Primiţi Bitcoin + + + + Show the list of addresses for receiving payments + Lista de adrese pentru recepţionarea plăţilor + + + + &Send coins + &Trimiteţi Bitcoin + + + + Prove you control an address + + + + + E&xit + + + + + Quit application + Părăsiţi aplicaţia + + + + &About %1 + + + + + Show information about Bitcoin + Informaţii despre Bitcoin + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + &Setări... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Exportă... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + Criptează şi decriptează portofelul electronic + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + &Schimbă parola folosită pentru criptarea portofelului electronic + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Fişier + + + + &Settings + &Setări + + + + &Help + &Ajutor + + + + Tabs toolbar + Bara de ferestre de lucru + + + + Actions toolbar + Bara de acţiuni + + + + + [testnet] + [testnet] + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + %n active connections to Bitcoin network%n active connections to Bitcoin network%n active connections to Bitcoin network + + + + Downloaded %1 blocks of transaction history. + S-au descărcat %1 blocuri din istoricul tranzaciilor. + + + + %n second(s) ago + %n seconds ago%n seconds ago%n seconds ago + + + + %n minute(s) ago + Acum %n minutAcum %n minuteAcum %n minute + + + + %n hour(s) ago + Acum %n orăAcum %n oreAcum %n ore + + + + %n day(s) ago + Acum %n ziAcum %n zileAcum %n zile + + + + Up to date + Actualizat + + + + Catching up... + Se actualizează... + + + + Last received block was generated %1. + Ultimul bloc primit a fost generat %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Această tranzacţie depăşeşte limita. Puteţi iniţia tranzacţia platind un comision de %1, de care vor beneficia nodurile care procesează tranzacţia şi ajută la menţinerea reţelei. Acceptaţi plata comisionului? + + + + Confirm transaction fee + + + + + Sent transaction + Tranzacţie expediată + + + + Incoming transaction + Tranzacţie recepţionată + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Portofelul electronic este <b>criptat</b> iar in momentul de faţă este <b>deblocat</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Portofelul electronic este <b>criptat</b> iar in momentul de faţă este <b>blocat</b> + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Afişare + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Alege subdiviziunea folosită la afişarea interfeţei şi la trimiterea de bitcoin. + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Editează adresa + + + + &Label + &Eticheta + + + + The label associated with this address book entry + Eticheta asociată cu această înregistrare în Lista de adrese + + + + &Address + &Adresă + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Adresa asociată cu această înregistrare în Lista de adrese. Aceasta poate fi modificată doar pentru expediere. + + + + New receiving address + Noua adresă de primire + + + + New sending address + Noua adresă de trimitere + + + + Edit receiving address + Editează adresa de primire + + + + Edit sending address + Editează adresa de trimitere + + + + The entered address "%1" is already in the address book. + Adresa introdusă "%1" se află deja în Lista de adrese. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Portofelul electronic nu a putut fi deblocat . + + + + New key generation failed. + New key generation failed. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Uz: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Plăteşte comision pentru tranzacţie &f + + + + Main + Principal + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + Alegeţi adresa din Listă + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Lipiţi adresa copiată in clipboard. + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Introduceţi o adresă Bitcoin (de exemplu: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Mapeaza portul folosind &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Deschide automat în router portul aferent clientului Bitcoin. Funcţionează doar în cazul în care routerul e compatibil UPnP şi opţiunea e activată. + + + + &Connect through SOCKS4 proxy: + &Conectează prin proxy SOCKS4: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Conectare la reţeaua Bitcoin folosind un proxy SOCKS4 (de exemplu, când conexiunea se stabileşte prin reţeaua Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + Adresa de IP a proxy serverului (de exemplu: 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Portul pe care se concetează proxy serverul (de exemplu: 1234) + + + + OptionsDialog + + + Options + Setări + + + + OverviewPage + + + Form + Form + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Balanţă: + + + + Number of transactions: + Număr total de tranzacţii: + + + + Unconfirmed: + Neconfirmat: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Ultimele tranzacţii</b> + + + + Your current balance + Soldul contul + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Totalul tranzacţiilor care aşteaptă să fie confirmate şi care nu sunt încă luate în calcul la afişarea soldului contului. + + + + Total number of transactions in wallet + Numărul total de tranzacţii din portofelul electronic + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + Mesaj: + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Trimite Bitcoin + + + + Send to multiple recipients at once + Trimite simultan către mai mulţi destinatari + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + Balanţă: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Confirmă operaţiunea de trimitere + + + + &Send + &S Trimite + + + + <b>%1</b> to %2 (%3) + <b>%1</b> la %2 (%3) + + + + Confirm send coins + Confirmaţi trimiterea de bitcoin + + + + Are you sure you want to send %1? + Sunteţi sigur că doriţi să trimiteţi %1? + + + + and + şi + + + + The recepient address is not valid, please recheck. + Adresa destinatarului nu este validă, vă rugăm să o verificaţi. + + + + The amount to pay must be larger than 0. + Suma de plată trebuie să fie mai mare decât 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Form + + + + A&mount: + Su&mă : + + + + Pay &To: + Plăteşte Că&tre: + + + + + Enter a label for this address to add it to your address book + Adaugă o etichetă acestei adrese pentru a o trece în Lista de adrese + + + + &Label: + &L Etichetă: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adresa către care se va face plata (de exemplu: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Lipiţi adresa copiată in clipboard. + + + + Alt+P + Alt+P + + + + Remove this recipient + Şterge destinatarul + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Introduceţi o adresă Bitcoin (de exemplu: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Deschis pentru %1 blocuri + + + + Open until %1 + Deschis până la %1 + + + + %1/offline? + %1/offline? + + + + %1/unconfirmed + %1/neconfirmat + + + + %1 confirmations + %1 confirmări + + + + <b>Status:</b> + <b>Stare:</b> + + + + , has not been successfully broadcast yet + , nu s-a propagat încă + + + + , broadcast through %1 node + , se propagă prin %1 nod + + + + , broadcast through %1 nodes + , se propagă prin %1 noduri + + + + <b>Date:</b> + <b>Data:</b> + + + + <b>Source:</b> Generated<br> + <b>Sursă:</b> Generat<br> + + + + + <b>From:</b> + <b>De la:</b> + + + + unknown + necunoscut + + + + + + <b>To:</b> + <b>Către:</b> + + + + (yours, label: + (propriu, etichetă: + + + + (yours) + (propriu) + + + + + + + <b>Credit:</b> + <b>Credit:</b> + + + + (%1 matures in %2 more blocks) + (%1 se definitivează peste %2 blocuri) + + + + (not accepted) + (nu este acceptat) + + + + + + <b>Debit:</b> + <b>Debit:</b> + + + + <b>Transaction fee:</b> + <b>Comisionul tranzacţiei:</b> + + + + <b>Net amount:</b> + <b>Suma netă:</b> + + + + Message: + Mesaj: + + + + Comment: + Comentarii: + + + + Transaction ID: + + + + + 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. + Monedele bitcoin generate se pot cheltui dupa parcurgerea a 120 de blocuri. După ce a fost generat, s-a propagat în reţea, urmând să fie adăugat lanţului de blocuri. Dacă nu poate fi inclus in lanţ, starea sa va deveni "neacceptat" si nu va putea fi folosit la tranzacţii. Acest fenomen se întâmplă atunci cand un alt nod a generat un bloc la o diferenţa de câteva secunde. + + + + TransactionDescDialog + + + Transaction details + Detaliile tranzacţiei + + + + This pane shows a detailed description of the transaction + Afişează detalii despre tranzacţie + + + + TransactionTableModel + + + Date + Data + + + + Type + Tipul + + + + Address + Adresa + + + + Amount + Cantitate + + + + Open for %n block(s) + Deschis pentru for %n blocDeschis pentru %n blocuriDeschis pentru %n blocuri + + + + Open until %1 + Deschis până la %1 + + + + Offline (%1 confirmations) + Neconectat (%1 confirmări) + + + + Unconfirmed (%1 of %2 confirmations) + Neconfirmat (%1 din %2 confirmări) + + + + Confirmed (%1 confirmations) + Confirmat (%1 confirmări) + + + + Mined balance will be available in %n more blocks + Soldul de bitcoin produs va fi disponibil după încă %n blocSoldul de bitcoin produs va fi disponibil după încă %n blocuriSoldul de bitcoin produs va fi disponibil după încă %n blocuri + + + + This block was not received by any other nodes and will probably not be accepted! + Blocul nu a fost recepţionat de niciun alt nod şi e probabil că nu va fi acceptat. + + + + Generated but not accepted + Generat, dar neacceptat + + + + Received with + Recepţionat cu + + + + Received from + + + + + Sent to + Trimis către + + + + Payment to yourself + Plată către un cont propriu + + + + Mined + Produs + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + Starea tranzacţiei. Treceţi cu mouse-ul peste acest câmp pentru afişarea numărului de confirmări. + + + + Date and time that the transaction was received. + Data şi ora la care a fost recepţionată tranzacţia. + + + + Type of transaction. + Tipul tranzacţiei. + + + + Destination address of transaction. + Adresa de destinaţie a tranzacţiei. + + + + Amount removed from or added to balance. + Suma extrasă sau adăugată la sold. + + + + TransactionView + + + + All + Toate + + + + Today + Astăzi + + + + This week + Săptămâna aceasta + + + + This month + Luna aceasta + + + + Last month + Luna trecută + + + + This year + Anul acesta + + + + Range... + Între... + + + + Received with + Recepţionat cu... + + + + Sent to + Trimis către + + + + To yourself + Către propriul cont + + + + Mined + Produs + + + + Other + Altele + + + + Enter address or label to search + Introduceţi adresa sau eticheta pentru căutare + + + + Min amount + Cantitatea produsă + + + + Copy address + Copiază adresa + + + + Copy label + Copiază eticheta + + + + Copy amount + + + + + Edit label + Editează eticheta + + + + Show transaction details + + + + + Export Transaction Data + Exportă tranzacţiile + + + + Comma separated file (*.csv) + Fişier text cu valori separate prin virgulă (*.csv) + + + + Confirmed + Confirmat + + + + Date + Data + + + + Type + Tipul + + + + Label + Etichetă + + + + Address + Adresă + + + + Amount + Sumă + + + + ID + ID + + + + Error exporting + Eroare în timpul exportului + + + + Could not write to file %1. + Fisierul %1 nu a putut fi accesat pentru scriere. + + + + Range: + Interval: + + + + to + către + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Copiați adresa selectată în clipboard + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Se expediază... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + &M Ascunde în tray în loc de taskbar + + + + Show only a tray icon after minimizing the window + Afişează doar un icon in tray la ascunderea ferestrei + + + + M&inimize on close + + + + + 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. + Ascunde fereastra în locul părăsirii programului în momentul închiderii ferestrei. Când acestă opţiune e activă, aplicaţia se va opri doar în momentul selectării comenzii Quit din menu. + + + + bitcoin-core + + + Bitcoin version + versiunea Bitcoin + + + + Usage: + Uz: + + + + Send command to -server or bitcoind + Trimite comanda la -server sau bitcoind + + + + List commands + Listă de comenzi + + + + Get help for a command + Ajutor pentru o comandă + + + + Options: + Setări: + + + + Specify configuration file (default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + + + + + Generate coins + + + + + Don't generate coins + + + + + Specify data directory + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + + + + + Run in the background as a daemon and accept commands + + + + + Use the test network + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + + + + + Password for JSON-RPC connections + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + + Use OpenSSL (https) for JSON-RPC connections + + + + + Server certificate file (default: server.cert) + + + + + Server private key (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Încarc adrese... + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Eroare: Tranyacţia nu a putut fi iniţiată + + + + Sending... + Transmitere... + + + + 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. + Eroare: Tranyacţia a fost respinsă. Acesta poate fi rezultatul cheltuirii prealabile a unei sume de bitcoin din portofelul electronic, ca în cazul folosirii unei copii a fisierului wallet.dat, în care s-au efectuat tranzacţii neînregistrate în fisierul curent. + + + + Invalid amount + + + + + Insufficient funds + Fonduri insuficiente + + + + Loading block index... + Încarc indice bloc... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Încarc portofel... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Rescanez... + + + + Done loading + Încărcare terminată + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts new file mode 100644 index 0000000..f4e3c8c --- /dev/null +++ b/src/qt/locale/bitcoin_ru.ts @@ -0,0 +1,2521 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + О Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> версия + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Все права защищены © 2009-2012 Разработчики Bitcoin + +Это экспериментальная программа. + +Распространяется на правах лицензии MIT/X11, см. файл license.txt или http://www.opensource.org/licenses/mit-license.php. + +Этот продукт включает ПО, разработанное OpenSSL Project для использования в OpenSSL Toolkit (http://www.openssl.org/) и криптографическое ПО, написанное Eric Young (eay@cryptsoft.com) и ПО для работы с UPnP, написанное Thomas Bernard. + + + + AddressBookPage + + + Address Book + Адресная книга + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Здесь перечислены Ваши адреса для получения платежей. Вы можете использовать их для того, чтобы давать разным людям разные адреса и, таким образом, иметь возможность отслеживать, кто и сколько Вам платил, а также поддерживать бо́льшую анонимность. + + + + Double-click to edit address or label + Для того, чтобы изменить адрес или метку давжды кликните по изменяемому объекту + + + + Create a new address + Создать новый адрес + + + + Copy the currently selected address to the system clipboard + Копировать текущий выделенный адрес в буфер обмена + + + + &New Address + &Новый адрес + + + + &Copy Address + &Копировать адрес + + + + Show &QR Code + Показать &QR код + + + + Sign a message to prove you own this address + Подпишите сообщение для доказательства + + + + &Sign Message + &Подписать сообщение + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Удалить выделенный адрес из списка (могут быть удалены только записи из адресной книги). + + + + &Delete + &Удалить + + + + Copy &Label + Копировать &метку + + + + &Edit + &Правка + + + + Export Address Book Data + Экспортировать адресную книгу + + + + Comma separated file (*.csv) + Текст, разделённый запятыми (*.csv) + + + + Error exporting + Ошибка экспорта + + + + Could not write to file %1. + Невозможно записать в файл %1. + + + + AddressTableModel + + + Label + Метка + + + + Address + Адрес + + + + (no label) + [нет метки] + + + + AskPassphraseDialog + + + Passphrase Dialog + Диалог ввода пароля + + + + Enter passphrase + Введите пароль + + + + New passphrase + Новый пароль + + + + Repeat new passphrase + Повторите новый пароль + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Введите новый пароль для бумажника. <br/> Пожалуйста, используйте фразы из <b>10 или более случайных символов,</b> или <b>восьми и более слов.</b> + + + + Encrypt wallet + Зашифровать бумажник + + + + This operation needs your wallet passphrase to unlock the wallet. + Для выполнения операции требуется пароль вашего бумажника. + + + + Unlock wallet + Разблокировать бумажник + + + + This operation needs your wallet passphrase to decrypt the wallet. + Для выполнения операции требуется пароль вашего бумажника. + + + + Decrypt wallet + Расшифровать бумажник + + + + Change passphrase + Сменить пароль + + + + Enter the old and new passphrase to the wallet. + Введите старый и новый пароль для бумажника. + + + + Confirm wallet encryption + Подтвердите шифрование бумажника + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + ВНИМАНИЕ: Если вы зашифруете бумажник и потеряете свой ​​пароль, вы <b>ПОТЕРЯЕТЕ ВСЕ ВАШИ БИТКОИНЫ!</b> +Вы действительно хотите зашифровать ваш бумажник? + + + + + Wallet encrypted + Бумажник зашифрован + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Сейчас программа закроется для завершения процесса шифрования. Помните, что шифрование вашего бумажника не может полностью защитить ваши биткоины от кражи с помощью инфицирования вашего компьютера вредоносным ПО. + + + + + Warning: The Caps Lock key is on. + Внимание: Caps Lock включен. + + + + + + + Wallet encryption failed + Не удалось зашифровать бумажник + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Шифрование бумажника не удалось из-за внутренней ошибки. Ваш бумажник не был зашифрован. + + + + + The supplied passphrases do not match. + Введённые пароли не совпадают. + + + + Wallet unlock failed + Разблокировка бумажника не удалась + + + + + + The passphrase entered for the wallet decryption was incorrect. + Указанный пароль не подходит. + + + + Wallet decryption failed + Расшифрование бумажника не удалось + + + + Wallet passphrase was succesfully changed. + Пароль бумажника успешно изменён. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin-бумажник + + + + Sign &message... + &Подписать сообщение + + + + Show/Hide &Bitcoin + Показать/Скрыть &Bitcoin + + + + Synchronizing with network... + Синхронизация с сетью... + + + + &Overview + О&бзор + + + + Show general overview of wallet + Показать общий обзор действий с бумажником + + + + &Transactions + &Транзакции + + + + Browse transaction history + Показать историю транзакций + + + + &Address Book + &Адресная книга + + + + Edit the list of stored addresses and labels + Изменить список сохранённых адресов и меток к ним + + + + &Receive coins + &Получение монет + + + + Show the list of addresses for receiving payments + Показать список адресов для получения платежей + + + + &Send coins + Отп&равка монет + + + + Prove you control an address + Доказать, что вы владеете адресом + + + + E&xit + В&ыход + + + + Quit application + Закрыть приложение + + + + &About %1 + &О %1 + + + + Show information about Bitcoin + Показать информацию о Bitcoin'е + + + + About &Qt + О &Qt + + + + Show information about Qt + Показать информацию о Qt + + + + &Options... + Оп&ции... + + + + &Encrypt Wallet... + &Зашифровать бумажник + + + + &Backup Wallet... + &Сделать резервную копию бумажника + + + + &Change Passphrase... + &Изменить пароль + + + + ~%n block(s) remaining + остался ~%n блокосталось ~%n блоковосталось ~%n блоков + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Загружено %1 из %2 блоков истории операций (%3% завершено). + + + + &Export... + &Экспорт... + + + + Send coins to a Bitcoin address + Отправить монеты на указанный адрес Bitcoin + + + + Modify configuration options for Bitcoin + Изменить параметры конфигурации Bitcoin + + + + Show or hide the Bitcoin window + Показать или скрыть окно Bitcoin + + + + Export the data in the current tab to a file + Экспортировать данные из вкладки в файл + + + + Encrypt or decrypt wallet + Зашифровать или расшифровать бумажник + + + + Backup wallet to another location + Сделать резервную копию бумажника в другом месте + + + + Change the passphrase used for wallet encryption + Изменить пароль шифрования бумажника + + + + &Debug window + &Окно отладки + + + + Open debugging and diagnostic console + Открыть консоль отладки и диагностики + + + + &Verify message... + &Проверить сообщение... + + + + Verify a message signature + Проверить подпись сообщения + + + + &File + &Файл + + + + &Settings + &Настройки + + + + &Help + &Помощь + + + + Tabs toolbar + Панель вкладок + + + + Actions toolbar + Панель действий + + + + + [testnet] + [тестовая сеть] + + + + + Bitcoin client + Bitcoin клиент + + + + %n active connection(s) to Bitcoin network + %n активное соединение с сетью%n активных соединений с сетью%n активных соединений с сетью + + + + Downloaded %1 blocks of transaction history. + Загружено %1 блоков истории транзакций. + + + + %n second(s) ago + %n секунду назад%n секунды назад%n секунд назад + + + + %n minute(s) ago + %n минуту назад%n минуты назад%n минут назад + + + + %n hour(s) ago + %n час назад%n часа назад%n часов назад + + + + %n day(s) ago + %n день назад%n дня назад%n дней назад + + + + Up to date + Синхронизированно + + + + Catching up... + Синхронизируется... + + + + Last received block was generated %1. + Последний полученный блок был сгенерирован %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Данная транзакция превышает предельно допустимый размер. Но Вы можете всё равно совершить её, добавив комиссию в %1, которая отправится тем узлам, которые обработают Вашу транзакцию, и поможет поддержать сеть. Вы хотите добавить комиссию? + + + + Confirm transaction fee + Подтвердите комиссию + + + + Sent transaction + Исходящая транзакция + + + + Incoming transaction + Входящая транзакция + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Дата: %1 +Количество: %2 +Тип: %3 +Адрес: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Бумажник <b>зашифрован</b> и в настоящее время <b>разблокирован</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Бумажник <b>зашифрован</b> и в настоящее время <b>заблокирован</b> + + + + Backup Wallet + Сделать резервную копию бумажника + + + + Wallet Data (*.dat) + Данные бумажника (*.dat) + + + + Backup Failed + Резервное копирование не удалось + + + + There was an error trying to save the wallet data to the new location. + При попытке сохранения данных бумажника в новое место произошла ошибка. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + Обнаружена неисправимая ошибка. Bitcoin не может продолжать безопасную работу и будет закрыт. + + + + ClientModel + + + Network Alert + Сетевая Тревога + + + + DisplayOptionsPage + + + Display + Отображение + + + + default + по умолчанию + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + Здесь можно выбрать язык интерфейса. Настройки вступят в силу после перезапуска Bitcoin. + + + + User Interface &Language: + &Язык интерфейса + + + + &Unit to show amounts in: + &Отображать суммы в единицах: + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Единица измерения количества монет при отображении и при отправке + + + + &Display addresses in transaction list + &Показывать адреса в списке транзакций + + + + Whether to show Bitcoin addresses in the transaction list + Показывать ли адреса Bitcoin в списке транзакций + + + + Warning + Внимание + + + + This setting will take effect after restarting Bitcoin. + Эта настройка вступит в силу после перезапуска Bitcoin + + + + EditAddressDialog + + + Edit Address + Изменить адрес + + + + &Label + &Метка + + + + The label associated with this address book entry + Метка, связанная с данной записью + + + + &Address + &Адрес + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Адрес, связанный с данной записью. + + + + New receiving address + Новый адрес для получения + + + + New sending address + Новый адрес для отправки + + + + Edit receiving address + Изменение адреса для получения + + + + Edit sending address + Изменение адреса для отправки + + + + The entered address "%1" is already in the address book. + Введённый адрес «%1» уже находится в адресной книге. + + + + The entered address "%1" is not a valid Bitcoin address. + Введённый адрес "%1" не является правильным Bitcoin-адресом. + + + + Could not unlock wallet. + Не удается разблокировать бумажник. + + + + New key generation failed. + Генерация нового ключа не удалась. + + + + HelpMessageBox + + + + Bitcoin-Qt + Bitcoin-Qt + + + + version + версия + + + + Usage: + Использование: + + + + options + опции + + + + UI options + Опции интерфейса + + + + Set language, for example "de_DE" (default: system locale) + Выберите язык, например "de_DE" (по умолчанию: как в системе) + + + + Start minimized + Запускать свёрнутым + + + + Show splash screen on startup (default: 1) + Показывать сплэш при запуске (по умолчанию: 1) + + + + MainOptionsPage + + + 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. + Отключить базы данных блоков и адресов при выходе. Это означает, что их можно будет переместить в другой каталог данных, но завершение работы будет медленнее. Бумажник всегда отключается. + + + + Pay transaction &fee + Добавлять ко&миссию + + + + Main + Основное + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Опциональная комиссия за каждый КБ транзакции, которая позволяет быть уверенным, что Ваша транзакция будет обработана быстро. Большинство транзакций занимают 1КБ. Рекомендуется комиссия 0.01. + + + + &Start Bitcoin on system login + &Запускать Bitcoin при входе в систему + + + + Automatically start Bitcoin after logging in to the system + Автоматически запускать Bitcoin после входа в систему + + + + &Detach databases at shutdown + &Отключать базы данных при выходе + + + + MessagePage + + + Sign Message + Подписать сообщение + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Вы можете подписывать сообщения своими адресами, чтобы доказать владение ими. Будьте осторожны, не подписывайте что-то неопределённое, так как фишинговые атаки могут обманным путём заставить вас подписать нежелательные сообщения. Подписывайте только те сообщения, с которыми вы согласны вплоть до мелочей. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Адрес, которым вы хотите подписать сообщение (напр. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Выбрать адрес из адресной книги + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Вставить адрес из буфера обмена + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Введите сообщение для подписи + + + + Copy the current signature to the system clipboard + Скопировать текущую подпись в системный буфер обмена + + + + &Copy Signature + &Копировать подпись + + + + Reset all sign message fields + Сбросить значения всех полей подписывания сообщений + + + + Clear &All + Очистить &всё + + + + Click "Sign Message" to get signature + Для создания подписи нажмите на "Подписать сообщение" + + + + Sign a message to prove you own this address + Подпишите сообщение для доказательства + + + + &Sign Message + &Подписать сообщение + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Введите адрес Bitcoin (напр. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Ошибка создания подписи + + + + %1 is not a valid address. + %1 не является правильным адресом. + + + + %1 does not refer to a key. + %1 не связан с ключом + + + + Private key for %1 is not available. + Секретный ключ для %1 не доступен + + + + Sign failed + Подписание не удалось. + + + + NetworkOptionsPage + + + Network + Сеть + + + + Map port using &UPnP + Пробросить порт через &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Автоматически открыть порт для Bitcoin-клиента на роутере. Работает только если Ваш роутер поддерживает UPnP, и данная функция включена. + + + + &Connect through SOCKS4 proxy: + &Подключаться через SOCKS4 прокси: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Подключаться к сети Bitcoin через прокси SOCKS4 (например, при использовании Tor) + + + + Proxy &IP: + &IP Прокси: + + + + &Port: + По&рт: + + + + IP address of the proxy (e.g. 127.0.0.1) + IP-адрес прокси (например 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Порт прокси-сервера (например 1234) + + + + OptionsDialog + + + Options + Опции + + + + OverviewPage + + + Form + Форма + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + Отображаемая информация может быть устаревшей. Ваш бумажник автоматически синхронизируется с сетью Bitcoin после подключения, но этот процесс пока не завершён. + + + + Balance: + Баланс: + + + + Number of transactions: + Количество транзакций: + + + + Unconfirmed: + Не подтверждено: + + + + Wallet + Бумажник + + + + <b>Recent transactions</b> + <b>Последние транзакции</b> + + + + Your current balance + Ваш текущий баланс + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Общая сумма всех транзакций, которые до сих пор не подтверждены, и до сих пор не учитываются в текущем балансе + + + + Total number of transactions in wallet + Общее количество транзакций в Вашем бумажнике + + + + + out of sync + не синхронизировано + + + + QRCodeDialog + + + QR Code Dialog + Диалог QR-кода + + + + QR Code + QR код + + + + Request Payment + Запросить платёж + + + + Amount: + Количество: + + + + BTC + BTC + + + + Label: + Метка: + + + + Message: + Сообщение: + + + + &Save As... + &Сохранить как... + + + + Error encoding URI into QR Code. + Ошибка кодирования URI в QR-код + + + + Resulting URI too long, try to reduce the text for label / message. + Получившийся URI слишком длинный, попробуйте сократить текст метки / сообщения. + + + + Save QR Code + Сохранить QR-код + + + + PNG Images (*.png) + PNG Изображения (*.png) + + + + RPCConsole + + + Bitcoin debug window + Окно отладки Bitcoin + + + + Client name + Имя клиента + + + + + + + + + + + + N/A + Н/Д + + + + Client version + Версия клиента + + + + &Information + &Информация + + + + Client + Клиент + + + + Startup time + Время запуска + + + + Network + Сеть + + + + Number of connections + Число подключений + + + + On testnet + В тестовой сети + + + + Block chain + Цепь блоков + + + + Current number of blocks + Текущее число блоков + + + + Estimated total blocks + Расчётное число блоков + + + + Last block time + Время последнего блока + + + + Debug logfile + Отладочный лог-файл + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + Открыть отладочный лог-файл Bitcoin из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов. + + + + &Open + &Открыть + + + + &Console + Консоль + + + + Build date + Дата сборки + + + + Clear console + Очистить консоль + + + + Welcome to the Bitcoin RPC console. + Добро пожаловать в RPC-консоль Bitcoin. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Используйте стрелки вверх и вниз для просмотра истории и <b>Ctrl-L</b> для очистки экрана. + + + + Type <b>help</b> for an overview of available commands. + Напишите <b>help</b> для просмотра доступных команд. + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Отправка + + + + Send to multiple recipients at once + Отправить нескольким получателям одновременно + + + + &Add Recipient + &Добавить получателя + + + + Remove all transaction fields + Удалить все поля транзакции + + + + Clear &All + Очистить &всё + + + + Balance: + Баланс: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Подтвердить отправку + + + + &Send + &Отправить + + + + <b>%1</b> to %2 (%3) + <b>%1</b> адресату %2 (%3) + + + + Confirm send coins + Подтвердите отправку монет + + + + Are you sure you want to send %1? + Вы уверены, что хотите отправить %1? + + + + and + и + + + + The recepient address is not valid, please recheck. + Адрес получателя неверный, пожалуйста, перепроверьте. + + + + The amount to pay must be larger than 0. + Количество монет для отправки должно быть больше 0. + + + + The amount exceeds your balance. + Количество отправляемых монет превышает Ваш баланс + + + + The total exceeds your balance when the %1 transaction fee is included. + Сумма превысит Ваш баланс, если комиссия в размере %1 будет добавлена к транзакции + + + + Duplicate address found, can only send to each address once per send operation. + Обнаружен дублирующийся адрес. Отправка на один и тот же адрес возможна только один раз за одну операцию отправки + + + + Error: Transaction creation failed. + Ошибка: не удалось создать транзакцию. + + + + 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. + Ошибка: В транзакции отказано. Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию файла wallet.dat, а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой. + + + + SendCoinsEntry + + + Form + Форма + + + + A&mount: + Ко&личество: + + + + Pay &To: + Полу&чатель: + + + + + Enter a label for this address to add it to your address book + Введите метку для данного адреса (для добавления в адресную книгу) + + + + &Label: + &Метка: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Адрес получателя платежа (например 1LA5FtQhnnWnkK6zjFfutR7Stiit4wKd63) + + + + Choose address from address book + Выберите адрес из адресной книги + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Вставить адрес из буфера обмена + + + + Alt+P + Alt+P + + + + Remove this recipient + Удалить этого получателя + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Введите Bitcoin-адрес (например 1LA5FtQhnnWnkK6zjFfutR7Stiit4wKd63) + + + + TransactionDesc + + + Open for %1 blocks + Открыто до получения %1 блоков + + + + Open until %1 + Открыто до %1 + + + + %1/offline? + %1/оффлайн? + + + + %1/unconfirmed + %1/не подтверждено + + + + %1 confirmations + %1 подтверждений + + + + <b>Status:</b> + <b>Статус:</b> + + + + , has not been successfully broadcast yet + , ещё не было успешно разослано + + + + , broadcast through %1 node + , разослано через %1 узел + + + + , broadcast through %1 nodes + , разослано через %1 узлов + + + + <b>Date:</b> + <b>Дата:</b> + + + + <b>Source:</b> Generated<br> + <b>Источник:</b> [сгенерированно]<br> + + + + + <b>From:</b> + <b>Отправитель:</b> + + + + unknown + неизвестно + + + + + + <b>To:</b> + <b>Получатель:</b> + + + + (yours, label: + (Ваш, метка: + + + + (yours) + (ваш) + + + + + + + <b>Credit:</b> + <b>Кредит:</b> + + + + (%1 matures in %2 more blocks) + (%1 станет доступно через %2 блоков) + + + + (not accepted) + (не принято) + + + + + + <b>Debit:</b> + <b>Дебет:</b> + + + + <b>Transaction fee:</b> + <b>Комиссия:</b> + + + + <b>Net amount:</b> + <b>Общая сумма:</b> + + + + Message: + Сообщение: + + + + Comment: + Комментарий: + + + + Transaction ID: + Идентификатор транзакции: + + + + 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. + Сгенерированные монеты должны подождать 120 блоков прежде, чем они смогут быть отправлены. Когда Вы сгенерировали этот блок он был отправлен в сеть, чтобы он был добавлен к цепочке блоков. Если данная процедура не удастся, статус изменится на «не подтверждено» и монеты будут непередаваемыми. Такое может случайно происходить в случае, если другой узел сгенерирует блок на несколько секунд раньше. + + + + TransactionDescDialog + + + Transaction details + Детали транзакции + + + + This pane shows a detailed description of the transaction + Данный диалог показывает детализированную статистику по выбранной транзакции + + + + TransactionTableModel + + + Date + Дата + + + + Type + Тип + + + + Address + Адрес + + + + Amount + Количество + + + + Open for %n block(s) + Открыто для %n блокаОткрыто для %n блоковОткрыто для %n блоков + + + + Open until %1 + Открыто до %1 + + + + Offline (%1 confirmations) + Оффлайн (%1 подтверждений) + + + + Unconfirmed (%1 of %2 confirmations) + Не подтверждено (%1 из %2 подтверждений) + + + + Confirmed (%1 confirmations) + Подтверждено (%1 подтверждений) + + + + Mined balance will be available in %n more blocks + Добытыми монетами можно будет воспользоваться через %n блокДобытыми монетами можно будет воспользоваться через %n блокаДобытыми монетами можно будет воспользоваться через %n блоков + + + + This block was not received by any other nodes and will probably not be accepted! + Этот блок не был получен другими узлами и, возможно, не будет принят! + + + + Generated but not accepted + Сгенерированно, но не подтверждено + + + + Received with + Получено + + + + Received from + Получено от + + + + Sent to + Отправлено + + + + Payment to yourself + Отправлено себе + + + + Mined + Добыто + + + + (n/a) + [не доступно] + + + + Transaction status. Hover over this field to show number of confirmations. + Статус транзакции. Подведите курсор к нужному полю для того, чтобы увидеть количество подтверждений. + + + + Date and time that the transaction was received. + Дата и время, когда транзакция была получена. + + + + Type of transaction. + Тип транзакции. + + + + Destination address of transaction. + Адрес назначения транзакции. + + + + Amount removed from or added to balance. + Сумма, добавленная, или снятая с баланса. + + + + TransactionView + + + + All + Все + + + + Today + Сегодня + + + + This week + На этой неделе + + + + This month + В этом месяце + + + + Last month + За последний месяц + + + + This year + В этом году + + + + Range... + Промежуток... + + + + Received with + Получено на + + + + Sent to + Отправлено на + + + + To yourself + Отправленные себе + + + + Mined + Добытые + + + + Other + Другое + + + + Enter address or label to search + Введите адрес или метку для поиска + + + + Min amount + Мин. сумма + + + + Copy address + Копировать адрес + + + + Copy label + Копировать метку + + + + Copy amount + Скопировать сумму + + + + Edit label + Изменить метку + + + + Show transaction details + Показать подробности транзакции + + + + Export Transaction Data + Экспортировать данные транзакций + + + + Comma separated file (*.csv) + Текст, разделённый запятыми (*.csv) + + + + Confirmed + Подтверждено + + + + Date + Дата + + + + Type + Тип + + + + Label + Метка + + + + Address + Адрес + + + + Amount + Количество + + + + ID + ID + + + + Error exporting + Ошибка экспорта + + + + Could not write to file %1. + Невозможно записать в файл %1. + + + + Range: + Промежуток от: + + + + to + до + + + + VerifyMessageDialog + + + Verify Signed Message + Проверить подписанное сообщение + + + + 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. + Введите ниже сообщение и подпись (копируйте в точности переводы строк, пробелы, табы и иные невидимые или малозаметные символы), чтобы получить адрес Bitcoin, который использовался при подписывании сообщения. + + + + Verify a message and obtain the Bitcoin address used to sign the message + Проверить сообщение и получить адрес Bitcoin, который использовался для подписи + + + + &Verify Message + &Проверить сообщение + + + + Copy the currently selected address to the system clipboard + Скопировать выбранный адрес в системный буфер обмена + + + + &Copy Address + &Копировать адрес + + + + Reset all verify message fields + Сбросить все поля проверки сообщения + + + + Clear &All + Очистить &всё + + + + Enter Bitcoin signature + Введите подпись Bitcoin + + + + Click "Verify Message" to obtain address + Щёлкните "Проверить сообщение" для получения адреса + + + + + Invalid Signature + Неверная подпись + + + + The signature could not be decoded. Please check the signature and try again. + Не удаётся декодировать подпись. Проверьте подпись и попробуйте ещё раз. + + + + The signature did not match the message digest. Please check the signature and try again. + Подпись не совпадает с контрольной суммой сообщения. Проверьте подпись и попробуйте ещё раз. + + + + Address not found in address book. + Адрес не найден в адресной книге. + + + + Address found in address book: %1 + Адрес найден в адресной книге: %1 + + + + WalletModel + + + Sending... + Отправка.... + + + + WindowOptionsPage + + + Window + Окно + + + + &Minimize to the tray instead of the taskbar + &Cворачивать в системный лоток вместо панели задач + + + + Show only a tray icon after minimizing the window + Показывать только иконку в системном лотке после сворачивания окна + + + + M&inimize on close + С&ворачивать при закрытии + + + + 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. + Сворачивать вместо выхода, когда окно приложения закрывается. Если данная опция будет выбрана, приложение закроется только после выбора пункта Выход в меню. + + + + bitcoin-core + + + Bitcoin version + Версия + + + + Usage: + Использование: + + + + Send command to -server or bitcoind + Отправить команду на -server или bitcoind + + + + List commands + Список команд + + + + + Get help for a command + Получить помощь по команде + + + + Options: + Опции: + + + + Specify configuration file (default: bitcoin.conf) + Указать конфигурационный файл (по умолчанию: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Указать pid-файл (по умолчанию: bitcoin.pid) + + + + Generate coins + Генерировать монеты + + + + Don't generate coins + Не генерировать монеты + + + + Specify data directory + Укажите каталог данных + + + + Set database cache size in megabytes (default: 25) + Установить размер кэша базы данных в мегабайтах (по умолчанию: 25) + + + + Set database disk log size in megabytes (default: 100) + Установить размер лога базы данных в мегабайтах (по умолчанию: 100) + + + + Specify connection timeout (in milliseconds) + Укажите таймаут соединения (в миллисекундах) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Принимать входящие подключения на <port> (по умолчанию: 8333 или 18333 в тестовой сети) + + + + Maintain at most <n> connections to peers (default: 125) + Поддерживать не более <n> подключений к узлам (по умолчанию: 125) + + + + Connect only to the specified node + Подключаться только к указанному узлу + + + + Connect to a node to retrieve peer addresses, and disconnect + Подключиться к узлу, чтобы получить список адресов других участников и отключиться + + + + Specify your own public address + Укажите ваш собственный публичный адрес + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + Подключаться только к узлам из сети <net> (IPv4 или IPv6) + + + + Try to discover public IP address (default: 1) + Попробовать обнаружить внешний IP-адрес (по умолчанию: 1) + + + + Bind to given address. Use [host]:port notation for IPv6 + Привязаться (bind) к указанному адресу. Используйте запись вида [хост]:порт для IPv6 + + + + Threshold for disconnecting misbehaving peers (default: 100) + Порог для отключения неправильно ведущих себя узлов (по умолчанию: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Число секунд блокирования неправильно ведущих себя узлов (по умолчанию: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Максимальный размер буфера приёма на соединение, <n>*1000 байт (по умолчанию: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Максимальный размер буфера отправки на соединение, <n>*1000 байт (по умолчанию: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + Отключить базы данных блоков и адресов. Увеличивает время завершения работы (по умолчанию: 0) + + + + Accept command line and JSON-RPC commands + Принимать командную строку и команды JSON-RPC + + + + Run in the background as a daemon and accept commands + Запускаться в фоне как демон и принимать команды + + + + Use the test network + Использовать тестовую сеть + + + + Output extra debugging information + Выводить дополнительную отладочную информацию + + + + Prepend debug output with timestamp + Дописывать отметки времени к отладочному выводу + + + + Send trace/debug info to console instead of debug.log file + Выводить информацию трассировки/отладки на консоль вместо файла debug.log + + + + Send trace/debug info to debugger + Отправлять информацию трассировки/отладки в отладчик + + + + Username for JSON-RPC connections + Имя для подключений JSON-RPC + + + + Password for JSON-RPC connections + Пароль для подключений JSON-RPC + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Ожидать подключения JSON-RPC на <порт> (по умолчанию: 8332) + + + + Allow JSON-RPC connections from specified IP address + Разрешить подключения JSON-RPC с указанного IP + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Посылать команды узлу, запущенному на <ip> (по умолчанию: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Выполнить команду, когда появляется новый блок (%s в команде заменяется на хэш блока) + + + + Upgrade wallet to latest format + Обновить бумажник до последнего формата + + + + Set key pool size to <n> (default: 100) + Установить размер запаса ключей в <n> (по умолчанию: 100) + + + + Rescan the block chain for missing wallet transactions + Перепроверить цепь блоков на предмет отсутствующих в бумажнике транзакций + + + + How many blocks to check at startup (default: 2500, 0 = all) + Сколько блоков проверять при запуске (по умолчанию: 2500, 0 = все) + + + + How thorough the block verification is (0-6, default: 1) + Насколько тщательно проверять блоки (0-6, по умолчанию: 1) + + + + Imports blocks from external blk000?.dat file + Импортировать блоки из внешнего файла blk000?.dat + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +Параметры SSL: (см. Bitcoin Wiki для инструкций по настройке SSL) + + + + Use OpenSSL (https) for JSON-RPC connections + Использовать OpenSSL (https) для подключений JSON-RPC + + + + Server certificate file (default: server.cert) + Файл серверного сертификата (по умолчанию: server.cert) + + + + Server private key (default: server.pem) + Приватный ключ сервера (по умолчанию: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Разрешённые алгоритмы (по умолчанию: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + ВНИМАНИЕ: мало места на диске + + + + This help message + Эта справка + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Невозможно установить блокировку на рабочую директорию %s. Возможно, бумажник уже запущен. + + + + Bitcoin + Биткоин + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + Невозможно привязаться к %s на этом компьютере (bind вернул ошибку %d, %s) + + + + Connect through socks proxy + Подключаться через socks прокси + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + Выберите версию socks прокси (4 или 5, по умолчанию 5) + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + Не использовать прокси для подключения к сети <net> (IPv4 или IPv6) + + + + Allow DNS lookups for -addnode, -seednode and -connect + Разрешить поиск в DNS для -addnode, -seednode и -connect + + + + Pass DNS requests to (SOCKS5) proxy + Выполнять DNS-запросы через (SOCKS5) прокси + + + + Loading addresses... + Загрузка адресов... + + + + Error loading blkindex.dat + Ошибка чтения blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Ошибка загрузки wallet.dat: Бумажник поврежден + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Ошибка загрузки wallet.dat: бумажник требует более новую версию Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Необходимо перезаписать бумажник, перезапустите Bitcoin для завершения операции. + + + + Error loading wallet.dat + Ошибка при загрузке wallet.dat + + + + Invalid -proxy address: '%s' + Неверный адрес -proxy: '%s' + + + + Unknown network specified in -noproxy: '%s' + В параметре -noproxy указана неизвестная сеть: '%s' + + + + Unknown network specified in -onlynet: '%s' + В параметре -onlynet указана неизвестная сеть: '%s' + + + + Unknown -socks proxy version requested: %i + В параметре -socks запрошена неизвестная версия: %i + + + + Cannot resolve -bind address: '%s' + Не удаётся разрешить адрес в параметре -bind: '%s' + + + + Not listening on any port + Никакие порты не прослушиваются + + + + Cannot resolve -externalip address: '%s' + Не удаётся разрешить адрес в параметре -externalip: '%s' + + + + Invalid amount for -paytxfee=<amount>: '%s' + Неверное количество в параметре -paytxfee=<кол-во>: '%s' + + + + Error: could not start node + Ошибка: не удалось запустить узел + + + + Error: Wallet locked, unable to create transaction + Ошибка: бумажник заблокирован, невозможно создать транзакцию + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Ошибка: эта транзакция требует комиссию в размере как минимум %s из-за её объёма, сложности или использования недавно полученных средств + + + + Error: Transaction creation failed + Ошибка: Создание транзакции не удалось + + + + Sending... + Отправка... + + + + 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. + Ошибка: В транзакции отказано. Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию файла wallet.dat, а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой. + + + + Invalid amount + Неверное количество + + + + Insufficient funds + Недостаточно монет + + + + Loading block index... + Загрузка индекса блоков... + + + + Add a node to connect to and attempt to keep the connection open + Добавить узел для подключения и пытаться поддерживать соединение открытым + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + Невозможно привязаться к %s на этом компьютере. Возможно, Bitcoin уже работает. + + + + Find peers using internet relay chat (default: 0) + Найти участников через IRC (по умолчанию: 0) + + + + Accept connections from outside (default: 1) + Принимать входящие подключения (по умолчанию: 1) + + + + Find peers using DNS lookup (default: 1) + Найти участников с помощью запросов DNS (по умолчанию: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Использовать универсальный Plug and Play для проброса порта (по умолчанию: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Использовать универсальный Plug and Play для проброса порта (по умолчанию: 0) + + + + Fee per KB to add to transactions you send + Комиссия на килобайт, добавляемая к вашим транзакциям + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + ВНИМАНИЕ: установлена очень большое значение -paytxfee. Это комиссия, которую вы заплатите при проведении транзакции. + + + + Loading wallet... + Загрузка бумажника... + + + + Cannot downgrade wallet + Не удаётся понизить версию бумажника + + + + Cannot initialize keypool + Не удаётся инициализировать массив ключей + + + + Cannot write default address + Не удаётся записать адрес по умолчанию + + + + Rescanning... + Сканирование... + + + + Done loading + Загрузка завершена + + + + To use the %s option + Чтобы использовать опцию %s + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, вы должны установить опцию rpcpassword в конфигурационном файле: + %s +Рекомендуется использовать следующий случайный пароль: +rpcuser=bitcoinrpc +rpcpassword=%s +(вам не нужно запоминать этот пароль) +Если файл не существует, создайте его и установите право доступа только для чтения только для владельца. + + + + + Error + Ошибка + + + + An error occured while setting up the RPC port %i for listening: %s + Произошла ошибка в процессе открытия RPC-порта %i для прослушивания: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Вы должны установить rpcpassword=<password> в конфигурационном файле: +%s +Если файл не существует, создайте его и установите право доступа только для чтения только для владельца. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + ВНИМАНИЕ: Проверьте дату и время, установленные на Вашем компьютере. Если Ваши часы идут не правильно Bitcoin может наботать не корректно. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts new file mode 100644 index 0000000..bd56dd1 --- /dev/null +++ b/src/qt/locale/bitcoin_sk.ts @@ -0,0 +1,2503 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + O Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> verzia + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + Adresár + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Toto sú Vaše Bitcoin adresy pre prijímanie platieb. Môžete dať každému odosielateľovi inú rôznu adresu a tak udržiavať prehľad o platbách. + + + + Double-click to edit address or label + Dvojklikom editovať adresu alebo popis + + + + Create a new address + Vytvoriť novú adresu + + + + Copy the currently selected address to the system clipboard + Kopírovať práve zvolenú adresu do systémového klipbordu + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Zobraz &QR Kód + + + + Sign a message to prove you own this address + Podpísať správu a dokázať že vlastníte túto adresu + + + + &Sign Message + &Podpísať Správu + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Zmazať práve zvolená adresu zo zoznamu. Len adresy pre odosielanie sa dajú zmazať. + + + + &Delete + &Zmazať + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Exportovať dáta z adresára + + + + Comma separated file (*.csv) + Čiarkou oddelený súbor (*.csv) + + + + Error exporting + Chyba exportu. + + + + Could not write to file %1. + Nedalo sa zapisovať do súboru %1. + + + + AddressTableModel + + + Label + Popis + + + + Address + Adresa + + + + (no label) + (bez popisu) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Zadajte heslo + + + + New passphrase + Nové heslo + + + + Repeat new passphrase + Zopakujte nové heslo + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Zadajte nové heslo k peňaženke.<br/>Prosím použite heslo s dĺžkou aspon <b>10 alebo viac náhodných znakov</b>, alebo <b>8 alebo viac slov</b>. + + + + Encrypt wallet + Zašifrovať peňaženku + + + + This operation needs your wallet passphrase to unlock the wallet. + Táto operácia potrebuje heslo k vašej peňaženke aby ju mohla dešifrovať. + + + + Unlock wallet + Odomknúť peňaženku + + + + This operation needs your wallet passphrase to decrypt the wallet. + Táto operácia potrebuje heslo k vašej peňaženke na dešifrovanie peňaženky. + + + + Decrypt wallet + Dešifrovať peňaženku + + + + Change passphrase + Zmena hesla + + + + Enter the old and new passphrase to the wallet. + Zadajte staré a nové heslo k peňaženke. + + + + Confirm wallet encryption + Potvrďte šifrovanie peňaženky + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + VAROVANIE: Ak zašifrujete peňaženku a stratíte heslo, <b>STRATÍTE VŠETKY VAŠE BITCOINY</b>!⏎ +Ste si istí, že si želáte zašifrovať peňaženku? + + + + + Wallet encrypted + Peňaženka zašifrovaná + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin sa teraz ukončí pre dokončenie procesu šifrovania. Pamätaj že šifrovanie peňaženky Ťa nemôže úplne ochrániť pred kráďežou bitcoinov pomocou škodlivého software. + + + + + Warning: The Caps Lock key is on. + Varovanie: Caps Lock je zapnutý + + + + + + + Wallet encryption failed + Šifrovanie peňaženky zlyhalo + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Šifrovanie peňaženky zlyhalo kôli internej chybe. Vaša peňaženka nebola zašifrovaná. + + + + + The supplied passphrases do not match. + Zadané heslá nesúhlasia. + + + + Wallet unlock failed + Odomykanie peňaženky zlyhalo + + + + + + The passphrase entered for the wallet decryption was incorrect. + Zadané heslo pre dešifrovanie peňaženky bolo nesprávne. + + + + Wallet decryption failed + Zlyhalo šifrovanie peňaženky. + + + + Wallet passphrase was succesfully changed. + Heslo k peňaženke bolo úspešne zmenené. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin peňaženka + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Synchronizácia so sieťou... + + + + &Overview + &Prehľad + + + + Show general overview of wallet + Zobraziť celkový prehľad o peňaženke + + + + &Transactions + &Transakcie + + + + Browse transaction history + Prechádzať históriu transakcií + + + + &Address Book + &Adresár + + + + Edit the list of stored addresses and labels + Editovať zoznam uložených adries a popisov + + + + &Receive coins + &Prijať bitcoins + + + + Show the list of addresses for receiving payments + Zobraziť zoznam adries pre prijímanie platieb. + + + + &Send coins + &Poslať bitcoins + + + + Prove you control an address + Dokázať že kontrolujete adresu + + + + E&xit + U&končiť + + + + Quit application + Ukončiť program + + + + &About %1 + &O %1 + + + + Show information about Bitcoin + Zobraziť informácie o Bitcoin + + + + About &Qt + O &Qt + + + + Show information about Qt + Zobrazit informácie o Qt + + + + &Options... + &Možnosti... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Export... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + Exportovať tento náhľad do súboru + + + + Encrypt or decrypt wallet + Zašifrovať alebo dešifrovať peňaženku + + + + Backup wallet to another location + Zálohovať peňaženku na iné miesto + + + + Change the passphrase used for wallet encryption + Zmeniť heslo použité na šifrovanie peňaženky + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Súbor + + + + &Settings + &Nastavenia + + + + &Help + &Pomoc + + + + Tabs toolbar + Lišta záložiek + + + + Actions toolbar + Lišta aktvivít + + + + + [testnet] + [testovacia sieť] + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + %n aktívne spojenie v Bitcoin sieti%n aktívne spojenia v Bitcoin sieti%n aktívnych spojení v Bitconi sieti + + + + Downloaded %1 blocks of transaction history. + Stiahnutých %1 blokov transakčnej histórie + + + + %n second(s) ago + pred %n sekundoupred %n sekundamipred %n sekundami + + + + %n minute(s) ago + pred %n minútoupred %n minútamipred %n minútami + + + + %n hour(s) ago + pred hodinoupred %n hodinamipred %n hodinami + + + + %n day(s) ago + včerapred %n dňamipred %n dňami + + + + Up to date + Aktualizovaný + + + + Catching up... + Sťahujem... + + + + Last received block was generated %1. + Posledný prijatý blok bol generovaný %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Veľkosť tejto transakcie prekračuje limit. Stále ju však môžete odoslať za poplatok %1 ktorý bude pripísaný uzlu spracúvajúcemu vašu transakciu. Chcete zaplatiť poplatok? + + + + Confirm transaction fee + + + + + Sent transaction + Odoslané transakcie + + + + Incoming transaction + Prijaté transakcie + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Dátum: %1 +Suma: %2 +Typ: %3 +Adresa: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Peňaženka je <b>zašifrovaná</b> a momentálne <b>odomknutá</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Peňaženka je <b>zašifrovaná</b> a momentálne <b>zamknutá</b> + + + + Backup Wallet + Zálohovať peňaženku + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + Nastala chyba pri pokuse uložiť peňaženku na nové miesto. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Displej + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Zvoľ východziu podjednotku ktorá sa bude zobrazovať v programe a pri odosielaní mincí. + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Upraviť adresu + + + + &Label + &Popis + + + + The label associated with this address book entry + Popis priradený k tomuto záznamu v adresári + + + + &Address + &Adresa + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Adresa spojená s týmto záznamom v adresári. Možno upravovať len pre odosielajúce adresy. + + + + New receiving address + Nová adresa pre prijímanie + + + + New sending address + Nová adresa pre odoslanie + + + + Edit receiving address + Upraviť prijímacie adresy + + + + Edit sending address + Upraviť odosielaciu adresu + + + + The entered address "%1" is already in the address book. + Vložená adresa "%1" sa už nachádza v adresári. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Nepodarilo sa odomknúť peňaženku. + + + + New key generation failed. + Generovanie nového kľúča zlyhalo. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Použitie: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + Spustiť minimalizované + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Zaplatiť transakčné &poplatky + + + + Main + Hlavné + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Voliteľný transakčný poplatok za kB ktorý pomôže rýchlemu spracovaniu transakcie. Väčšina transakcií má 1 kB. Poplatok 0.01 je odporúčaný. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Môžete podpísať správy svojou adresou a dokázať, že ju vlastníte. Buďte opatrní a podpíšte len prehlásenia s ktorými plne súhlasíte, nakoľko útoky typu "phishing" Vás môžu lákať k ich podpísaniu. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + Vyberte adresu z adresára + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Vložte adresu z klipbordu + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Sem vložte správu ktorú chcete podpísať + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Kliknite "Podpísať Správu" na získanie podpisu + + + + Sign a message to prove you own this address + Podpíšte správu aby ste dokázali že vlastníte túto adresu + + + + &Sign Message + &Podpísať Správu + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Zadajte Bitcoin adresu (napr. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Chyba podpisovania + + + + %1 is not a valid address. + %1 nieje platná adresa. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Súkromný kľúč pre %1 nieje k dispozícii. + + + + Sign failed + Podpisovanie neúspešné + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Mapovať port pomocou &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Automaticky otvorit port pre Bitcoin na routeri. Toto funguje len ak router podporuje UPnP a je táto podpora aktivovaná. + + + + &Connect through SOCKS4 proxy: + &Pripojiť cez SOCKS4 proxy: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Pripojiť do siete Bitcoin cez SOCKS4 proxy (napr. keď sa pripájate cez Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + IP addresa proxy (napr. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Port proxy (napr. 1234) + + + + OptionsDialog + + + Options + Možnosti + + + + OverviewPage + + + Form + Forma + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Zostatok: + + + + Number of transactions: + Počet transakcií: + + + + Unconfirmed: + Nepotvrdené: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Nedávne transakcie</b> + + + + Your current balance + Váš súčasný zostatok + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Suma transakcií ktoré ešte neboli potvrdené a nezapočítavaju sa do celkového zostatku. + + + + Total number of transactions in wallet + Celkový počet transakcií v peňaženke + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + QR kód + + + + Request Payment + Vyžiadať platbu + + + + Amount: + Suma: + + + + BTC + BTC + + + + Label: + Popis: + + + + Message: + Správa: + + + + &Save As... + &Uložiť ako... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Poslať Bitcoins + + + + Send to multiple recipients at once + Poslať viacerým príjemcom naraz + + + + &Add Recipient + + + + + Remove all transaction fields + Odobrať všetky políčka transakcie + + + + Clear &All + + + + + Balance: + Zostatok: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Potvrďte odoslanie + + + + &Send + &Odoslať + + + + <b>%1</b> to %2 (%3) + <b>%1</b> do %2 (%3) + + + + Confirm send coins + Potvrdiť odoslanie bitcoins + + + + Are you sure you want to send %1? + Ste si istí, že chcete odoslať %1? + + + + and + a + + + + The recepient address is not valid, please recheck. + Adresa príjemcu je neplatná, prosím, overte ju. + + + + The amount to pay must be larger than 0. + Suma na úhradu musí byť väčšia ako 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Forma + + + + A&mount: + Su&ma: + + + + Pay &To: + Zapla&tiť: + + + + + Enter a label for this address to add it to your address book + Vložte popis pre túto adresu aby sa pridala do adresára + + + + &Label: + &Popis: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adresa pre odoslanie platby je (napr. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Zvoľte adresu z adresára + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Vložiť adresu z klipbordu + + + + Alt+P + Alt+P + + + + Remove this recipient + Odstrániť tohto príjemcu + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Zadajte Bitcoin adresu (napr. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Otvorené pre %1 blokov + + + + Open until %1 + Otvorené do %1 + + + + %1/offline? + + + + + %1/unconfirmed + %1/nepotvrdené + + + + %1 confirmations + %1 potvrdení + + + + <b>Status:</b> + <b>Stav:</b> + + + + , has not been successfully broadcast yet + , ešte nebola úspešne odoslaná + + + + , broadcast through %1 node + , odoslaná cez %1 nódu + + + + , broadcast through %1 nodes + , odoslaná cez %1 nód + + + + <b>Date:</b> + <b>Dátum:</b> + + + + <b>Source:</b> Generated<br> + <b>Zdroj:</b> Generovaný<br> + + + + + <b>From:</b> + <b>od:</b> + + + + unknown + neznámy + + + + + + <b>To:</b> + <b>Komu:</b> + + + + (yours, label: + (vaše, popis: + + + + (yours) + (vaše) + + + + + + + <b>Credit:</b> + <b>Kredit:</b> + + + + (%1 matures in %2 more blocks) + (%1 dospeje o %2 blokov) + + + + (not accepted) + (neprijaté) + + + + + + <b>Debit:</b> + <b>Debet:</b> + + + + <b>Transaction fee:</b> + <b>Transakčný poplatok:</b> + + + + <b>Net amount:</b> + <b>Suma netto:</b> + + + + Message: + Správa: + + + + Comment: + Komentár: + + + + Transaction ID: + ID transakcie: + + + + 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. + + + + + TransactionDescDialog + + + Transaction details + Detaily transakcie + + + + This pane shows a detailed description of the transaction + Táto časť obrazovky zobrazuje detailný popis transakcie + + + + TransactionTableModel + + + Date + Dátum + + + + Type + Typ + + + + Address + Adresa + + + + Amount + Hodnota + + + + Open for %n block(s) + + + + + Open until %1 + Otvorené do %1 + + + + Offline (%1 confirmations) + + + + + Unconfirmed (%1 of %2 confirmations) + Nepotvrdené (%1 z %2 potvrdení) + + + + Confirmed (%1 confirmations) + Potvrdené (%1 potvrdení) + + + + Mined balance will be available in %n more blocks + + + + + This block was not received by any other nodes and will probably not be accepted! + Ten blok nebol prijatý žiadnou inou nódou a pravdepodobne nebude akceptovaný! + + + + Generated but not accepted + Vypočítané ale neakceptované + + + + Received with + Prijaté s + + + + Received from + Prijaté od: + + + + Sent to + Odoslané na + + + + Payment to yourself + Platba sebe samému + + + + Mined + Vyfárané + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + Status transakcie. Pohybujte myšou nad týmto poľom a zjaví sa počet potvrdení. + + + + Date and time that the transaction was received. + Dátum a čas prijatia transakcie. + + + + Type of transaction. + Typ transakcie. + + + + Destination address of transaction. + Cieľová adresa transakcie. + + + + Amount removed from or added to balance. + Suma pridaná alebo odobraná k zostatku. + + + + TransactionView + + + + All + Všetko + + + + Today + Dnes + + + + This week + Tento týždeň + + + + This month + Tento mesiac + + + + Last month + Minulý mesiac + + + + This year + Tento rok + + + + Range... + Rozsah... + + + + Received with + Prijaté s + + + + Sent to + Odoslané na + + + + To yourself + Samému sebe + + + + Mined + Vyfárané + + + + Other + Iné + + + + Enter address or label to search + Vložte adresu alebo popis pre vyhľadávanie + + + + Min amount + Min množstvo + + + + Copy address + Kopírovať adresu + + + + Copy label + Kopírovať popis + + + + Copy amount + Kopírovať sumu + + + + Edit label + Editovať popis + + + + Show transaction details + + + + + Export Transaction Data + Exportovať transakčné dáta + + + + Comma separated file (*.csv) + Čiarkou oddelovaný súbor (*.csv) + + + + Confirmed + Potvrdené + + + + Date + Dátum + + + + Type + Typ + + + + Label + Popis + + + + Address + Adresa + + + + Amount + Suma + + + + ID + ID + + + + Error exporting + Chyba exportu + + + + Could not write to file %1. + Nedalo sa zapisovať do súboru %1. + + + + Range: + Rozsah: + + + + to + do + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Kopírovať práve zvolenú adresu do systémového klipbordu + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Odosielanie... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + Zobraziť len ikonu na lište po minimalizovaní okna. + + + + Show only a tray icon after minimizing the window + Zobraziť len ikonu na lište po minimalizovaní okna. + + + + M&inimize on close + + + + + 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. + Minimalizovat namiesto ukončenia aplikácie keď sa okno zavrie. Keď je zvolená táto možnosť, aplikácia sa zavrie len po zvolení Ukončiť v menu. + + + + bitcoin-core + + + Bitcoin version + Bitcoin verzia + + + + Usage: + Použitie: + + + + Send command to -server or bitcoind + Odoslať príkaz -server alebo bitcoind + + + + List commands + Zoznam príkazov + + + + Get help for a command + Dostať pomoc pre príkaz + + + + Options: + Možnosti: + + + + Specify configuration file (default: bitcoin.conf) + Určiť súbor s nastaveniami (predvolené: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Určiť súbor pid (predvolené: bitcoind.pid) + + + + Generate coins + Počítaj bitcoins + + + + Don't generate coins + Nepočítaj bitcoins + + + + Specify data directory + Určiť priečinok s dátami + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Určiť aut spojenia (v milisekundách) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Načúvať spojeniam na <port> (prednastavené: 8333 alebo testovacia sieť: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Udržiavať maximálne <n> spojení (predvolené: 125) + + + + Connect only to the specified node + Pripojiť sa len k určenej nóde + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Prijímať príkazy z príkazového riadku a JSON-RPC + + + + Run in the background as a daemon and accept commands + Bežať na pozadí ako démon a prijímať príkazy + + + + Use the test network + Použiť testovaciu sieť + + + + Output extra debugging information + Produkovať extra ladiace informácie + + + + Prepend debug output with timestamp + Pridať na začiatok ladiaceho výstupu časový údaj + + + + Send trace/debug info to console instead of debug.log file + Odoslať trace/debug informácie na konzolu namiesto debug.info žurnálu + + + + Send trace/debug info to debugger + Odoslať trace/debug informácie do ladiaceho programu + + + + Username for JSON-RPC connections + Užívateľské meno pre JSON-RPC spojenia + + + + Password for JSON-RPC connections + Heslo pre JSON-rPC spojenia + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Počúvať JSON-RPC spojeniam na <port> (predvolené: 8332) + + + + Allow JSON-RPC connections from specified IP address + Povoliť JSON-RPC spojenia z určenej IP adresy. + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Poslať príkaz nóde bežiacej na <ip> (predvolené: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + Nastaviť zásobu adries na <n> (predvolené: 100) + + + + Rescan the block chain for missing wallet transactions + Znovu skenovať reťaz blokov pre chýbajúce transakcie + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + SSL možnosť: (pozrite Bitcoin Wiki pre návod na nastavenie SSL) + + + + Use OpenSSL (https) for JSON-RPC connections + Použiť OpenSSL (https) pre JSON-RPC spojenia + + + + Server certificate file (default: server.cert) + Súbor s certifikátom servra (predvolené: server.cert) + + + + Server private key (default: server.pem) + Súkromný kľúč servra (predvolené: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Prijateľné šifry (predvolené: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + + + + + This help message + Táto pomocná správa + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + + Bitcoin + + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Načítavanie adries... + + + + Error loading blkindex.dat + Chyba načítania blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Chyba načítania wallet.dat: Peňaženka je poškodená + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Chyba načítania wallet.dat: Peňaženka vyžaduje novšiu verziu Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Bolo potrebné prepísať peňaženku: dokončite reštartovaním Bitcoin + + + + Error loading wallet.dat + Chyba načítania wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Chyba: Zlyhalo vytvorenie transakcie + + + + Sending... + Odosielanie... + + + + 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. + Chyba: Transakcia bola odmietnutá. Toto sa môže stať ak niektoré z mincí vo vašej peňaženke boli už utratené, napríklad ak používaš kópiu wallet.dat a mince označené v druhej kópií neboli označené ako utratené v tejto. + + + + Invalid amount + + + + + Insufficient funds + + + + + Loading block index... + Načítavanie zoznamu blokov... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Načítavam peňaženku... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + + + + + Done loading + Dokončené načítavanie + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Varovanie: Skontroluj či je na počítači nastavený správny čas a dátum. Ak sú hodiny nastavené nesprávne, Bitcoin nebude správne pracovať + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts new file mode 100644 index 0000000..89d8f77 --- /dev/null +++ b/src/qt/locale/bitcoin_sr.ts @@ -0,0 +1,2500 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + О Bitcoin-у + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> верзија + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + + AddressBookPage + + + Address Book + Адресар + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Ово су Ваше Bitcoin адресе за примање уплата. Можете да сваком пошиљаоцу дате другачију адресу да би пратили ко је вршио уплате. + + + + Double-click to edit address or label + Кликните два пута да промените адресу и/или етикету + + + + Create a new address + Прави нову адресу + + + + Copy the currently selected address to the system clipboard + Копира изабрану адресу на системски клипборд + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Брише изабрану адресу. Могуће је брисати само адресе са којих се шаље. + + + + &Delete + &Избриши + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Извоз података из адресара + + + + Comma separated file (*.csv) + Зарезом одвојене вредности (*.csv) + + + + Error exporting + Грешка током извоза + + + + Could not write to file %1. + Није могуће писати у фајл %1. + + + + AddressTableModel + + + Label + Етикета + + + + Address + Адреса + + + + (no label) + (без етикете) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Унесите лозинку + + + + New passphrase + Нова лозинка + + + + Repeat new passphrase + Поновите нову лозинку + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Унесите нову лозинку за приступ новчанику.<br/>Молимо Вас да лозинка буде <b>10 или више насумице одабраних знакова</b>, или <b>осам или више речи</b>. + + + + Encrypt wallet + Шифровање новчаника + + + + This operation needs your wallet passphrase to unlock the wallet. + Ова акција захтева лозинку Вашег новчаника да би га откључала. + + + + Unlock wallet + Откључавање новчаника + + + + This operation needs your wallet passphrase to decrypt the wallet. + Ова акција захтева да унесете лозинку да би дешифловала новчаник. + + + + Decrypt wallet + Дешифровање новчаника + + + + Change passphrase + Промена лозинке + + + + Enter the old and new passphrase to the wallet. + Унесите стару и нову лозинку за шифровање новчаника. + + + + Confirm wallet encryption + Одобрите шифровање новчаника + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + УПОЗОРЕЊЕ: Ако се ваш новчаник шифрује а потом изгубите лозинкзу, ви ћете <b>ИЗГУБИТИ СВЕ BITCOIN-Е</b>! +Да ли сте сигурни да желите да се новчаник шифује? + + + + + Wallet encrypted + Новчаник је шифрован + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + + + + Warning: The Caps Lock key is on. + + + + + + + + Wallet encryption failed + Неуспело шифровање новчаника + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Настала је унутрашња грешка током шифровања новчаника. Ваш новчаник није шифрован. + + + + + The supplied passphrases do not match. + Лозинке које сте унели се не подударају. + + + + Wallet unlock failed + Неуспело откључавање новчаника + + + + + + The passphrase entered for the wallet decryption was incorrect. + Лозинка коју сте унели за откључавање новчаника је нетачна. + + + + Wallet decryption failed + Неуспело дешифровање новчаника + + + + Wallet passphrase was succesfully changed. + Лозинка за приступ новчанику је успешно промењена. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin новчаник + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Синхронизација са мрежом у току... + + + + &Overview + &Општи преглед + + + + Show general overview of wallet + Погледајте општи преглед новчаника + + + + &Transactions + &Трансакције + + + + Browse transaction history + Претражите историјат трансакција + + + + &Address Book + &Адресар + + + + Edit the list of stored addresses and labels + Уредите запамћене адресе и њихове етикете + + + + &Receive coins + П&римање новца + + + + Show the list of addresses for receiving payments + Прегледајте листу адреса на којима прихватате уплате + + + + &Send coins + &Слање новца + + + + Prove you control an address + + + + + E&xit + + + + + Quit application + Напустите програм + + + + &About %1 + + + + + Show information about Bitcoin + Прегледајте информације о Bitcoin-у + + + + About &Qt + + + + + Show information about Qt + + + + + &Options... + П&оставке... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Извоз... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + + + + + Encrypt or decrypt wallet + Шифровање и дешифровање новчаника + + + + Backup wallet to another location + + + + + Change the passphrase used for wallet encryption + Мењање лозинке којом се шифрује новчаник + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Фајл + + + + &Settings + &Подешавања + + + + &Help + П&омоћ + + + + Tabs toolbar + Трака са картицама + + + + Actions toolbar + Трака са алаткама + + + + + [testnet] + [testnet] + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + %n активна веза са Bitcoin мрежом%n активне везе са Bitcoin мрежом%n активних веза са Bitcoin мрежом + + + + Downloaded %1 blocks of transaction history. + Преузето је %1 блокова историјата трансакција. + + + + %n second(s) ago + пре %n секундпре %n секундепре %n секунди + + + + %n minute(s) ago + пре %n минутпре %n минутапре %n минута + + + + %n hour(s) ago + пре %n сатпре %n сатапре %n сати + + + + %n day(s) ago + пре %n данпре %n данапре %n дана + + + + Up to date + Ажурно + + + + Catching up... + Ажурирање у току... + + + + Last received block was generated %1. + Последњи примљени блок је направљен %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Ова трансакција је превелика. И даље је можете послати уз накнаду од %1, која ће отићи чвору који прерађује трансакцију и помаже издржавању целе мреже. Да ли желите да дате напојницу? + + + + Confirm transaction fee + + + + + Sent transaction + Послана трансакција + + + + Incoming transaction + Придошла трансакција + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Новчаник јс <b>шифрован</b> и тренутно <b>откључан</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Новчаник јс <b>шифрован</b> и тренутно <b>закључан</b> + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to the new location. + + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + + + + + &Label + + + + + The label associated with this address book entry + + + + + &Address + + + + + The address associated with this address book entry. This can only be modified for sending addresses. + + + + + New receiving address + + + + + New sending address + + + + + Edit receiving address + + + + + Edit sending address + + + + + The entered address "%1" is already in the address book. + + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Немогуће откључати новчаник. + + + + New key generation failed. + + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + + + + + Main + + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Enter the message you want to sign here + + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + + + + + Sign a message to prove you own this address + + + + + &Sign Message + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + + Error signing + + + + + %1 is not a valid address. + + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + + + + + Sign failed + + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + + + &Connect through SOCKS4 proxy: + + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + + + + + Port of the proxy (e.g. 1234) + + + + + OptionsDialog + + + Options + + + + + OverviewPage + + + Form + + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + + + + + Number of transactions: + + + + + Unconfirmed: + + + + + Wallet + + + + + <b>Recent transactions</b> + + + + + Your current balance + + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + + + + + Total number of transactions in wallet + Укупан број трансакција у новчанику + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + + + + + Request Payment + + + + + Amount: + + + + + BTC + + + + + Label: + + + + + Message: + + + + + &Save As... + + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + + + + + Send to multiple recipients at once + + + + + &Add Recipient + + + + + Remove all transaction fields + + + + + Clear &All + + + + + Balance: + + + + + 123.456 BTC + + + + + Confirm the send action + + + + + &Send + &Пошаљи + + + + <b>%1</b> to %2 (%3) + + + + + Confirm send coins + + + + + Are you sure you want to send %1? + Да ли сте сигурни да желите да пошаљете %1? + + + + and + + + + + The recepient address is not valid, please recheck. + + + + + The amount to pay must be larger than 0. + + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + + + + + A&mount: + + + + + Pay &To: + + + + + + Enter a label for this address to add it to your address book + + + + + &Label: + + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose address from address book + + + + + Alt+A + + + + + Paste address from clipboard + + + + + Alt+P + + + + + Remove this recipient + + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + TransactionDesc + + + Open for %1 blocks + + + + + Open until %1 + + + + + %1/offline? + + + + + %1/unconfirmed + + + + + %1 confirmations + + + + + <b>Status:</b> + + + + + , has not been successfully broadcast yet + + + + + , broadcast through %1 node + + + + + , broadcast through %1 nodes + + + + + <b>Date:</b> + + + + + <b>Source:</b> Generated<br> + + + + + + <b>From:</b> + + + + + unknown + + + + + + + <b>To:</b> + + + + + (yours, label: + + + + + (yours) + + + + + + + + <b>Credit:</b> + + + + + (%1 matures in %2 more blocks) + + + + + (not accepted) + + + + + + + <b>Debit:</b> + + + + + <b>Transaction fee:</b> + + + + + <b>Net amount:</b> + + + + + Message: + + + + + Comment: + + + + + Transaction ID: + + + + + 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. + + + + + TransactionDescDialog + + + Transaction details + + + + + This pane shows a detailed description of the transaction + + + + + TransactionTableModel + + + Date + + + + + Type + + + + + Address + Адреса + + + + Amount + + + + + Open for %n block(s) + + + + + Open until %1 + + + + + Offline (%1 confirmations) + + + + + Unconfirmed (%1 of %2 confirmations) + + + + + Confirmed (%1 confirmations) + + + + + Mined balance will be available in %n more blocks + + + + + This block was not received by any other nodes and will probably not be accepted! + + + + + Generated but not accepted + + + + + Received with + + + + + Received from + + + + + Sent to + + + + + Payment to yourself + + + + + Mined + + + + + (n/a) + + + + + Transaction status. Hover over this field to show number of confirmations. + + + + + Date and time that the transaction was received. + + + + + Type of transaction. + + + + + Destination address of transaction. + + + + + Amount removed from or added to balance. + + + + + TransactionView + + + + All + + + + + Today + + + + + This week + + + + + This month + + + + + Last month + + + + + This year + + + + + Range... + + + + + Received with + + + + + Sent to + + + + + To yourself + + + + + Mined + + + + + Other + + + + + Enter address or label to search + + + + + Min amount + + + + + Copy address + + + + + Copy label + + + + + Copy amount + + + + + Edit label + + + + + Show transaction details + + + + + Export Transaction Data + + + + + Comma separated file (*.csv) + Зарезом одвојене вредности (*.csv) + + + + Confirmed + + + + + Date + + + + + Type + + + + + Label + Етикета + + + + Address + Адреса + + + + Amount + + + + + ID + + + + + Error exporting + Грешка током извоза + + + + Could not write to file %1. + Није могуће писати у фајл %1. + + + + Range: + + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Копира изабрану адресу на системски клипборд + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Слање у току... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + + + + + Show only a tray icon after minimizing the window + + + + + M&inimize on close + + + + + 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. + + + + + bitcoin-core + + + Bitcoin version + + + + + Usage: + + + + + Send command to -server or bitcoind + + + + + List commands + + + + + Get help for a command + + + + + Options: + + + + + Specify configuration file (default: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + + + + + Generate coins + + + + + Don't generate coins + + + + + Specify data directory + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + + + + + Maintain at most <n> connections to peers (default: 125) + + + + + Connect only to the specified node + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + + + + + Run in the background as a daemon and accept commands + + + + + Use the test network + + + + + Output extra debugging information + + + + + Prepend debug output with timestamp + + + + + Send trace/debug info to console instead of debug.log file + + + + + Send trace/debug info to debugger + + + + + Username for JSON-RPC connections + + + + + Password for JSON-RPC connections + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + + + + + Allow JSON-RPC connections from specified IP address + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + + + + + Rescan the block chain for missing wallet transactions + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + + + + + Use OpenSSL (https) for JSON-RPC connections + + + + + Server certificate file (default: server.cert) + + + + + Server private key (default: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + + + + + Bitcoin + + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + + + + + Error loading blkindex.dat + + + + + Error loading wallet.dat: Wallet corrupted + + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + + + + + Wallet needed to be rewritten: restart Bitcoin to complete + + + + + Error loading wallet.dat + + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + + + + + Sending... + Слање у току... + + + + 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. + + + + + Invalid amount + + + + + Insufficient funds + + + + + Loading block index... + + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Новчаник се учитава... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + + + + + Done loading + + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts new file mode 100644 index 0000000..d41390f --- /dev/null +++ b/src/qt/locale/bitcoin_sv.ts @@ -0,0 +1,2520 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Om Bitcoin + + + + <b>Bitcoin</b> version + <b>Bitcoin</b>-version + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Copyright © 2009-2012 Bitcoin-utvecklarna + +Detta är experimentell mjukvara. + +Distribuerad under mjukvarulicensen MIT/X11, se den medföljande filen license.txt eller http://www.opensource.org/licenses/mit-license.php. + +Denna produkten innehåller mjukvara utvecklad av OpenSSL Project för användning i OpenSSL Toolkit (http://www.openssl.org/) och kryptografisk mjukvara utvecklad av Eric Young (eay@cryptsoft.com) samt UPnP-mjukvara skriven av Thomas Bernard. + + + + AddressBookPage + + + Address Book + Adressbok + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Detta är dina Bitcoin-adresser för att ta emot betalningar. Du kan ge varje avsändare en egen adress så att du kan hålla reda på vem som betalar dig. + + + + Double-click to edit address or label + Dubbel-klicka för att ändra adressen eller etiketten + + + + Create a new address + Skapa ny adress + + + + Copy the currently selected address to the system clipboard + Kopiera den markerade adressen till systemets Urklipp + + + + &New Address + &Ny adress + + + + &Copy Address + &Kopiera adress + + + + Show &QR Code + Visa &QR-kod + + + + Sign a message to prove you own this address + Signera ett meddelande för att bevisa att du äger denna adress + + + + &Sign Message + &Signera meddelande + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Ta bort den valda adressen från listan. Bara avsändar-adresser kan tas bort. + + + + &Delete + &Ta bort + + + + Copy &Label + Kopiera &etikett + + + + &Edit + &Editera + + + + Export Address Book Data + Exportera Adressbok + + + + Comma separated file (*.csv) + Kommaseparerad fil (*.csv) + + + + Error exporting + Fel vid export + + + + Could not write to file %1. + Kunde inte skriva till filen %1. + + + + AddressTableModel + + + Label + Etikett + + + + Address + Adress + + + + (no label) + (Ingen etikett) + + + + AskPassphraseDialog + + + Passphrase Dialog + Lösenords Dialog + + + + Enter passphrase + Ange lösenord + + + + New passphrase + Nytt lösenord + + + + Repeat new passphrase + Upprepa nytt lösenord + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Ange plånbokens nya lösenord. <br/> Använd ett lösenord på <b>10 eller fler slumpmässiga tecken,</b> eller <b>åtta eller fler ord.</b> + + + + Encrypt wallet + Kryptera plånbok + + + + This operation needs your wallet passphrase to unlock the wallet. + Denna operation behöver din plånboks lösenord för att låsa upp plånboken. + + + + Unlock wallet + Lås upp plånbok + + + + This operation needs your wallet passphrase to decrypt the wallet. + Denna operation behöver din plånboks lösenord för att dekryptera plånboken. + + + + Decrypt wallet + Dekryptera plånbok + + + + Change passphrase + Ändra lösenord + + + + Enter the old and new passphrase to the wallet. + Ange plånbokens gamla och nya lösenord. + + + + Confirm wallet encryption + Bekräfta kryptering av plånbok + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + VARNING: Om du krypterar din plånbok och glömmer ditt lösenord, kommer du att <b>FÖRLORA ALLA DINA TILLGÅNGAR</b>! +Är du säker på att du vill kryptera din plånbok? + + + + + Wallet encrypted + Plånboken är krypterad + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Programmet kommer nu att stänga ner för att färdigställa krypteringen. Tänk på att en krypterad plånbok inte skyddar mot stöld om din dator är infekterad med en keylogger. + + + + + Warning: The Caps Lock key is on. + Varning: Caps Lock är påslaget + + + + + + + Wallet encryption failed + Kryptering av plånbok misslyckades + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Kryptering av plånbok misslyckades på grund av ett internt fel. Din plånbok blev inte krypterad. + + + + + The supplied passphrases do not match. + De angivna lösenorden överensstämmer inte. + + + + Wallet unlock failed + Upplåsning av plånbok misslyckades + + + + + + The passphrase entered for the wallet decryption was incorrect. + Lösenordet för dekryptering av plånbok var felaktig. + + + + Wallet decryption failed + Dekryptering av plånbok misslyckades + + + + Wallet passphrase was succesfully changed. + Plånbokens lösenord har ändrats. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin-plånbok + + + + Sign &message... + Signera &meddelande... + + + + Show/Hide &Bitcoin + Visa/Göm &Bitcoin + + + + Synchronizing with network... + Synkroniserar med nätverk... + + + + &Overview + &Översikt + + + + Show general overview of wallet + Visa översiktsvy av plånbok + + + + &Transactions + &Transaktioner + + + + Browse transaction history + Bläddra i transaktionshistorik + + + + &Address Book + &Adressbok + + + + Edit the list of stored addresses and labels + Redigera listan med lagrade adresser och etiketter + + + + &Receive coins + &Ta emot bitcoins + + + + Show the list of addresses for receiving payments + Visa listan med adresser för att ta emot betalningar + + + + &Send coins + &Skicka bitcoins + + + + Prove you control an address + Bevisa att du kontrollerar en adress + + + + E&xit + &Avsluta + + + + Quit application + Avsluta programmet + + + + &About %1 + &Om %1 + + + + Show information about Bitcoin + Visa information om Bitcoin + + + + About &Qt + Om &Qt + + + + Show information about Qt + Visa information om Qt + + + + &Options... + &Alternativ... + + + + &Encrypt Wallet... + &Kryptera plånbok... + + + + &Backup Wallet... + &Säkerhetskopiera plånbok... + + + + &Change Passphrase... + &Byt Lösenord... + + + + ~%n block(s) remaining + ~%n block återstår~%n block återstår + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Laddat ner %1 av %2 block från transaktionshistoriken (%3% klart). + + + + &Export... + &Exportera... + + + + Send coins to a Bitcoin address + Skicka mynt till en Bitcoin-adress + + + + Modify configuration options for Bitcoin + Ändra konfigurationsalternativ för Bitcoin + + + + Show or hide the Bitcoin window + Visa eller göm Bitcoin-fönstret + + + + Export the data in the current tab to a file + Exportera informationen i den nuvarande fliken till en fil + + + + Encrypt or decrypt wallet + Kryptera eller dekryptera plånbok + + + + Backup wallet to another location + Säkerhetskopiera plånboken till en annan plats + + + + Change the passphrase used for wallet encryption + Byt lösenord för kryptering av plånbok + + + + &Debug window + &Debug fönster + + + + Open debugging and diagnostic console + Öppna debug- och diagnostikkonsolen + + + + &Verify message... + &Verifiera meddelande... + + + + Verify a message signature + Verifiera meddelandets signatur + + + + &File + &Arkiv + + + + &Settings + &Inställningar + + + + &Help + &Hjälp + + + + Tabs toolbar + Verktygsfält för Tabbar + + + + Actions toolbar + Verktygsfältet för Handlingar + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Bitcoin-klient + + + + %n active connection(s) to Bitcoin network + %n aktiv anslutning till Bitcoin-nätverket%n aktiva anslutningar till Bitcoin-nätverket + + + + Downloaded %1 blocks of transaction history. + Laddat ner %1 block från transaktionshistoriken. + + + + %n second(s) ago + %n sekund sedan%n sekunder sedan + + + + %n minute(s) ago + %n minut sedan%n minuter sedan + + + + %n hour(s) ago + %n timme sedan%n timmar sedan + + + + %n day(s) ago + %n dag sedan%n dagar sedan + + + + Up to date + Uppdaterad + + + + Catching up... + Hämtar senaste... + + + + Last received block was generated %1. + Senast mottagna block genererades %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Transaktionen överskrider storleksgränsen. Du kan dock fortfarande skicka den mot en kostnad av %1. Denna avgift går till noderna som behandlar din transaktion och bidrar till nätverket. Vill du betala denna avgift? + + + + Confirm transaction fee + Bekräfta överföringsavgift + + + + Sent transaction + Transaktion skickad + + + + Incoming transaction + Inkommande transaktion + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Datum: %1 +Belopp: %2 +Typ: %3 +Adress: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Denna plånbok är <b>krypterad</b> och för närvarande <b>olåst</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Denna plånbok är <b>krypterad</b> och för närvarande <b>låst</b> + + + + Backup Wallet + Säkerhetskopiera Plånbok + + + + Wallet Data (*.dat) + Plånboks-data (*.dat) + + + + Backup Failed + Säkerhetskopiering misslyckades + + + + There was an error trying to save the wallet data to the new location. + Det inträffade ett fel när plånboken skulle sparas till den nya platsen. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + Ett allvarligt fel har uppstått. Bitcoin kan inte längre köras säkert och kommer att avslutas. + + + + ClientModel + + + Network Alert + Nätverkslarm + + + + DisplayOptionsPage + + + Display + Visa + + + + default + standard + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + Användargränssnittets språk kan ställas in här. Denna inställning träder i kraft efter en omstart av Bitcoin. + + + + User Interface &Language: + Användargränssnittets &Språk: + + + + &Unit to show amounts in: + &Måttenhet att visa belopp i: + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Välj en måttenhet att visa när du skickar mynt + + + + &Display addresses in transaction list + &Visa adresser i transaktionslistan + + + + Whether to show Bitcoin addresses in the transaction list + Anger om Bitcoin-adresser skall visas i transaktionslistan + + + + Warning + Varning + + + + This setting will take effect after restarting Bitcoin. + Denna inställning träder i kraft efter en omstart av Bitcoin. + + + + EditAddressDialog + + + Edit Address + Redigera Adress + + + + &Label + &Etikett + + + + The label associated with this address book entry + Den etikett som är associerad med detta adressboksinlägg + + + + &Address + &Adress + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Adressen som är associerad med detta adressboksinlägg. Detta kan enbart ändras för sändande adresser. + + + + New receiving address + Ny mottagaradress + + + + New sending address + Ny avsändaradress + + + + Edit receiving address + Redigera mottagaradress + + + + Edit sending address + Redigera avsändaradress + + + + The entered address "%1" is already in the address book. + Den angivna adressen "%1" finns redan i adressboken. + + + + The entered address "%1" is not a valid Bitcoin address. + Den angivna adressen "%1" är inte en giltig Bitcoin-adress. + + + + Could not unlock wallet. + Plånboken kunde inte låsas upp. + + + + New key generation failed. + Misslyckades med generering av ny nyckel. + + + + HelpMessageBox + + + + Bitcoin-Qt + Bitcoin-Qt + + + + version + version + + + + Usage: + Användning: + + + + options + alternativ + + + + UI options + UI alternativ + + + + Set language, for example "de_DE" (default: system locale) + Ändra språk, till exempel "de_DE" (standard: systemets språk) + + + + Start minimized + Starta som minimerad + + + + Show splash screen on startup (default: 1) + Visa startbilden vid uppstart (standard: 1) + + + + MainOptionsPage + + + 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. + Frigör block- och adressdatabaser vid nedstängning. Detta innebär att de kan flyttas till en annan data katalog, men det saktar ner avstängningen. Plånboken är alltid frigjord. + + + + Pay transaction &fee + Betala överförings&avgift + + + + Main + Allmänt + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Valfri transaktionsavgift per kB som ser till att dina transaktioner behandlas snabbt. De flesta transaktioner är 1 kB. Avgift 0.01 rekommenderas. + + + + &Start Bitcoin on system login + &Starta Bitcoin vid systemstart + + + + Automatically start Bitcoin after logging in to the system + Starta Bitcoin automatiskt efter inloggning + + + + &Detach databases at shutdown + &Frigör databaser vid nedstängning + + + + MessagePage + + + Sign Message + Signera meddelande + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Du kan signera meddelanden med dina adresser för att bevisa att du äger dem. Var försiktig med vad du signerar eftersom phising-attacker kan försöka få dig att skriva över din identitet till någon annan. Signera bara väldetaljerade påståenden du kan gå i god för. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adressen att signera meddelandet med (t.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Välj adress från adressboken + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Klistra in adress från Urklipp + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Skriv in meddelandet du vill signera här + + + + Copy the current signature to the system clipboard + Kopiera signaturen till systemets Urklipp + + + + &Copy Signature + &Kopiera signatur + + + + Reset all sign message fields + Rensa alla fält + + + + Clear &All + Rensa &alla + + + + Click "Sign Message" to get signature + Klicka "Signera Meddelande" för att få en signatur + + + + Sign a message to prove you own this address + Signera ett meddelande för att bevisa att du äger denna adress + + + + &Sign Message + &Signera meddelande + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Ange en Bitcoin-adress (t.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Fel vid signering + + + + %1 is not a valid address. + %1 är ingen giltig adress. + + + + %1 does not refer to a key. + %1 refererar inte till en nyckel. + + + + Private key for %1 is not available. + Privata nyckeln för %1 är inte tillgänglig. + + + + Sign failed + Signering misslyckades + + + + NetworkOptionsPage + + + Network + Nätverk + + + + Map port using &UPnP + Tilldela port med hjälp av &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Öppna automatiskt Bitcoin-klientens port på routern. Detta fungerar endast om din router har UPnP aktiverat. + + + + &Connect through SOCKS4 proxy: + &Anslut genom SOCKS4-proxy: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Anslut till Bitcoin-nätverket genom en SOCKS4-proxy (t.ex. när du ansluter genom Tor) + + + + Proxy &IP: + Proxy-&IP: + + + + &Port: + &Port: + + + + IP address of the proxy (e.g. 127.0.0.1) + Proxyns IP-adress (t.ex. 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Proxyns port (t.ex. 1234) + + + + OptionsDialog + + + Options + Alternativ + + + + OverviewPage + + + Form + Formulär + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + Den visade informationen kan vara inaktuell. Plånboken synkroniseras automatiskt med Bitcoin-nätverket efter att anslutningen är upprättad, men denna process har inte slutförts ännu. + + + + Balance: + Saldo: + + + + Number of transactions: + Antal transaktioner: + + + + Unconfirmed: + Obekräftade: + + + + Wallet + Plånbok + + + + <b>Recent transactions</b> + <b>Nyligen genomförda transaktioner</b> + + + + Your current balance + Ditt nuvarande saldo + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Totalt antal transaktioner som ännu inte bekräftats, och som ännu inte räknas med i aktuellt saldo + + + + Total number of transactions in wallet + Totalt antal transaktioner i plånboken + + + + + out of sync + osynkroniserad + + + + QRCodeDialog + + + QR Code Dialog + QR-kod dialogruta + + + + QR Code + QR-kod + + + + Request Payment + Begär Betalning + + + + Amount: + Belopp: + + + + BTC + BTC + + + + Label: + Etikett: + + + + Message: + Meddelande: + + + + &Save As... + &Spara som... + + + + Error encoding URI into QR Code. + Fel vid skapande av QR-kod från URI. + + + + Resulting URI too long, try to reduce the text for label / message. + URI:n är för lång, försöka minska texten för etikett / meddelande. + + + + Save QR Code + Spara QR-kod + + + + PNG Images (*.png) + PNG-bilder (*.png) + + + + RPCConsole + + + Bitcoin debug window + Bitcoin debug fönster + + + + Client name + Klientnamn + + + + + + + + + + + + N/A + ej tillgänglig + + + + Client version + Klient-version + + + + &Information + &Information + + + + Client + Klient + + + + Startup time + Uppstartstid + + + + Network + Nätverk + + + + Number of connections + Antalet anslutningar + + + + On testnet + På testnet + + + + Block chain + Blockkedja + + + + Current number of blocks + Aktuellt antal block + + + + Estimated total blocks + Beräknade totala block + + + + Last block time + Sista blocktid + + + + Debug logfile + Debugloggfil + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + Öppna Bitcoin debug-loggfilen som finns i datakatalogen. Detta kan ta några sekunder för stora loggfiler. + + + + &Open + &Öppna + + + + &Console + &Konsol + + + + Build date + Kompileringsdatum + + + + Clear console + Rensa konsollen + + + + Welcome to the Bitcoin RPC console. + Välkommen till Bitcoin RPC-konsollen. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Använd upp- och ner-pilarna för att navigera i historiken, och <b>Ctrl-L</b> för att rensa skärmen. + + + + Type <b>help</b> for an overview of available commands. + Skriv <b>help</b> för en översikt av alla kommandon. + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Skicka pengar + + + + Send to multiple recipients at once + Skicka till flera mottagare samtidigt + + + + &Add Recipient + &Lägg till mottagare + + + + Remove all transaction fields + Ta bort alla transaktions-fält + + + + Clear &All + Rensa &alla + + + + Balance: + Balans: + + + + 123.456 BTC + 123,456 BTC + + + + Confirm the send action + Bekräfta sändordern + + + + &Send + &Skicka + + + + <b>%1</b> to %2 (%3) + <b>%1</b> till %2 (%3) + + + + Confirm send coins + Bekräfta skickade mynt + + + + Are you sure you want to send %1? + Är du säker på att du vill skicka %1? + + + + and + och + + + + The recepient address is not valid, please recheck. + Mottagarens adress är inte giltig, vänligen kontrollera igen. + + + + The amount to pay must be larger than 0. + Det betalade beloppet måste vara större än 0. + + + + The amount exceeds your balance. + Värdet överstiger ditt saldo. + + + + The total exceeds your balance when the %1 transaction fee is included. + Totalvärdet överstiger ditt saldo när transaktionsavgiften %1 är pålagd. + + + + Duplicate address found, can only send to each address once per send operation. + Dubblett av adress funnen, kan bara skicka till varje adress en gång per sändning. + + + + Error: Transaction creation failed. + Fel: Transaktionen gick inte att skapa. + + + + 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. + Fel: Transaktionen avslogs. Detta kan hända om några av mynten i plånboken redan spenderats, t.ex om du använt en kopia av wallet.dat och mynt spenderades i kopian men inte markerats som spenderas här. + + + + SendCoinsEntry + + + Form + Formulär + + + + A&mount: + &Belopp: + + + + Pay &To: + Betala &Till: + + + + + Enter a label for this address to add it to your address book + Ange ett namn för den här adressen och lägg till den i din adressbok + + + + &Label: + &Etikett: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Adressen som betalningen skall skickas till (t.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Välj adress från adresslistan + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Klistra in adress från Urklipp + + + + Alt+P + Alt+P + + + + Remove this recipient + Ta bort denna mottagare + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Ange en Bitcoin-adress (t.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Öppen för %1 block + + + + Open until %1 + Öppet till %1 + + + + %1/offline? + %1/nerkopplad? + + + + %1/unconfirmed + %1/obekräftade + + + + %1 confirmations + %1 bekräftelser + + + + <b>Status:</b> + <b>Status:</b> + + + + , has not been successfully broadcast yet + , har inte lyckats skickas ännu + + + + , broadcast through %1 node + , sänd genom %1 nod + + + + , broadcast through %1 nodes + , sänd genom %1 noder + + + + <b>Date:</b> + <b>Datum:</b> + + + + <b>Source:</b> Generated<br> + <b>Källa:</b> Genererade<br> + + + + + <b>From:</b> + <b>Från:</b> + + + + unknown + okänd + + + + + + <b>To:</b> + <b>Till:</b> + + + + (yours, label: + (din, etikett: + + + + (yours) + (dina) + + + + + + + <b>Credit:</b> + <b>Kredit:</b> + + + + (%1 matures in %2 more blocks) + (%1 mognar om %2 block) + + + + (not accepted) + (inte accepterad) + + + + + + <b>Debit:</b> + <b>Debet:</b> + + + + <b>Transaction fee:</b> + <b>Transaktionsavgift:</b> + + + + <b>Net amount:</b> + <b>Nettobelopp:</b> + + + + Message: + Meddelande: + + + + Comment: + Kommentar: + + + + Transaction ID: + Transaktions-ID: + + + + 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. + Genererade mynt måste vänta 120 block innan de kan användas. När du skapade detta block sändes det till nätverket för att läggas till i blockkedjan. Om blocket inte kommer in i kedjan kommer det att ändras till "accepteras inte" och kommer ej att gå att spendera. Detta kan ibland hända om en annan nod genererar ett block nästan samtidigt som dig. + + + + TransactionDescDialog + + + Transaction details + Transaktionsdetaljer + + + + This pane shows a detailed description of the transaction + Den här panelen visar en detaljerad beskrivning av transaktionen + + + + TransactionTableModel + + + Date + Datum + + + + Type + Typ + + + + Address + Adress + + + + Amount + Mängd + + + + Open for %n block(s) + Öppen i %n blockÖppen i %n block + + + + Open until %1 + Öppet till %1 + + + + Offline (%1 confirmations) + Offline (%1 bekräftelser) + + + + Unconfirmed (%1 of %2 confirmations) + Obekräftad (%1 av %2 bekräftelser) + + + + Confirmed (%1 confirmations) + Bekräftad (%1 bekräftelser) + + + + Mined balance will be available in %n more blocks + Genererat belopp kommer bli tillgängligt om %n blockGenererat belopp kommer bli tillgängligt om %n block + + + + This block was not received by any other nodes and will probably not be accepted! + Det här blocket togs inte emot av några andra noder och kommer antagligen inte att bli godkänt. + + + + Generated but not accepted + Genererad men inte accepterad + + + + Received with + Mottagen med + + + + Received from + Mottaget från + + + + Sent to + Skickad till + + + + Payment to yourself + Betalning till dig själv + + + + Mined + Genererade + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + Transaktionsstatus. Håll muspekaren över för att se antal bekräftelser. + + + + Date and time that the transaction was received. + Tidpunkt då transaktionen mottogs. + + + + Type of transaction. + Transaktionstyp. + + + + Destination address of transaction. + Transaktionens destinationsadress. + + + + Amount removed from or added to balance. + Belopp draget eller tillagt till balans. + + + + TransactionView + + + + All + Alla + + + + Today + Idag + + + + This week + Denna vecka + + + + This month + Denna månad + + + + Last month + Föregående månad + + + + This year + Det här året + + + + Range... + Period... + + + + Received with + Mottagen med + + + + Sent to + Skickad till + + + + To yourself + Till dig själv + + + + Mined + Genererade + + + + Other + Övriga + + + + Enter address or label to search + Sök efter adress eller etikett + + + + Min amount + Minsta mängd + + + + Copy address + Kopiera adress + + + + Copy label + Kopiera etikett + + + + Copy amount + Kopiera belopp + + + + Edit label + Ändra etikett + + + + Show transaction details + Visa transaktionsdetaljer + + + + Export Transaction Data + Exportera Transaktionsdata + + + + Comma separated file (*.csv) + Kommaseparerad fil (*. csv) + + + + Confirmed + Bekräftad + + + + Date + Datum + + + + Type + Typ + + + + Label + Etikett + + + + Address + Adress + + + + Amount + Mängd + + + + ID + ID + + + + Error exporting + Fel vid export + + + + Could not write to file %1. + Kunde inte skriva till filen %1. + + + + Range: + Intervall: + + + + to + till + + + + VerifyMessageDialog + + + Verify Signed Message + Verifiera Signerat Meddelande + + + + 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. + Skriv meddelandet och signaturen nedan (var noga med att kopiera rätt nyradstecken, mellanslag, tabbar och andra osynliga tecken) för att erhålla Bitcoin-adressen som användes för att signera meddelandet. + + + + Verify a message and obtain the Bitcoin address used to sign the message + Verifiera ett meddelande och erhåll Bitcoin-adressen som användes för att signera meddelandet + + + + &Verify Message + &Verifiera Meddelande + + + + Copy the currently selected address to the system clipboard + Kopiera den markerade adressen till systemets Urklipp + + + + &Copy Address + &Kopiera adress + + + + Reset all verify message fields + Rensa alla fält + + + + Clear &All + Rensa &alla + + + + Enter Bitcoin signature + Ange Bitcoin-signatur + + + + Click "Verify Message" to obtain address + Klicka på "Verifiera meddelande" för att få adressen + + + + + Invalid Signature + Ogiltig Signatur + + + + The signature could not be decoded. Please check the signature and try again. + Signaturen kunde inte avkodas. Kontrollera signaturen och försök igen. + + + + The signature did not match the message digest. Please check the signature and try again. + Signaturen matchade inte meddelandesammanfattningen. Kontrollera signaturen och försök igen. + + + + Address not found in address book. + Adressen hittas ej i adressboken. + + + + Address found in address book: %1 + Adressen hittades i adressboken: %1 + + + + WalletModel + + + Sending... + Skickar... + + + + WindowOptionsPage + + + Window + Fönster + + + + &Minimize to the tray instead of the taskbar + &Minimera till systemfältet istället för aktivitetsfältet + + + + Show only a tray icon after minimizing the window + Visa endast en systemfältsikon vid minimering + + + + M&inimize on close + M&inimera vid stängning + + + + 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. + Minimera applikationen istället för att stänga ner den när fönstret stängs. Detta innebär att programmet fotrsätter att köras tills du väljer Avsluta i menyn. + + + + bitcoin-core + + + Bitcoin version + Bitcoin version + + + + Usage: + Användning: + + + + Send command to -server or bitcoind + Skicka kommando till -server eller bitcoind + + + + List commands + Lista kommandon + + + + Get help for a command + Få hjälp med ett kommando + + + + Options: + Inställningar: + + + + Specify configuration file (default: bitcoin.conf) + Ange konfigurationsfil (standard: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Ange pid fil (standard: bitcoind.pid) + + + + Generate coins + Generera mynt + + + + Don't generate coins + Generera inte mynt + + + + Specify data directory + Ange katalog för data + + + + Set database cache size in megabytes (default: 25) + Sätt databas cache storleken i megabyte (standard: 25) + + + + Set database disk log size in megabytes (default: 100) + Sätt databasens loggfil storlek i megabyte (standard: 100) + + + + Specify connection timeout (in milliseconds) + Ange timeout för uppkoppling (i millisekunder) + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Lyssna efter anslutningar på <port> (förval: 8333 eller testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Ha som mest <n> anslutningar till andra klienter (förval: 125) + + + + Connect only to the specified node + Koppla enbart upp till den specifierade noden + + + + Connect to a node to retrieve peer addresses, and disconnect + Anslut till en nod för att hämta klientadresser, och koppla från + + + + Specify your own public address + Ange din egen publika adress + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + Anslut enbart till noder i nätverket <net> (IPv4 eller IPv6) + + + + Try to discover public IP address (default: 1) + Försök att upptäcka den publika IP-adressen (standard: 1) + + + + Bind to given address. Use [host]:port notation for IPv6 + Bind till given adress. Använd [värd]:port notation för IPv6 + + + + Threshold for disconnecting misbehaving peers (default: 100) + Tröskelvärde för att koppla ifrån klienter som missköter sig (förval: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Antal sekunder att hindra klienter som missköter sig från att ansluta (förval: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maximal buffert för mottagning per anslutning, <n>*1000 byte (förval: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maximal buffert för sändning per anslutning, <n>*1000 byte (förval: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + Frigör block- och adressdatabaser vid nedstängning. Detta ökar tiden för nedstängning (standard: 0) + + + + Accept command line and JSON-RPC commands + Tillåt kommandon från kommandotolken och JSON-RPC-kommandon + + + + Run in the background as a daemon and accept commands + Kör i bakgrunden som tjänst och acceptera kommandon + + + + Use the test network + Använd testnätverket + + + + Output extra debugging information + Skriv ut extra felsökningsinformation + + + + Prepend debug output with timestamp + Skriv ut tid i felsökningsinformationen + + + + Send trace/debug info to console instead of debug.log file + Skicka trace-/debuginformation till terminalen istället för till debug.log + + + + Send trace/debug info to debugger + Skicka trace-/debuginformation till debugger + + + + Username for JSON-RPC connections + Användarnamn för JSON-RPC-anslutningar + + + + Password for JSON-RPC connections + Lösenord för JSON-RPC-anslutningar + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Lyssna på JSON-RPC-anslutningar på <port> (förval: 8332) + + + + Allow JSON-RPC connections from specified IP address + Tillåt JSON-RPC-anslutningar från specifika IP-adresser + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Skicka kommandon till klient på <ip> (förval: 127.0.0.1) + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Exekvera kommando när bästa blocket ändras (%s i cmd är utbytt av blockhash) + + + + Upgrade wallet to latest format + Uppgradera plånboken till senaste formatet + + + + Set key pool size to <n> (default: 100) + Sätt storleken på nyckelpoolen till <n> (förval: 100) + + + + Rescan the block chain for missing wallet transactions + Sök i block-kedjan efter saknade wallet transaktioner + + + + How many blocks to check at startup (default: 2500, 0 = all) + Hur många block att kontrollera vid uppstart (standardvärde: 2500, 0 = alla) + + + + How thorough the block verification is (0-6, default: 1) + Hur grundlig blockverifikationen är (0-6, standardvärde: 1) + + + + Imports blocks from external blk000?.dat file + Inporterar block från extern blk000?.dat fil + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL-inställningar: (se Bitcoin-wikin för instruktioner) + + + + Use OpenSSL (https) for JSON-RPC connections + Använd OpenSSL (https) för JSON-RPC-anslutningar + + + + Server certificate file (default: server.cert) + Serverns certifikatfil (förval: server.cert) + + + + Server private key (default: server.pem) + Serverns privata nyckel (förval: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Accepterade krypteringsalgoritmer (förval: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + Varning: Hårddiskutrymme börjar bli lågt + + + + This help message + Det här hjälp medelandet + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Kan inte låsa data-mappen %s. Bitcoin körs förmodligen redan. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + Det går inte att binda till %s på den här datorn (bind returnerade felmeddelande %d, %s) + + + + Connect through socks proxy + Anslut genom socks-proxy + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + Välj socks-proxy version att använda (4 eller 5, 5 är standard) + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + Använd inte en proxy för anslutningar till nätverket <net> (IPv4 eller IPv6) + + + + Allow DNS lookups for -addnode, -seednode and -connect + Tillåt DNS-sökningar för -addnode, -seednode och -connect + + + + Pass DNS requests to (SOCKS5) proxy + Skicka vidare DNS-förfrågningar till (SOCKS5) proxy + + + + Loading addresses... + Laddar adresser... + + + + Error loading blkindex.dat + Fel vid inläsning av blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Fel vid inläsningen av wallet.dat: Plånboken är skadad + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Fel vid inläsningen av wallet.dat: Plånboken kräver en senare version av Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Plånboken behöver skrivas om: Starta om Bitcoin för att färdigställa + + + + Error loading wallet.dat + Fel vid inläsning av plånboksfilen wallet.dat + + + + Invalid -proxy address: '%s' + Ogiltig -proxy adress: '%s' + + + + Unknown network specified in -noproxy: '%s' + Okänt nätverk som anges i -noproxy: '%s' + + + + Unknown network specified in -onlynet: '%s' + Okänt nätverk som anges i -onlynet: '%s' + + + + Unknown -socks proxy version requested: %i + Okänd -socks proxy version begärd: %i + + + + Cannot resolve -bind address: '%s' + Kan inte matcha -bind adress: '%s' + + + + Not listening on any port + Lyssnar ej på någon port + + + + Cannot resolve -externalip address: '%s' + Kan inte matcha -externalip adress: '%s' + + + + Invalid amount for -paytxfee=<amount>: '%s' + Ogiltigt belopp för -paytxfee=<belopp>:'%s' + + + + Error: could not start node + Fel: kunde inte starta nod + + + + Error: Wallet locked, unable to create transaction + Fel: Plånboken är låst, det går ej att skapa en transaktion + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Fel: Denna transaktion kräver en transaktionsavgift på minst %s på grund av dess storlek, komplexitet, eller användning av senast mottagna bitcoins + + + + Error: Transaction creation failed + Fel: Transaktionen gick inte att skapa + + + + Sending... + Skickar... + + + + 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. + Fel: Transaktionen avslogs. Detta kan hända om några av mynten i plånboken redan spenderats, t.ex om du använt en kopia av wallet.dat och mynt spenderades i kopian men inte markerats som spenderas här. + + + + Invalid amount + Ogiltig mängd + + + + Insufficient funds + Otillräckligt med bitcoins + + + + Loading block index... + Laddar blockindex... + + + + Add a node to connect to and attempt to keep the connection open + Lägg till en nod att koppla upp mot och försök att hålla anslutningen öppen + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + Det går inte att binda till %s på den här datorn. Bitcoin är förmodligen redan igång. + + + + Find peers using internet relay chat (default: 0) + Sök efter klienter med internet relay chat (standard: 0) + + + + Accept connections from outside (default: 1) + Acceptera anslutningar utifrån (standard: 1) + + + + Find peers using DNS lookup (default: 1) + Sök efter klienter med DNS sökningen (standard: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Använd Universal Plug and Play för att mappa den lyssnande porten (standard: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Använd Universal Plug and Play för att mappa den lyssnande porten (standard: 0) + + + + Fee per KB to add to transactions you send + Avgift per KB att lägga till på transaktioner du skickar + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + Varning: -paytxfee är satt väldigt hög. Detta är avgiften du kommer betala för varje transaktion. + + + + Loading wallet... + Laddar plånbok... + + + + Cannot downgrade wallet + Kan inte nedgradera plånboken + + + + Cannot initialize keypool + Kan inte initiera keypool + + + + Cannot write default address + Kan inte skriva standardadress + + + + Rescanning... + Söker igen... + + + + Done loading + Klar med laddning + + + + To use the %s option + Att använda %s alternativet + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, du behöver sätta ett rpclösensord i konfigurationsfilen: + %s +Det är rekommenderat att använda följande slumpade lösenord: +rpcuser=bitcoinrpc +rpcpassword=%s +(du behöver inte komma ihåg lösenordet) +Om filen inte existerar, skapa den med enbart ägarläsbara filrättigheter. + + + + + Error + Fel + + + + An error occured while setting up the RPC port %i for listening: %s + Ett fel uppstod vid upprättandet av RPC port %i för att lyssna: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + Du behöver välja ett rpclösensord i konfigurationsfilen: +%s +Om filen inte existerar, skapa den med filrättigheten endast läsbar för ägaren. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Varning: Vänligen kolla så din dators datum och tid är korrekt. Om din klocka går fel kommer Bitcoin inte fungera korrekt. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts new file mode 100644 index 0000000..4e0e82d --- /dev/null +++ b/src/qt/locale/bitcoin_tr.ts @@ -0,0 +1,2520 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Bitcoin hakkında + + + + <b>Bitcoin</b> version + <b>Bitcoin</b> sürüm + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Telif hakkı © 2009-2012 Bitcoin geliştiricileri + +Bu yazılım deneme safhasındadır. + +MIT/X11 yazılım lisansı kapsamında yayınlanmıştır, license.txt dosyasına ya da http://www.opensource.org/licenses/mit-license.php sayfasına bakınız. + +Bu ürün OpenSSL projesi tarafından OpenSSL araç takımı (http://www.openssl.org/) için geliştirilen yazılımlar, Eric Young (eay@cryptsoft.com) tarafından yazılmış şifreleme yazılımları ve Thomas Bernard tarafından programlanmış UPnP yazılımı içerir. + + + + AddressBookPage + + + Address Book + Adres defteri + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Bunlar, ödemeleri almak için Bitcoin adresleridir. Kimin ödeme yaptığını izleyebilmek için her ödeme yollaması gereken kişiye değişik bir adres verebilirsiniz. + + + + Double-click to edit address or label + Adresi ya da etiketi düzenlemek için çift tıklayınız + + + + Create a new address + Yeni bir adres oluştur + + + + Copy the currently selected address to the system clipboard + Şu anda seçili olan adresi panoya kopyalar + + + + &New Address + &Yeni adres + + + + &Copy Address + Adresi &kopyala + + + + Show &QR Code + &QR kodunu göster + + + + Sign a message to prove you own this address + Bu adresin sizin olduğunu ispatlamak için mesaj imzalayın + + + + &Sign Message + Mesaj &imzala + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Seçilen adresi listeden siler. Sadece gönderi adresleri silinebilir. + + + + &Delete + &Sil + + + + Copy &Label + &Etiketi kopyala + + + + &Edit + &Düzenle + + + + Export Address Book Data + Adres defteri verilerini dışa aktar + + + + Comma separated file (*.csv) + Virgülle ayrılmış değerler dosyası (*.csv) + + + + Error exporting + Dışa aktarımda hata oluştu + + + + Could not write to file %1. + %1 dosyasına yazılamadı. + + + + AddressTableModel + + + Label + Etiket + + + + Address + Adres + + + + (no label) + (boş etiket) + + + + AskPassphraseDialog + + + Passphrase Dialog + Parola diyaloğu + + + + Enter passphrase + Parolayı giriniz + + + + New passphrase + Yeni parola + + + + Repeat new passphrase + Yeni parolayı tekrarlayınız + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Cüzdanınız için yeni parolayı giriniz.<br/>Lütfen <b>10 ya da daha fazla rastgele karakter</b> veya <b>sekiz ya da daha fazla kelime</b> içeren bir parola seçiniz. + + + + Encrypt wallet + Cüzdanı şifrele + + + + This operation needs your wallet passphrase to unlock the wallet. + Bu işlem cüzdan kilidini açmak için cüzdan parolanızı gerektirir. + + + + Unlock wallet + Cüzdan kilidini aç + + + + This operation needs your wallet passphrase to decrypt the wallet. + Bu işlem, cüzdan şifresini açmak için cüzdan parolasını gerektirir. + + + + Decrypt wallet + Cüzdan şifresini aç + + + + Change passphrase + Parolayı değiştir + + + + Enter the old and new passphrase to the wallet. + Cüzdan için eski ve yeni parolaları giriniz. + + + + Confirm wallet encryption + Cüzdan şifrelenmesini teyit eder + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + UYARI: Eğer cüzdanınızı şifrelerseniz ve parolanızı kaybederseniz, <b>TÜM BİTCOİNLERİNİZİ KAYBEDERSİNİZ</b>! +Cüzdanınızı şifrelemek istediğinizden emin misiniz? + + + + + Wallet encrypted + Cüzdan şifrelendi + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Şifreleme işlemini tamamlamak için Bitcoin şimdi kapanacaktır. Cüzdanınızı şifrelemenin, Bitcoinlerinizin bilgisayara bulaşan kötücül bir yazılım tarafından çalınmaya karşı tamamen koruyamayacağını unutmayınız. + + + + + Warning: The Caps Lock key is on. + Uyarı: Caps Lock tuşu etkin durumda. + + + + + + + Wallet encryption failed + Cüzdan şifrelemesi başarısız oldu + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Dahili bir hata sebebiyle cüzdan şifrelemesi başarısız oldu. Cüzdanınız şifrelenmedi. + + + + + The supplied passphrases do not match. + Girilen parolalar birbirleriyle uyumlu değil. + + + + Wallet unlock failed + Cüzdan kilidinin açılması başarısız oldu + + + + + + The passphrase entered for the wallet decryption was incorrect. + Cüzdan şifresinin açılması için girilen parola yanlıştı. + + + + Wallet decryption failed + Cüzdan şifresinin açılması başarısız oldu + + + + Wallet passphrase was succesfully changed. + Cüzdan parolası başarılı bir şekilde değiştirildi. + + + + BitcoinGUI + + + Bitcoin Wallet + Bitcoin cüzdanı + + + + Sign &message... + &Mesaj imzala... + + + + Show/Hide &Bitcoin + &Bitcoin'i Göster/Sakla + + + + Synchronizing with network... + Şebeke ile senkronizasyon... + + + + &Overview + &Genel bakış + + + + Show general overview of wallet + Cüzdana genel bakışı gösterir + + + + &Transactions + &Muameleler + + + + Browse transaction history + Muamele tarihçesini tara + + + + &Address Book + &Adres defteri + + + + Edit the list of stored addresses and labels + Saklanan adres ve etiket listesini düzenler + + + + &Receive coins + Bitcoin &al + + + + Show the list of addresses for receiving payments + Ödeme alma adreslerinin listesini gösterir + + + + &Send coins + Bitcoin &yolla + + + + Prove you control an address + Bu adresin kontrolünüz altında olduğunu ispatlayın + + + + E&xit + &Çık + + + + Quit application + Uygulamadan çıkar + + + + &About %1 + %1 &hakkında + + + + Show information about Bitcoin + Bitcoin hakkında bilgi gösterir + + + + About &Qt + &Qt hakkında + + + + Show information about Qt + Qt hakkında bilgi görüntüler + + + + &Options... + &Seçenekler... + + + + &Encrypt Wallet... + Cüzdanı &şifrele... + + + + &Backup Wallet... + Cüzdanı &yedekle... + + + + &Change Passphrase... + Parolayı &değiştir... + + + + ~%n block(s) remaining + ~%n blok kaldı + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + Muamele tarihçesinden %1 blok indirildi (toplam %2 blok, %%3 tamamlandı). + + + + &Export... + &Dışa aktar... + + + + Send coins to a Bitcoin address + Bir Bitcoin adresine Bitcoin yollar + + + + Modify configuration options for Bitcoin + Bitcoin seçeneklerinin yapılandırmasını değiştirir + + + + Show or hide the Bitcoin window + Bitcoin penceresini göster ya da sakla + + + + Export the data in the current tab to a file + Güncel sekmedeki verileri bir dosyaya aktar + + + + Encrypt or decrypt wallet + Cüzdanı şifreler ya da şifreyi açar + + + + Backup wallet to another location + Cüzdanı diğer bir konumda yedekle + + + + Change the passphrase used for wallet encryption + Cüzdan şifrelemesi için kullanılan parolayı değiştirir + + + + &Debug window + &Hata ayıklama penceresi + + + + Open debugging and diagnostic console + Hata ayıklama ve teşhis penceresini aç + + + + &Verify message... + &Mesaj kontrol et... + + + + Verify a message signature + Mesaj imzasını kontrol et + + + + &File + &Dosya + + + + &Settings + &Ayarlar + + + + &Help + &Yardım + + + + Tabs toolbar + Sekme araç çubuğu + + + + Actions toolbar + Faaliyet araç çubuğu + + + + + [testnet] + [testnet] + + + + + Bitcoin client + Bitcoin istemcisi + + + + %n active connection(s) to Bitcoin network + Bitcoin şebekesine %n etkin bağlantı + + + + Downloaded %1 blocks of transaction history. + Muamele tarihçesinin %1 adet bloku indirildi. + + + + %n second(s) ago + %n saniye önce + + + + %n minute(s) ago + %n dakika önce + + + + %n hour(s) ago + %n saat önce + + + + %n day(s) ago + %n gün önce + + + + Up to date + Güncel + + + + Catching up... + Aralık kapatılıyor... + + + + Last received block was generated %1. + Son alınan blok şu vakit oluşturulmuştu: %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Bu muamele boyut sınırlarını aşmıştır. Gene de %1 ücret ödeyerek gönderebilirsiniz, ki bu ücret muamelenizi işleyen ve şebekeye yardım eden düğümlere ödenecektir. Ücreti ödemek istiyor musunuz? + + + + Confirm transaction fee + Muamele ücretini teyit et + + + + Sent transaction + Muamele yollandı + + + + Incoming transaction + Gelen muamele + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Tarih: %1 +Miktar: %2 +Tür: %3 +Adres: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Cüzdan <b>şifrelenmiştir</b> ve şu anda <b>kilidi açılmıştır</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Cüzdan <b>şifrelenmiştir</b> ve şu anda <b>kilitlidir</b> + + + + Backup Wallet + Cüzdanı yedekle + + + + Wallet Data (*.dat) + Cüzdan verileri (*.dat) + + + + Backup Failed + Yedekleme başarısız oldu + + + + There was an error trying to save the wallet data to the new location. + Cüzdan verilerinin başka bir konumda kaydedilmesi sırasında bir hata meydana geldi. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + Ciddi bir hata oluştu. Artık Bitcoin güvenli bir şekilde işlemeye devam edemez ve kapanacaktır. + + + + ClientModel + + + Network Alert + Şebeke hakkında uyarı + + + + DisplayOptionsPage + + + Display + Görünüm + + + + default + varsayılan + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + Kullanıcı arayüzünün dili burada belirtilebilir. Bu ayar Bitcoin tekrar başlatıldığında etkinleşecektir. + + + + User Interface &Language: + Kullanıcı arayüzü &lisanı: + + + + &Unit to show amounts in: + Miktarı göstermek için &birim: + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Bitcoin gönderildiğinde arayüzde gösterilecek varsayılan alt birimi seçiniz + + + + &Display addresses in transaction list + Muamele listesinde adresleri &göster + + + + Whether to show Bitcoin addresses in the transaction list + Muamele listesinde Bitcoin adreslerinin gösterilip gösterilmeyeceklerini belirler + + + + Warning + Uyarı + + + + This setting will take effect after restarting Bitcoin. + Bu ayarlar Bitcoin tekrar başlatıldığında etkinleşecektir. + + + + EditAddressDialog + + + Edit Address + Adresi düzenle + + + + &Label + &Etiket + + + + The label associated with this address book entry + Bu adres defteri unsuru ile ilişkili etiket + + + + &Address + &Adres + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Bu adres defteri unsuru ile ilişkili adres. Bu, sadece gönderi adresi için değiştirilebilir. + + + + New receiving address + Yeni alım adresi + + + + New sending address + Yeni gönderi adresi + + + + Edit receiving address + Alım adresini düzenle + + + + Edit sending address + Gönderi adresini düzenle + + + + The entered address "%1" is already in the address book. + Girilen "%1" adresi hâlihazırda adres defterinde mevcuttur. + + + + The entered address "%1" is not a valid Bitcoin address. + Girilen "%1" adresi geçerli bir Bitcoin adresi değildir. + + + + Could not unlock wallet. + Cüzdan kilidi açılamadı. + + + + New key generation failed. + Yeni anahtar oluşturulması başarısız oldu. + + + + HelpMessageBox + + + + Bitcoin-Qt + Bitcoin-Qt + + + + version + sürüm + + + + Usage: + Kullanım: + + + + options + seçenekler + + + + UI options + Kullanıcı arayüzü seçenekleri + + + + Set language, for example "de_DE" (default: system locale) + Lisan belirt, mesela "de_De" (varsayılan: sistem dili) + + + + Start minimized + Küçültülmüş olarak başla + + + + Show splash screen on startup (default: 1) + Başlatıldığında başlangıç ekranını göster (varsayılan: 1) + + + + MainOptionsPage + + + 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. + Çıkışta blok ve adres veri tabanlarını ayırır. Bu, kapanışı yavaşlatır ancak veri tabanlarının başka klasörlere taşınabilmelerine imkân sağlar. Cüzdan daima ayırılır. + + + + Pay transaction &fee + Muamele ücreti &öde + + + + Main + Ana menü + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Muamelelerin hızlı işlenmesini garantilemeye yardım eden, seçime dayalı kB başı muamele ücreti. Muamelelerin çoğunluğunun boyutu 1 kB'dir. 0.01 ücreti önerilir. + + + + &Start Bitcoin on system login + Bitcoin'i sistem oturumuyla &başlat + + + + Automatically start Bitcoin after logging in to the system + Sistemde oturum açıldığında Bitcoin'i otomatik olarak başlat + + + + &Detach databases at shutdown + Kapanışta veritabanlarını &ayır + + + + MessagePage + + + Sign Message + Mesaj imzala + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + Bir adresin sizin olduğunu ispatlamak için adresinizle mesaj imzalayabilirsiniz. Oltalama saldırılarının kimliğinizi imzanızla elde etmeyi deneyebilecekleri için belirsiz hiçbir şey imzalamamaya dikkat ediniz. Sadece ayrıntılı açıklaması olan ve tümüne katıldığınız ifadeleri imzalayın. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Mesajı imzalamak için kullanılacak adres (mesela 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + Adres defterinden adres seç + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Panodan adres yapıştır + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + İmzalamak istediğiniz mesajı burada giriniz + + + + Copy the current signature to the system clipboard + Güncel imzayı sistem panosuna kopyala + + + + &Copy Signature + İmzayı &kopyala + + + + Reset all sign message fields + Tüm mesaj alanlarını sıfırla + + + + Clear &All + Tümünü &temizle + + + + Click "Sign Message" to get signature + İmza elde etmek için "Mesaj İmzala" unsurunu tıklayın + + + + Sign a message to prove you own this address + Bu adresin sizin olduğunu ispatlamak için bir mesaj imzalayın + + + + &Sign Message + Mesaj &İmzala + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Bitcoin adresi giriniz (mesela 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + İmza sırasında hata meydana geldi + + + + %1 is not a valid address. + %1 geçerli bir adres değildir. + + + + %1 does not refer to a key. + %1 herhangi bir anahtara işaret etmemektedir. + + + + Private key for %1 is not available. + %1 için özel anahtar mevcut değil. + + + + Sign failed + İmzalama başarısız oldu + + + + NetworkOptionsPage + + + Network + Şebeke + + + + Map port using &UPnP + Portları &UPnP kullanarak haritala + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Yönlendiricide Bitcoin istemci portlarını otomatik olarak açar. Bu, sadece yönlendiricinizin UPnP desteği bulunuyorsa ve etkinse çalışabilir. + + + + &Connect through SOCKS4 proxy: + SOCKS4 vekil sunucusu vasıtasıyla ba&ğlan: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Bitcoin şebekesine SOCKS4 vekil sunucusu vasıtasıyla bağlanır (mesela Tor ile bağlanıldığında) + + + + Proxy &IP: + Vekil &İP: + + + + &Port: + &Port: + + + + IP address of the proxy (e.g. 127.0.0.1) + Vekil sunucunun İP adresi (mesela 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Vekil sunucun portu (örneğin 1234) + + + + OptionsDialog + + + Options + Seçenekler + + + + OverviewPage + + + Form + Form + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + Görüntülenen veriler zaman aşımını uğramış olabilir. Bağlantı kurulduğunda cüzdanınız otomatik olarak şebeke ile eşleşir ancak bu işlem henüz tamamlanmamıştır. + + + + Balance: + Bakiye: + + + + Number of transactions: + Muamele sayısı: + + + + Unconfirmed: + Doğrulanmamış: + + + + Wallet + Cüzdan + + + + <b>Recent transactions</b> + <b>Son muameleler</b> + + + + Your current balance + Güncel bakiyeniz + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Doğrulanması beklenen ve henüz güncel bakiyeye ilâve edilmemiş muamelelerin toplamı + + + + Total number of transactions in wallet + Cüzdandaki muamelelerin toplam sayısı + + + + + out of sync + eşleşme dışı + + + + QRCodeDialog + + + QR Code Dialog + QR kodu diyaloğu + + + + QR Code + QR Kodu + + + + Request Payment + Ödeme isteği + + + + Amount: + Miktar: + + + + BTC + BTC + + + + Label: + Etiket: + + + + Message: + Mesaj: + + + + &Save As... + &Farklı kaydet... + + + + Error encoding URI into QR Code. + URI'nin QR koduna kodlanmasında hata oluştu. + + + + Resulting URI too long, try to reduce the text for label / message. + Sonuç URI çok uzun, etiket ya da mesaj metnini kısaltmayı deneyiniz. + + + + Save QR Code + QR kodu kaydet + + + + PNG Images (*.png) + PNG resimleri (*.png) + + + + RPCConsole + + + Bitcoin debug window + Bitcoin hata ayıklama penceresi + + + + Client name + İstemci ismi + + + + + + + + + + + + N/A + Mevcut değil + + + + Client version + İstemci sürümü + + + + &Information + &Malumat + + + + Client + İstemci + + + + Startup time + Başlama zamanı + + + + Network + Şebeke + + + + Number of connections + Bağlantı sayısı + + + + On testnet + Testnet üzerinde + + + + Block chain + Blok zinciri + + + + Current number of blocks + Güncel blok sayısı + + + + Estimated total blocks + Tahmini toplam blok sayısı + + + + Last block time + Son blok zamanı + + + + Debug logfile + Hata ayıklama kütük dosyası + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + Güncel veri klasöründen Bitcoin hata ayıklama kütüğünü aç. Büyük kütük dosyaları için bu birkaç saniye alabilir. + + + + &Open + &Aç + + + + &Console + &Konsol + + + + Build date + Derleme tarihi + + + + Clear console + Konsolu temizle + + + + Welcome to the Bitcoin RPC console. + Bitcoin RPC konsoluna hoş geldiniz. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Tarihçede gezinmek için imleç tuşlarını kullanınız, <b>Ctrl-L</b> ile de ekranı temizleyebilirsiniz. + + + + Type <b>help</b> for an overview of available commands. + Mevcut komutların listesi için <b>help</b> yazınız. + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Bitcoin yolla + + + + Send to multiple recipients at once + Birçok alıcıya aynı anda gönder + + + + &Add Recipient + Alıcı &ekle + + + + Remove all transaction fields + Bütün muamele alanlarını kaldır + + + + Clear &All + Tümünü &temizle + + + + Balance: + Bakiye: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Yollama etkinliğini teyit ediniz + + + + &Send + &Gönder + + + + <b>%1</b> to %2 (%3) + <b>%1</b> şu adrese: %2 (%3) + + + + Confirm send coins + Gönderiyi teyit ediniz + + + + Are you sure you want to send %1? + %1 göndermek istediğinizden emin misiniz? + + + + and + ve + + + + The recepient address is not valid, please recheck. + Alıcı adresi geçerli değildir, lütfen denetleyiniz. + + + + The amount to pay must be larger than 0. + Ödeyeceğiniz tutarın sıfırdan yüksek olması gerekir. + + + + The amount exceeds your balance. + Tutar bakiyenizden yüksektir. + + + + The total exceeds your balance when the %1 transaction fee is included. + Toplam, %1 muamele ücreti ilâve edildiğinde bakiyenizi geçmektedir. + + + + Duplicate address found, can only send to each address once per send operation. + Çift adres bulundu, belli bir gönderi sırasında her adrese sadece tek bir gönderide bulunulabilir. + + + + Error: Transaction creation failed. + Hata: Muamele oluşturması başarısız oldu. + + + + 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. + Hata: Muamele reddedildi. Cüzdanınızdaki madenî paraların bazıları zaten harcanmış olduğunda bu meydana gelebilir. Örneğin wallet.dat dosyasının bir kopyasını kullandıysanız ve kopyada para harcandığında ancak burada harcandığı işaretlenmediğinde. + + + + SendCoinsEntry + + + Form + Form + + + + A&mount: + M&iktar: + + + + Pay &To: + &Şu kişiye öde: + + + + + Enter a label for this address to add it to your address book + Adres defterinize eklemek için bu adrese ilişik bir etiket giriniz + + + + &Label: + &Etiket: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Ödemenin gönderileceği adres (mesela 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Adres defterinden adres seç + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Panodan adres yapıştır + + + + Alt+P + Alt+P + + + + Remove this recipient + Bu alıcıyı kaldır + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Bitcoin adresi giriniz (mesela 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + %1 blok için açık + + + + Open until %1 + %1 değerine dek açık + + + + %1/offline? + %1/çevrimdışı mı? + + + + %1/unconfirmed + %1/doğrulanmadı + + + + %1 confirmations + %1 teyit + + + + <b>Status:</b> + <b>Durum:</b> + + + + , has not been successfully broadcast yet + , henüz başarılı bir şekilde yayınlanmadı + + + + , broadcast through %1 node + , %1 düğüm vasıtasıyla yayınlandı + + + + , broadcast through %1 nodes + , %1 düğüm vasıtasıyla yayınlandı + + + + <b>Date:</b> + <b>Tarih:</b> + + + + <b>Source:</b> Generated<br> + <b>Kaynak:</b> Oluşturuldu<br> + + + + + <b>From:</b> + <b>Gönderen:</b> + + + + unknown + bilinmiyor + + + + + + <b>To:</b> + <b>Alıcı:</b> + + + + (yours, label: + (sizin, etiket: + + + + (yours) + (sizin) + + + + + + + <b>Credit:</b> + <b>Gelir:</b> + + + + (%1 matures in %2 more blocks) + (%1, %2 ek blok sonrasında olgunlaşacak) + + + + (not accepted) + (kabul edilmedi) + + + + + + <b>Debit:</b> + <b>Gider:</b> + + + + <b>Transaction fee:</b> + <b>Muamele ücreti:<b> + + + + <b>Net amount:</b> + <b>Net miktar:</b> + + + + Message: + Mesaj: + + + + Comment: + Yorum: + + + + Transaction ID: + Muamele kimliği: + + + + 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. + Oluşturulan Bitcoin'lerin harcanabilmelerinden önce 120 blok beklemeleri gerekmektedir. Bu blok, oluşturduğunuzda, blok zincirine eklenmesi için ağda yayınlandı. Zincire eklenmesi başarısız olursa, "kabul edilmedi" olarak değiştirilecek ve harcanamayacaktır. Bu, bazen başka bir düğüm sizden birkaç saniye önce ya da sonra blok oluşturursa meydana gelebilir. + + + + TransactionDescDialog + + + Transaction details + Muamele detayları + + + + This pane shows a detailed description of the transaction + Bu pano muamelenin ayrıntılı açıklamasını gösterir + + + + TransactionTableModel + + + Date + Tarih + + + + Type + Tür + + + + Address + Adres + + + + Amount + Miktar + + + + Open for %n block(s) + %n blok için açık + + + + Open until %1 + %1 değerine dek açık + + + + Offline (%1 confirmations) + Çevrimdışı (%1 teyit) + + + + Unconfirmed (%1 of %2 confirmations) + Doğrulanmadı (%1 (toplam %2 üzerinden) teyit) + + + + Confirmed (%1 confirmations) + Doğrulandı (%1 teyit) + + + + Mined balance will be available in %n more blocks + Madenden çıkarılan bakiye %n ek blok sonrasında kullanılabilecektir + + + + This block was not received by any other nodes and will probably not be accepted! + Bu blok başka hiçbir düğüm tarafından alınmamıştır ve muhtemelen kabul edilmeyecektir! + + + + Generated but not accepted + Oluşturuldu ama kabul edilmedi + + + + Received with + Şununla alındı + + + + Received from + Alındığı kişi + + + + Sent to + Gönderildiği adres + + + + Payment to yourself + Kendinize ödeme + + + + Mined + Madenden çıkarılan + + + + (n/a) + (mevcut değil) + + + + Transaction status. Hover over this field to show number of confirmations. + Muamele durumu. Doğrulama sayısını görüntülemek için imleci bu alanda tutunuz. + + + + Date and time that the transaction was received. + Muamelenin alındığı tarih ve zaman. + + + + Type of transaction. + Muamele türü. + + + + Destination address of transaction. + Muamelenin alıcı adresi. + + + + Amount removed from or added to balance. + Bakiyeden alınan ya da bakiyeye eklenen miktar. + + + + TransactionView + + + + All + Hepsi + + + + Today + Bugün + + + + This week + Bu hafta + + + + This month + Bu ay + + + + Last month + Geçen ay + + + + This year + Bu sene + + + + Range... + Aralık... + + + + Received with + Şununla alınan + + + + Sent to + Gönderildiği adres + + + + To yourself + Kendinize + + + + Mined + Oluşturulan + + + + Other + Diğer + + + + Enter address or label to search + Aranacak adres ya da etiket giriniz + + + + Min amount + Asgari miktar + + + + Copy address + Adresi kopyala + + + + Copy label + Etiketi kopyala + + + + Copy amount + Miktarı kopyala + + + + Edit label + Etiketi düzenle + + + + Show transaction details + Muamele detaylarını göster + + + + Export Transaction Data + Muamele verilerini dışa aktar + + + + Comma separated file (*.csv) + Virgülle ayrılmış değerler dosyası (*.csv) + + + + Confirmed + Doğrulandı + + + + Date + Tarih + + + + Type + Tür + + + + Label + Etiket + + + + Address + Adres + + + + Amount + Miktar + + + + ID + Kimlik + + + + Error exporting + Dışa aktarımda hata oluştu + + + + Could not write to file %1. + %1 dosyasına yazılamadı. + + + + Range: + Aralık: + + + + to + ilâ + + + + VerifyMessageDialog + + + Verify Signed Message + İmzalı mesajı kontrol et + + + + 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. + Mesajı imzalamak için kullanılan Bitcoin adresini elde etmek için mesaj ve imzayı aşağıda giriniz (yani satırlar, boşluklar ve sekmeler gibi görünmeyen karakterleri doğru şekilde kopyalamaya dikkat ediniz). + + + + Verify a message and obtain the Bitcoin address used to sign the message + Mesajı kontrol et ve imzalamak için kullanılan Bitcoin adresini elde et + + + + &Verify Message + Mesajı &kontrol et + + + + Copy the currently selected address to the system clipboard + Şu anda seçili olan adresi panoya kopyalar + + + + &Copy Address + Adresi &kopyala + + + + Reset all verify message fields + Tüm mesaj kontrolü alanlarını sıfırla + + + + Clear &All + Tümünü &temizle + + + + Enter Bitcoin signature + Bitcoin imzası gir + + + + Click "Verify Message" to obtain address + Adresi elde etmek için "Mesajı kontrol et" düğmesini tıkayınız + + + + + Invalid Signature + Geçersiz imza + + + + The signature could not be decoded. Please check the signature and try again. + İmzanın kodu çözülemedi. İmzayı kontrol edip tekrar deneyiniz. + + + + The signature did not match the message digest. Please check the signature and try again. + İmza mesajın hash değeri eşleşmedi. İmzayı kontrol edip tekrar deneyiniz. + + + + Address not found in address book. + Bu adres, adres defterinde bulunamadı. + + + + Address found in address book: %1 + Adres defterinde bu adres bulundu: %1 + + + + WalletModel + + + Sending... + Gönderiliyor... + + + + WindowOptionsPage + + + Window + Pencere + + + + &Minimize to the tray instead of the taskbar + İşlem çubuğu yerine sistem çekmecesine &küçült + + + + Show only a tray icon after minimizing the window + Küçültüldükten sonra sadece çekmece ikonu gösterir + + + + M&inimize on close + Kapatma sırasında k&üçült + + + + 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. + Pencere kapatıldığında uygulamadan çıkmak yerine uygulamayı küçültür. Bu seçenek etkinleştirildiğinde, uygulama sadece menüden çıkış seçildiğinde kapanacaktır. + + + + bitcoin-core + + + Bitcoin version + Bitcoin sürümü + + + + Usage: + Kullanım: + + + + Send command to -server or bitcoind + -server ya da bitcoind'ye komut gönder + + + + List commands + Komutları listele + + + + Get help for a command + Bir komut için yardım al + + + + Options: + Seçenekler: + + + + Specify configuration file (default: bitcoin.conf) + Yapılandırma dosyası belirt (varsayılan: bitcoin.conf) + + + + Specify pid file (default: bitcoind.pid) + Pid dosyası belirt (varsayılan: bitcoind.pid) + + + + Generate coins + Madenî para (Bitcoin) oluştur + + + + Don't generate coins + Bitcoin oluşturmasını devre dışı bırak + + + + Specify data directory + Veri dizinini belirt + + + + Set database cache size in megabytes (default: 25) + Veritabanı önbellek boyutunu megabayt olarak belirt (varsayılan: 25) + + + + Set database disk log size in megabytes (default: 100) + Diskteki veritabanı kütüğü boyutunu megabayt olarak belirt (varsayılan: 100) + + + + Specify connection timeout (in milliseconds) + Bağlantı zaman aşım süresini milisaniye olarak belirt + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Bağlantılar için dinlenecek <port> (varsayılan: 8333 ya da testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Eşler ile en çok <n> adet bağlantı kur (varsayılan: 125) + + + + Connect only to the specified node + Sadece belirtilen düğüme bağlan + + + + Connect to a node to retrieve peer addresses, and disconnect + Eş adresleri elde etmek için bir düğüme bağlan ve ardından bağlantıyı kes + + + + Specify your own public address + Kendi genel adresinizi tanımlayın + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + Sadece <net> şebekesindeki düğümlere bağlan (IPv4 ya da IPv6) + + + + Try to discover public IP address (default: 1) + Genel IP adresini keşfetmeye çalış (varsayılan: 1) + + + + Bind to given address. Use [host]:port notation for IPv6 + Belirtilen adresle ilişiklendir. IPv6 için [makine]:port simgelemini kullanınız + + + + Threshold for disconnecting misbehaving peers (default: 100) + Aksaklık gösteren eşlerle bağlantıyı kesme sınırı (varsayılan: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Aksaklık gösteren eşlerle yeni bağlantıları engelleme süresi, saniye olarak (varsayılan: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Her bağlantı için alım tamponu, <n>*1000 bayt (varsayılan: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Her bağlantı için yollama tamponu, <n>*1000 bayt (varsayılan: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + Blok ve adres veri tabanlarını ayır. Kapatma süresini arttırır (varsayılan: 0) + + + + Accept command line and JSON-RPC commands + Konut satırı ve JSON-RPC komutlarını kabul et + + + + Run in the background as a daemon and accept commands + Arka planda daemon (servis) olarak çalış ve komutları kabul et + + + + Use the test network + Deneme şebekesini kullan + + + + Output extra debugging information + İlâve hata ayıklama verisi çıkar + + + + Prepend debug output with timestamp + Hata ayıklama çıktısına tarih ön ekleri ilâve et + + + + Send trace/debug info to console instead of debug.log file + Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder + + + + Send trace/debug info to debugger + Hata ayıklayıcıya -debugger- trace/hata ayıklama verileri gönder + + + + Username for JSON-RPC connections + JSON-RPC bağlantıları için kullanıcı ismi + + + + Password for JSON-RPC connections + JSON-RPC bağlantıları için parola + + + + Listen for JSON-RPC connections on <port> (default: 8332) + JSON-RPC bağlantıları için dinlenecek <port> (varsayılan: 8332) + + + + Allow JSON-RPC connections from specified IP address + Belirtilen İP adresinden JSON-RPC bağlantılarını kabul et + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Şu <ip> adresinde (varsayılan: 127.0.0.1) çalışan düğüme komut yolla + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + En iyi blok değiştiğinde komutu çalıştır (cmd için %s blok hash değeri ile değiştirilecektir) + + + + Upgrade wallet to latest format + Cüzdanı en yeni biçime güncelle + + + + Set key pool size to <n> (default: 100) + Anahtar alan boyutunu <n> değerine ayarla (varsayılan: 100) + + + + Rescan the block chain for missing wallet transactions + Blok zincirini eksik cüzdan muameleleri için tekrar tara + + + + How many blocks to check at startup (default: 2500, 0 = all) + Başlangıçta ne kadar blokun denetleneceği (varsayılan: 2500, 0 = tümü) + + + + How thorough the block verification is (0-6, default: 1) + Blok kontrolünün derinliği (0 ilâ 6, varsayılan: 1) + + + + Imports blocks from external blk000?.dat file + Harici blk000?.dat dosyasından blokları içe aktarır + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL seçenekleri: (SSL kurulum bilgisi için Bitcoin vikisine bakınız) + + + + Use OpenSSL (https) for JSON-RPC connections + JSON-RPC bağlantıları için OpenSSL (https) kullan + + + + Server certificate file (default: server.cert) + Sunucu sertifika dosyası (varsayılan: server.cert) + + + + Server private key (default: server.pem) + Sunucu özel anahtarı (varsayılan: server.pem) + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Kabul edilebilir şifreler (varsayılan: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + Warning: Disk space is low + Uyarı: Disk alanı düşük + + + + This help message + Bu yardım mesajı + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + %s veri dizininde kilit elde edilemedi. Bitcoin muhtemelen hâlihazırda çalışmaktadır. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + Bu bilgisayarda %s unsuruna bağlanılamadı. (bind şu hatayı iletti: %d, %s) + + + + Connect through socks proxy + Socks vekil sunucusu vasıtasıyla bağlan + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + Kullanılacak socks vekil sunucu sürümünü seç (4 veya 5, ki 5 varsayılan değerdir) + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + <net> şebekesi ile bağlantılarda vekil sunucu kullanma (IPv4 ya da IPv6) + + + + Allow DNS lookups for -addnode, -seednode and -connect + -addnode, -seednode ve -connect için DNS aramalarına izin ver + + + + Pass DNS requests to (SOCKS5) proxy + DNS isteklerini (SOCKS5) vekil sunucusuna devret + + + + Loading addresses... + Adresler yükleniyor... + + + + Error loading blkindex.dat + blkindex.dat dosyasının yüklenmesinde hata oluştu + + + + Error loading wallet.dat: Wallet corrupted + wallet.dat dosyasının yüklenmesinde hata oluştu: bozuk cüzdan + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + wallet.dat dosyasının yüklenmesinde hata oluştu: cüzdanın daha yeni bir Bitcoin sürümüne ihtiyacı var + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Cüzdanın tekrar yazılması gerekiyordu: işlemi tamamlamak için Bitcoin'i yeniden başlatınız + + + + Error loading wallet.dat + wallet.dat dosyasının yüklenmesinde hata oluştu + + + + Invalid -proxy address: '%s' + Geçersiz -proxy adresi: '%s' + + + + Unknown network specified in -noproxy: '%s' + -noproxy'de bilinmeyen bir şebeke belirtildi: '%s' + + + + Unknown network specified in -onlynet: '%s' + -onlynet için bilinmeyen bir şebeke belirtildi: '%s' + + + + Unknown -socks proxy version requested: %i + Bilinmeyen bir -socks vekil sürümü talep edildi: %i + + + + Cannot resolve -bind address: '%s' + -bind adresi çözümlenemedi: '%s' + + + + Not listening on any port + Hiçbir port dinlenmiyor + + + + Cannot resolve -externalip address: '%s' + -externalip adresi çözümlenemedi: '%s' + + + + Invalid amount for -paytxfee=<amount>: '%s' + -paytxfee=<miktar> için geçersiz miktar: '%s' + + + + Error: could not start node + Hata: düğüm başlatılamadı + + + + Error: Wallet locked, unable to create transaction + Hata: Cüzdan kilitli, muamele oluşturulamadı + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + Hata: Muamelenin miktarı, karmaşıklığı ya da yakın geçmişte alınan fonların kullanılması nedeniyle bu muamele en az %s tutarında ücret gerektirmektedir + + + + Error: Transaction creation failed + Hata: Muamele oluşturması başarısız oldu + + + + Sending... + Gönderiliyor... + + + + 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. + Hata: Muamele reddedildi. Cüzdanınızdaki madenî paraların bazıları zaten harcanmış olduğunda bu meydana gelebilir. Örneğin wallet.dat dosyasının bir kopyasını kullandıysanız ve kopyada para harcandığında ancak burada harcandığı işaretlenmediğinde. + + + + Invalid amount + Geçersiz miktar + + + + Insufficient funds + Yetersiz bakiye + + + + Loading block index... + Blok indeksi yükleniyor... + + + + Add a node to connect to and attempt to keep the connection open + Bağlanılacak düğüm ekle ve bağlantıyı zinde tutmaya çalış + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin muhtemelen hâlihazırda çalışmaktadır. + + + + Find peers using internet relay chat (default: 0) + Eşleri Internet Relay Chat vasıtasıyla bul (varsayılan: 0) + + + + Accept connections from outside (default: 1) + Dışarıdan gelen bağlantıları kabul et (varsayılan: 1) + + + + Find peers using DNS lookup (default: 1) + Eşleri DNS araması vasıtasıyla bul (varsayılan: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + Dinlenecek portu haritalamak için Universal Plug and Play kullan (varsayılan: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + Dinlenecek portu haritalamak için Universal Plug and Play kullan (varsayılan: 0) + + + + Fee per KB to add to transactions you send + Yolladığınız muameleler için eklenecek KB başı ücret + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + Uyarı: -paytxfee çok yüksek bir değere ayarlanmış. Bu, muamele gönderirseniz ödeyeceğiniz muamele ücretidir. + + + + Loading wallet... + Cüzdan yükleniyor... + + + + Cannot downgrade wallet + Cüzdan eski biçime geri alınamaz + + + + Cannot initialize keypool + Keypool başlatılamadı + + + + Cannot write default address + Varsayılan adres yazılamadı + + + + Rescanning... + Yeniden tarama... + + + + Done loading + Yükleme tamamlandı + + + + To use the %s option + %s seçeneğini kullanmak için + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, şu yapılandırma dosyasında rpc parolası belirtmeniz gerekir: + %s +Aşağıdaki rastgele oluşturulan parolayı kullanmanız tavsiye edilir: +rpcuser=bitcoinrpc +rpcpassword=%s +(bu parolayı hatırlamanız gerekli değildir) +Dosya mevcut değilse, sadece sahibi için okumayla sınırlı izin ile oluşturunuz. + + + + + Error + Hata + + + + An error occured while setting up the RPC port %i for listening: %s + %i RPC portunun dinleme için kurulması sırasında bir hata meydana geldi: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + rpcpassword=<parola> şu yapılandırma dosyasında belirtilmelidir: +%s +Dosya mevcut değilse, sadece sahibi için okumayla sınırlı izin ile oluşturunuz. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Uyarı: Lütfen bilgisayarınızın tarih ve saatinin doğru olup olmadığını kontrol ediniz. Saatiniz doğru değilse Bitcoin gerektiği gibi çalışamaz. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts new file mode 100644 index 0000000..bf41f51 --- /dev/null +++ b/src/qt/locale/bitcoin_uk.ts @@ -0,0 +1,2540 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + Про Bitcoin + + + + <b>Bitcoin</b> version + Версія <b>Bitcoin'a<b> + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + Авторське право © 2009-2012 Розробники Bitcoin + +Це програмне забезпечення є експериментальним. + +Поширюється за ліцензією MIT/X11, додаткова інформація міститься у файлі license.txt, а також за адресою http://www.opensource.org/licenses/mit-license.php. + +Цей продукт включає в себе програмне забезпечення, розроблене в рамках проекту OpenSSL (http://www.openssl.org/), криптографічне програмне забезпечення, написане Еріком Янгом (eay@cryptsoft.com), та функції для роботи з UPnP, написані Томасом Бернардом. + + + + AddressBookPage + + + Address Book + Адресна книга + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + Це ваші адреси для отримання платежів. Ви можете давати різні адреси різним людям, таким чином маючи можливість відслідкувати хто конкретно і скільки вам заплатив. + + + + Double-click to edit address or label + Двічі клікніть на адресу чи назву для їх зміни + + + + Create a new address + Створити нову адресу + + + + Copy the currently selected address to the system clipboard + Копіювати виділену адресу в буфер обміну + + + + &New Address + + + + + &Copy Address + + + + + Show &QR Code + Показати QR-&Код + + + + Sign a message to prove you own this address + Підпишіть повідомлення щоб довести, що ви є власником цієї адреси + + + + &Sign Message + &Підписати повідомлення + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + Видалити виділену адресу зі списку. Лише адреси з адресної книги можуть бути видалені. + + + + &Delete + &Видалити + + + + Copy &Label + + + + + &Edit + + + + + Export Address Book Data + Експортувати адресну книгу + + + + Comma separated file (*.csv) + Файли відділені комами (*.csv) + + + + Error exporting + Помилка при експортуванні + + + + Could not write to file %1. + Неможливо записати у файл %1. + + + + AddressTableModel + + + Label + Назва + + + + Address + Адреса + + + + (no label) + (немає назви) + + + + AskPassphraseDialog + + + Passphrase Dialog + + + + + Enter passphrase + Введіть пароль + + + + New passphrase + Новий пароль + + + + Repeat new passphrase + Повторіть пароль + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + Введіть новий пароль для гаманця.<br/>Будь ласка, використовуйте паролі що містять <b> як мінімум 10 випадкових символів </b> або <b> як мінімум 8 слів</b>. + + + + Encrypt wallet + Зашифрувати гаманець + + + + This operation needs your wallet passphrase to unlock the wallet. + Ця операція потребує пароль для розблокування гаманця. + + + + Unlock wallet + Розблокувати гаманець + + + + This operation needs your wallet passphrase to decrypt the wallet. + Ця операція потребує пароль для дешифрування гаманця. + + + + Decrypt wallet + Дешифрувати гаманець + + + + Change passphrase + Змінити пароль + + + + Enter the old and new passphrase to the wallet. + Ввести старий та новий паролі для гаманця. + + + + Confirm wallet encryption + Підтвердити шифрування гаманця + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + УВАГА: Якщо ви зашифруєте гаманець і забудете пароль, ви <b>ВТРАТИТЕ ВСІ СВОЇ БІТКОІНИ</b>! +Ви дійсно хочете зашифрувати свій гаманець? + + + + + Wallet encrypted + Гаманець зашифровано + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Біткоін-клієнт буде закрито для завершення процесу шифрування. Пам’ятайте, що шифрування гаманця не може повністю захистити ваші біткоіни від кражі, у випадку якщо ваш комп’ютер буде інфіковано шкідливими програмами. + + + + + Warning: The Caps Lock key is on. + Увага: Ввімкнено Caps Lock + + + + + + + Wallet encryption failed + Не вдалося зашифрувати гаманець + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Виникла помилка під час шифрування гаманця. Ваш гаманець не було зашифровано. + + + + + The supplied passphrases do not match. + Введені паролі не співпадають. + + + + Wallet unlock failed + Не вдалося розблокувати гаманець + + + + + + The passphrase entered for the wallet decryption was incorrect. + Введений пароль є невірним. + + + + Wallet decryption failed + Не вдалося розшифрувати гаманець + + + + Wallet passphrase was succesfully changed. + Пароль було успішно змінено. + + + + BitcoinGUI + + + Bitcoin Wallet + Гаманець + + + + Sign &message... + + + + + Show/Hide &Bitcoin + + + + + Synchronizing with network... + Синхронізація з мережею... + + + + &Overview + &Огляд + + + + Show general overview of wallet + Показати загальний огляд гаманця + + + + &Transactions + Пе&реклади + + + + Browse transaction history + Переглянути історію переказів + + + + &Address Book + &Адресна книга + + + + Edit the list of stored addresses and labels + Редагувати список збережених адрес та міток + + + + &Receive coins + О&тримати + + + + Show the list of addresses for receiving payments + Показати список адрес для отримання платежів + + + + &Send coins + В&ідправити + + + + Prove you control an address + Доведіть, що це ваша адреса + + + + E&xit + &Вихід + + + + Quit application + Вийти + + + + &About %1 + П&ро %1 + + + + Show information about Bitcoin + Показати інформацію про Bitcoin + + + + About &Qt + &Про Qt + + + + Show information about Qt + Показати інформацію про Qt + + + + &Options... + &Параметри... + + + + &Encrypt Wallet... + + + + + &Backup Wallet... + + + + + &Change Passphrase... + + + + + ~%n block(s) remaining + + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + + + + + &Export... + &Експорт... + + + + Send coins to a Bitcoin address + + + + + Modify configuration options for Bitcoin + + + + + Show or hide the Bitcoin window + + + + + Export the data in the current tab to a file + Експортувати дані з поточної вкладки в файл + + + + Encrypt or decrypt wallet + Зашифрувати чи розшифрувати гаманець + + + + Backup wallet to another location + Резервне копіювання гаманця в інше місце + + + + Change the passphrase used for wallet encryption + Змінити пароль, який використовується для шифрування гаманця + + + + &Debug window + + + + + Open debugging and diagnostic console + + + + + &Verify message... + + + + + Verify a message signature + + + + + &File + &Файл + + + + &Settings + &Налаштування + + + + &Help + &Довідка + + + + Tabs toolbar + Панель вкладок + + + + Actions toolbar + Панель дій + + + + + [testnet] + [тестова мережа] + + + + + Bitcoin client + + + + + %n active connection(s) to Bitcoin network + %n активне з’єднання з мережею%n активні з’єднання з мережею%n активних з’єднань з мережею + + + + Downloaded %1 blocks of transaction history. + Завантажено %1 блоків історії транзакцій. + + + + %n second(s) ago + %n секунду тому%n секунди тому%n секунд тому + + + + %n minute(s) ago + %n хвилину тому%n хвилини тому%n хвилин тому + + + + %n hour(s) ago + %n годину тому%n години тому%n годин тому + + + + %n day(s) ago + %n день тому%n дня тому%n днів тому + + + + Up to date + Синхронізовано + + + + Catching up... + Синхронізується... + + + + Last received block was generated %1. + Останній отриманий блок було згенеровано %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + Цей переказ перевищує максимально допустимий розмір. Проте ви можете здійснити її, додавши комісію в %1, яка відправиться тим вузлам що оброблять ваш переказ, та допоможе підтримати мережу. Ви хочете додати комісію? + + + + Confirm transaction fee + + + + + Sent transaction + Надіслані перекази + + + + Incoming transaction + Отримані перекази + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + Дата: %1 +Кількість: %2 +Тип: %3 +Адреса: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + <b>Зашифрований</b> гаманець <b>розблоковано</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + <b>Зашифрований</b> гаманець <b>заблоковано</b> + + + + Backup Wallet + Резервне копіювання гаманця + + + + Wallet Data (*.dat) + Дані гаманця (*.dat) + + + + Backup Failed + Резервне копіювання не вдалося + + + + There was an error trying to save the wallet data to the new location. + Виникла помилка при спробі зберегти гаманець в новому місці + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + + + + + ClientModel + + + Network Alert + + + + + DisplayOptionsPage + + + Display + Відображення + + + + default + + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + + + + + User Interface &Language: + + + + + &Unit to show amounts in: + + + + + Choose the default subdivision unit to show in the interface, and when sending coins + Виберіть одиницю вимірювання монет, яка буде відображатись в гаманці та при відправленні. + + + + &Display addresses in transaction list + + + + + Whether to show Bitcoin addresses in the transaction list + + + + + Warning + + + + + This setting will take effect after restarting Bitcoin. + + + + + EditAddressDialog + + + Edit Address + Редагувати адресу + + + + &Label + &Мітка + + + + The label associated with this address book entry + Мітка, пов’язана з цим записом адресної книги + + + + &Address + &Адреса + + + + The address associated with this address book entry. This can only be modified for sending addresses. + Адреса, пов’язана з цим записом адресної книги. + + + + New receiving address + Нова адреса для отримання + + + + New sending address + Нова адреса для відправлення + + + + Edit receiving address + Редагувати адресу для отримання + + + + Edit sending address + Редагувати адресу для відправлення + + + + The entered address "%1" is already in the address book. + Введена адреса «%1» вже присутня в адресній книзі. + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + Could not unlock wallet. + Неможливо розблокувати гаманець. + + + + New key generation failed. + Не вдалося згенерувати нові ключі. + + + + HelpMessageBox + + + + Bitcoin-Qt + + + + + version + + + + + Usage: + Вкористання: + + + + options + + + + + UI options + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + Запускати згорнутим + + + + + Show splash screen on startup (default: 1) + + + + + MainOptionsPage + + + 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. + + + + + Pay transaction &fee + Заплатити комісі&ю + + + + Main + Головні + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Добровільна комісія за кожен Кб переказу, яка дозволяє бути впевненим у тому, що ваш переказ буде оброблено швидко. Розмір більшості переказів рівен 1 Кб. Рекомендована комісія: 0,01. + + + + &Start Bitcoin on system login + + + + + Automatically start Bitcoin after logging in to the system + + + + + &Detach databases at shutdown + + + + + MessagePage + + + Sign Message + + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + Choose adress from address book + Вибрати адресу з адресної книги + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Вставити адресу + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Введіть повідомлення, яке ви хочете підписати тут + + + + Copy the current signature to the system clipboard + + + + + &Copy Signature + + + + + Reset all sign message fields + + + + + Clear &All + + + + + Click "Sign Message" to get signature + Натисніть кнопку "Підписати повідомлення", для отриманя підпису + + + + Sign a message to prove you own this address + Підпишіть повідомлення щоб довести, що ви є власником цієї адреси + + + + &Sign Message + &Підписати повідомлення + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Введіть адресу Bitcoin (наприклад 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + Помилка при підписуванні + + + + %1 is not a valid address. + "%1" не є коректною адресою в мережі Bitcoin. + + + + %1 does not refer to a key. + + + + + Private key for %1 is not available. + Приватний ключ для %1 недоступний. + + + + Sign failed + Не вдалось підписати + + + + NetworkOptionsPage + + + Network + + + + + Map port using &UPnP + Відображення порту через &UPnP + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Автоматично відкривати порт для клієнту біткоін на роутері. Працює лише якщо ваш роутер підтримує UPnP і ця функція увімкнена. + + + + &Connect through SOCKS4 proxy: + Підключатись через &SOCKS4-проксі: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + Підключатись до мережі Bitcoin через SOCKS4-проксі (наприклад при використанні Tor) + + + + Proxy &IP: + + + + + &Port: + + + + + IP address of the proxy (e.g. 127.0.0.1) + IP-адреса проксі-сервера (наприклад 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + Порт проксі-сервера (наприклад 1234) + + + + OptionsDialog + + + Options + Параметри + + + + OverviewPage + + + Form + Форма + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + + + + + Balance: + Баланс: + + + + Number of transactions: + Кількість переказів: + + + + Unconfirmed: + Непідтверджені: + + + + Wallet + + + + + <b>Recent transactions</b> + <b>Недавні перекази</b> + + + + Your current balance + Ваш поточний баланс + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + Загальна сума всіх переказів, які ще не підтверджені, та до сих пір не враховуються в загальному балансі + + + + Total number of transactions in wallet + Загальна кількість переказів в гаманці + + + + + out of sync + + + + + QRCodeDialog + + + QR Code Dialog + + + + + QR Code + QR-Код + + + + Request Payment + Запросити Платіж + + + + Amount: + Кількість: + + + + BTC + BTC + + + + Label: + Мітка: + + + + Message: + Повідомлення: + + + + &Save As... + &Зберегти як... + + + + Error encoding URI into QR Code. + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Save QR Code + + + + + PNG Images (*.png) + PNG-зображення (*.png) + + + + RPCConsole + + + Bitcoin debug window + + + + + Client name + + + + + + + + + + + + + N/A + + + + + Client version + + + + + &Information + + + + + Client + + + + + Startup time + + + + + Network + + + + + Number of connections + + + + + On testnet + + + + + Block chain + + + + + Current number of blocks + + + + + Estimated total blocks + + + + + Last block time + + + + + Debug logfile + + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + + + + + &Open + + + + + &Console + + + + + Build date + + + + + Clear console + + + + + Welcome to the Bitcoin RPC console. + + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + + + Type <b>help</b> for an overview of available commands. + + + + + SendCoinsDialog + + + + + + + + + + Send Coins + Відправити + + + + Send to multiple recipients at once + Відправити на декілька адрес + + + + &Add Recipient + + + + + Remove all transaction fields + Видалити всі поля транзакції + + + + Clear &All + + + + + Balance: + Баланс: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + Підтвердити відправлення + + + + &Send + &Відправити + + + + <b>%1</b> to %2 (%3) + <b>%1</b> адресату %2 (%3) + + + + Confirm send coins + Підтвердіть відправлення + + + + Are you sure you want to send %1? + Ви впевнені що хочете відправити %1 + + + + and + і + + + + The recepient address is not valid, please recheck. + Адреса отримувача невірна, будьласка перепровірте. + + + + The amount to pay must be larger than 0. + Кількість монет для відправлення повинна бути більшою 0. + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found, can only send to each address once per send operation. + + + + + Error: Transaction creation failed. + + + + + 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. + + + + + SendCoinsEntry + + + Form + Форма + + + + A&mount: + &Кількість: + + + + Pay &To: + &Отримувач: + + + + + Enter a label for this address to add it to your address book + Введіть мітку для цієї адреси для додавання її в адресну книгу + + + + &Label: + &Мітка: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Адреса для отримувача платежу (наприклад, 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + Вибрати адресу з адресної книги + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Вставити адресу + + + + Alt+P + Alt+P + + + + Remove this recipient + Видалити цього отримувача + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + Введіть адресу Bitcoin (наприклад 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + Відкрити для %1 блоків + + + + Open until %1 + Відкрити до %1 + + + + %1/offline? + %1/поза інтернетом? + + + + %1/unconfirmed + %1/не підтверджено + + + + %1 confirmations + %1 підтверджень + + + + <b>Status:</b> + <b>Статус:</b> + + + + , has not been successfully broadcast yet + , ще не було успішно розіслано + + + + , broadcast through %1 node + , розіслано через %1 вузол + + + + , broadcast through %1 nodes + , розіслано через %1 вузлів + + + + <b>Date:</b> + <b>Дата:</b> + + + + <b>Source:</b> Generated<br> + <b>Джерело:</b> згенеровано<br> + + + + + <b>From:</b> + <b>Відправник:</b> + + + + unknown + невідомий + + + + + + <b>To:</b> + <b>Одержувач:</b> + + + + (yours, label: + (Ваша, мітка: + + + + (yours) + (ваша) + + + + + + + <b>Credit:</b> + <b>Кредит:</b> + + + + (%1 matures in %2 more blocks) + (%1 «дозріє» через %2 блоків) + + + + (not accepted) + (не прийнято) + + + + + + <b>Debit:</b> + <b>Дебет:</b> + + + + <b>Transaction fee:</b> + <b>Комісія за переказ:</b> + + + + <b>Net amount:</b> + <b>Загальна сума:</b> + + + + Message: + Повідомлення: + + + + Comment: + Коментар: + + + + Transaction ID: + ID транзакції: + + + + 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. + Після генерації монет, потрібно зачекати 120 блоків, перш ніж їх можна буде використати. Коли ви згенерували цей блок, його було відправлено в мережу для того, щоб він був доданий до ланцюжка блоків. Якщо ця процедура не вдасться, статус буде змінено на «не підтверджено» і ви не зможете потратити згенеровані монету. Таке може статись, якщо хтось інший згенерував блок на декілька секунд раніше. + + + + TransactionDescDialog + + + Transaction details + Деталі переказів + + + + This pane shows a detailed description of the transaction + Даний діалог показує детальну статистику по вибраному переказу + + + + TransactionTableModel + + + Date + Дата + + + + Type + Тип + + + + Address + Адреса + + + + Amount + Кількість + + + + Open for %n block(s) + Відкрити для %n блокуВідкрити для %n блоківВідкрити для %n блоків + + + + Open until %1 + Відкрити до %1 + + + + Offline (%1 confirmations) + Поза інтернетом (%1 підтверджень) + + + + Unconfirmed (%1 of %2 confirmations) + Непідтверджено (%1 із %2 підтверджень) + + + + Confirmed (%1 confirmations) + Підтверджено (%1 підтверджень) + + + + Mined balance will be available in %n more blocks + Добутими монетами можна буде скористатись через %n блокДобутими монетами можна буде скористатись через %n блокиДобутими монетами можна буде скористатись через %n блоків + + + + This block was not received by any other nodes and will probably not be accepted! + Цей блок не був отриманий жодними іншими вузлами і, ймовірно, не буде прийнятий! + + + + Generated but not accepted + Згенеровано, але не підтверджено + + + + Received with + Отримано + + + + Received from + Отримано від + + + + Sent to + Відправлено + + + + Payment to yourself + Відправлено собі + + + + Mined + Добуто + + + + (n/a) + (недоступно) + + + + Transaction status. Hover over this field to show number of confirmations. + Статус переказу. Наведіть вказівник на це поле, щоб показати кількість підтверджень. + + + + Date and time that the transaction was received. + Дата і час, коли переказ було отримано. + + + + Type of transaction. + Тип переказу. + + + + Destination address of transaction. + Адреса отримувача + + + + Amount removed from or added to balance. + Сума, додана чи знята з балансу. + + + + TransactionView + + + + All + Всі + + + + Today + Сьогодні + + + + This week + На цьому тижні + + + + This month + На цьому місяці + + + + Last month + Минулого місяця + + + + This year + Цього року + + + + Range... + Проміжок + + + + Received with + Отримані на + + + + Sent to + Відправлені на + + + + To yourself + Відправлені собі + + + + Mined + Добуті + + + + Other + Інше + + + + Enter address or label to search + Введіть адресу чи мітку для пошуку + + + + Min amount + Мінімальна сума + + + + Copy address + Скопіювати адресу + + + + Copy label + Скопіювати мітку + + + + Copy amount + Копіювати кількість + + + + Edit label + Редагувати мітку + + + + Show transaction details + + + + + Export Transaction Data + Експортувати дані переказів + + + + Comma separated file (*.csv) + Файли, розділені комою (*.csv) + + + + Confirmed + Підтверджені + + + + Date + Дата + + + + Type + Тип + + + + Label + Мітка + + + + Address + Адреса + + + + Amount + Кількість + + + + ID + Ідентифікатор + + + + Error exporting + Помилка експорту + + + + Could not write to file %1. + Неможливо записати у файл %1 + + + + Range: + Діапазон від: + + + + to + до + + + + VerifyMessageDialog + + + Verify Signed Message + + + + + 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. + + + + + Verify a message and obtain the Bitcoin address used to sign the message + + + + + &Verify Message + + + + + Copy the currently selected address to the system clipboard + Копіювати виділену адресу в буфер обміну + + + + &Copy Address + + + + + Reset all verify message fields + + + + + Clear &All + + + + + Enter Bitcoin signature + + + + + Click "Verify Message" to obtain address + + + + + + Invalid Signature + + + + + The signature could not be decoded. Please check the signature and try again. + + + + + The signature did not match the message digest. Please check the signature and try again. + + + + + Address not found in address book. + + + + + Address found in address book: %1 + + + + + WalletModel + + + Sending... + Відправка... + + + + WindowOptionsPage + + + Window + + + + + &Minimize to the tray instead of the taskbar + Мінімізувати &у трей + + + + Show only a tray icon after minimizing the window + Показувати лише іконку в треї після згортання вікна + + + + M&inimize on close + + + + + 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. + Згортати замість закриття. Якщо ця опція включена, програма закриється лише після вибору відповідного пункту в меню. + + + + bitcoin-core + + + Bitcoin version + Версія + + + + Usage: + Вкористання: + + + + Send command to -server or bitcoind + Відправити команду серверу -server чи демону + + + + + List commands + Список команд + + + + + Get help for a command + Отримати довідку по команді + + + + + Options: + Параметри: + + + + + Specify configuration file (default: bitcoin.conf) + Вкажіть файл конфігурації (за промовчуванням: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + Вкажіть pid-файл (за промовчуванням: bitcoind.pid) + + + + + Generate coins + Генерувати монети + + + + + Don't generate coins + Не генерувати монети + + + + + Specify data directory + Вкажіть робочий каталог + + + + + Set database cache size in megabytes (default: 25) + + + + + Set database disk log size in megabytes (default: 100) + + + + + Specify connection timeout (in milliseconds) + Вкажіть таймаут з’єднання (в мілісекундах) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + Чекати на з'єднання на порту (по замовченню 8333 або тестова мережа 18333) + + + + Maintain at most <n> connections to peers (default: 125) + Підтримувати не більше <n> зв'язків з колегами (за замовчуванням: 125) + + + + Connect only to the specified node + Підключитись лише до вказаного вузла + + + + + Connect to a node to retrieve peer addresses, and disconnect + + + + + Specify your own public address + + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + + + + + Try to discover public IP address (default: 1) + + + + + Bind to given address. Use [host]:port notation for IPv6 + + + + + Threshold for disconnecting misbehaving peers (default: 100) + Поріг відключення неправильно підєднаних пірів (за замовчуванням: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Максимальній розмір вхідного буферу на одне з'єднання (за замовчуванням 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Максимальоий буфер , <n> * 1000 байт (за умовчанням: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Максимальній розмір виіхідного буферу на одне з'єднання (за замовчуванням 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + + + + + Accept command line and JSON-RPC commands + Приймати команди із командного рядка та команди JSON-RPC + + + + + Run in the background as a daemon and accept commands + Запустити в фоновому режимі (як демон) та приймати команди + + + + + Use the test network + Використовувати тестову мережу + + + + + Output extra debugging information + Виводити більше налагоджувальної інформації + + + + Prepend debug output with timestamp + Доповнювати налагоджувальний вивід відміткою часу + + + + Send trace/debug info to console instead of debug.log file + Відсилаті налагоджувальну інформацію на консоль, а не у файл debug.log + + + + Send trace/debug info to debugger + Відсилаті налагоджувальну інформацію до налагоджувача + + + + Username for JSON-RPC connections + Ім’я користувача для JSON-RPC-з’єднань + + + + + Password for JSON-RPC connections + Пароль для JSON-RPC-з’єднань + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + Прослуховувати <port> для JSON-RPC-з’єднань (за промовчуванням: 8332) + + + + + Allow JSON-RPC connections from specified IP address + Дозволити JSON-RPC-з’єднання з вказаної IP-адреси + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + Відправляти команди на вузол, запущений на <ip> (за промовчуванням: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + + + Upgrade wallet to latest format + + + + + Set key pool size to <n> (default: 100) + Встановити розмір пулу ключів <n> (за промовчуванням: 100) + + + + + Rescan the block chain for missing wallet transactions + Пересканувати ланцюжок блоків, в пошуку втрачених переказів + + + + + How many blocks to check at startup (default: 2500, 0 = all) + + + + + How thorough the block verification is (0-6, default: 1) + + + + + Imports blocks from external blk000?.dat file + + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +Параметри SSL: (див. Bitcoin Wiki) + + + + + Use OpenSSL (https) for JSON-RPC connections + Використовувати OpenSSL (https) для JSON-RPC-з’єднань + + + + + Server certificate file (default: server.cert) + Сертифікату сервера (за промовчуванням: server.cert) + + + + + Server private key (default: server.pem) + Закритий ключ сервера (за промовчуванням: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Допустимі шифри (за промовчуванням: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + + + + + This help message + Дана довідка + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + Неможливо встановити блокування на робочий каталог %s. Можливо, гаманець вже запущено. + + + + Bitcoin + Bitcoin + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + + + + + Connect through socks proxy + + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + + + + + Allow DNS lookups for -addnode, -seednode and -connect + + + + + Pass DNS requests to (SOCKS5) proxy + + + + + Loading addresses... + Завантаження адрес... + + + + Error loading blkindex.dat + Помилка при завантаженні blkindex.dat + + + + Error loading wallet.dat: Wallet corrupted + Помилка при завантаженні wallet.dat: Гаманець пошкоджено + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + Помилка при завантаженні wallet.dat: Гаманець потребує новішої версії Біткоін-клієнта + + + + Wallet needed to be rewritten: restart Bitcoin to complete + Потрібно перезаписати гаманець: перезапустіть Біткоін-клієнт для завершення + + + + Error loading wallet.dat + Помилка при завантаженні wallet.dat + + + + Invalid -proxy address: '%s' + + + + + Unknown network specified in -noproxy: '%s' + + + + + Unknown network specified in -onlynet: '%s' + + + + + Unknown -socks proxy version requested: %i + + + + + Cannot resolve -bind address: '%s' + + + + + Not listening on any port + + + + + Cannot resolve -externalip address: '%s' + + + + + Invalid amount for -paytxfee=<amount>: '%s' + + + + + Error: could not start node + + + + + Error: Wallet locked, unable to create transaction + + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + + + + + Error: Transaction creation failed + Помилка: не вдалося створити переказ + + + + Sending... + Відправлення... + + + + 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. + Помилка: переказ було відхилено. Це може статись, якщо декілька монет з вашого гаманця вже використані, наприклад, якщо ви використовуєте одну копію гаманця (wallet.dat), а монети були використані з іншої копії, але не позначені як використані в цій. + + + + Invalid amount + + + + + Insufficient funds + Недостатньо коштів + + + + Loading block index... + Завантаження індексу блоків... + + + + Add a node to connect to and attempt to keep the connection open + + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + + + + + Find peers using internet relay chat (default: 0) + + + + + Accept connections from outside (default: 1) + + + + + Find peers using DNS lookup (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 1) + + + + + Use Universal Plug and Play to map the listening port (default: 0) + + + + + Fee per KB to add to transactions you send + Комісія за Кб + + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + + + + + Loading wallet... + Завантаження гаманця... + + + + Cannot downgrade wallet + + + + + Cannot initialize keypool + + + + + Cannot write default address + + + + + Rescanning... + Сканування... + + + + Done loading + Завантаження завершене + + + + To use the %s option + + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + + + + + Error + + + + + An error occured while setting up the RPC port %i for listening: %s + + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + Увага: будь ласка, перевірте дату і час на свому комп’ютері. Якщо ваш годинник йде неправильно, Bitcoin може працювати некоректно. + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts new file mode 100644 index 0000000..087e19b --- /dev/null +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -0,0 +1,2547 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + 关于比特币 + + + + <b>Bitcoin</b> version + <b>比特币</b>版本 + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + 版权归比特币开发者所有 © 2009-2012 + +这是一个实验性软件。 + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + + + + AddressBookPage + + + Address Book + 地址薄 + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + 这些是你接受支付的比特币地址。当支付时你可以给出不同的地址,以便追踪不同的支付者。 + + + + Double-click to edit address or label + 双击以编辑地址或标签 + + + + Create a new address + 创建新地址 + + + + Copy the currently selected address to the system clipboard + 复制当前选中地址到系统剪贴板 + + + + &New Address + &新建地址 + + + + &Copy Address + &复制地址 + + + + Show &QR Code + 显示二维码 + + + + Sign a message to prove you own this address + 发送签名消息以证明您是该比特币地址的拥有者 + + + + &Sign Message + &发送签名消息 + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + 从列表中删除当前选中地址。只有发送地址可以被删除。 + + + + &Delete + &删除 + + + + Copy &Label + 复制 &标签 + + + + &Edit + &编辑 + + + + Export Address Book Data + 导出地址薄数据 + + + + Comma separated file (*.csv) + 逗号分隔文件 (*.csv) + + + + Error exporting + 导出错误 + + + + Could not write to file %1. + 无法写入文件 %1。 + + + + AddressTableModel + + + Label + 标签 + + + + Address + 地址 + + + + (no label) + (没有标签) + + + + AskPassphraseDialog + + + Passphrase Dialog + 密码对话框 + + + + Enter passphrase + 输入口令 + + + + New passphrase + 新口令 + + + + Repeat new passphrase + 重复新口令 + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + 输入钱包的新口令。<br/>使用的口令请至少包含<b>10个以上随机字符</>,或者是<b>8个以上的单词</b>。 + + + + Encrypt wallet + 加密钱包 + + + + This operation needs your wallet passphrase to unlock the wallet. + 该操作需要您首先使用口令解锁钱包。 + + + + Unlock wallet + 解锁钱包 + + + + This operation needs your wallet passphrase to decrypt the wallet. + 该操作需要您首先使用口令解密钱包。 + + + + Decrypt wallet + 解密钱包 + + + + Change passphrase + 修改口令 + + + + Enter the old and new passphrase to the wallet. + 请输入钱包的旧口令与新口令。 + + + + Confirm wallet encryption + 确认加密钱包 + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + 警告:如果您加密了您的钱包之后忘记了口令,您将会<b>失去所有的比特币</b>! +确定要加密钱包吗? + + + + + Wallet encrypted + 钱包已加密 + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + 将关闭软件以完成加密过程。 请您谨记:钱包加密并不是万能的,电脑中毒,您的比特币还是有可能丢失。 + + + + + Warning: The Caps Lock key is on. + 警告:大写锁定键CapsLock开启 + + + + + + + Wallet encryption failed + 钱包加密失败 + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + 由于一个本地错误,加密钱包操作已经失败。您的钱包没有被加密。 + + + + + The supplied passphrases do not match. + 口令不匹配。 + + + + Wallet unlock failed + 钱包解锁失败 + + + + + + The passphrase entered for the wallet decryption was incorrect. + 用于解密钱包的口令不正确。 + + + + Wallet decryption failed + 钱包解密失败。 + + + + Wallet passphrase was succesfully changed. + 钱包口令修改成功 + + + + BitcoinGUI + + + Bitcoin Wallet + 比特币钱包 + + + + Sign &message... + 对&消息签名... + + + + Show/Hide &Bitcoin + 显示/隐藏 比特币客户端 + + + + Synchronizing with network... + 正在与网络同步... + + + + &Overview + &概况 + + + + Show general overview of wallet + 显示钱包概况 + + + + &Transactions + &交易 + + + + Browse transaction history + 查看交易历史 + + + + &Address Book + &地址薄 + + + + Edit the list of stored addresses and labels + 修改存储的地址和标签列表 + + + + &Receive coins + &接收货币 + + + + Show the list of addresses for receiving payments + 显示接收支付的地址列表 + + + + &Send coins + &发送货币 + + + + Prove you control an address + 证明您拥有某个比特币地址 + + + + E&xit + 退出 + + + + Quit application + 退出程序 + + + + &About %1 + &关于 %1 + + + + Show information about Bitcoin + 显示比特币的相关信息 + + + + About &Qt + 关于 &Qt + + + + Show information about Qt + 显示Qt相关信息 + + + + &Options... + &选项... + + + + &Encrypt Wallet... + &加密钱包... + + + + &Backup Wallet... + &备份钱包... + + + + &Change Passphrase... + &修改密码... + + + + ~%n block(s) remaining + ~还剩 %n 个区块 + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + 已下载 %2 个交易历史区块中的 %1 个 (完成率 %3% ). + + + + &Export... + &导出... + + + + Send coins to a Bitcoin address + 向一个比特币地址发送比特币 + + + + Modify configuration options for Bitcoin + 设置选项 + + + + Show or hide the Bitcoin window + 显示或隐藏比特币客户端窗口 + + + + Export the data in the current tab to a file + 导出当前数据到文件 + + + + Encrypt or decrypt wallet + 加密或解密钱包 + + + + Backup wallet to another location + 备份钱包到其它文件夹 + + + + Change the passphrase used for wallet encryption + 修改钱包加密口令 + + + + &Debug window + &调试窗口 + + + + Open debugging and diagnostic console + 在诊断控制台调试 + + + + &Verify message... + &验证消息... + + + + Verify a message signature + 验证签名消息 + + + + &File + &文件 + + + + &Settings + &设置 + + + + &Help + &帮助 + + + + Tabs toolbar + 分页工具栏 + + + + Actions toolbar + 动作工具栏 + + + + + [testnet] + [testnet] + + + + + Bitcoin client + 比特币客户端 + + + + %n active connection(s) to Bitcoin network + %n 个到比特币网络的活动连接 + + + + Downloaded %1 blocks of transaction history. + %1 个交易历史的区块已下载 + + + + %n second(s) ago + %n 秒前 + + + + %n minute(s) ago + %n 分种前 + + + + %n hour(s) ago + %n 小时前 + + + + %n day(s) ago + %n 天前 + + + + Up to date + 最新状态 + + + + Catching up... + 更新中... + + + + Last received block was generated %1. + 最新收到的区块产生于 %1。 + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + 该笔交易的数据量超限.您可以选择支付 %1 交易费, 交易费将支付给处理该笔交易的网络节点,有助于维持比特币网络的运行. 您愿意支付交易费用吗? + + + + Confirm transaction fee + 确认交易费 + + + + Sent transaction + 已发送交易 + + + + Incoming transaction + 流入交易 + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + 日期: %1 +金额: %2 +类别: %3 +地址: %4 + + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + 钱包已被<b>加密</b>,当前为<b>解锁</b>状态 + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + 钱包已被<b>加密</b>,当前为<b>锁定</b>状态 + + + + Backup Wallet + 备份钱包 + + + + Wallet Data (*.dat) + 钱包文件(*.dat) + + + + Backup Failed + 备份失败 + + + + There was an error trying to save the wallet data to the new location. + 备份钱包到其它文件夹失败. + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + 发生致命错误. 比特币客户端的安全存在问题,将退出. + + + + ClientModel + + + Network Alert + 网络警报 + + + + DisplayOptionsPage + + + Display + 查看 + + + + default + 缺省 + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + 设置语言选项。需重启客户端软件才能生效。 + + + + User Interface &Language: + &语言: + + + + &Unit to show amounts in: + &比特币金额单位: + + + + Choose the default subdivision unit to show in the interface, and when sending coins + 选择显示及发送比特币时使用的最小单位 + + + + &Display addresses in transaction list + 在交易清单中&显示比特币地址 + + + + Whether to show Bitcoin addresses in the transaction list + 是否在交易清单中显示比特币地址 + + + + Warning + 警告 + + + + This setting will take effect after restarting Bitcoin. + 需要重启客户端软件才能生效。 + + + + EditAddressDialog + + + Edit Address + 编辑地址 + + + + &Label + &标签 + + + + The label associated with this address book entry + 与此地址条目关联的标签 + + + + &Address + &地址 + + + + The address associated with this address book entry. This can only be modified for sending addresses. + 该地址与地址簿中的条目已关联,无法作为发送地址编辑。 + + + + New receiving address + 新接收地址 + + + + New sending address + 新发送地址 + + + + Edit receiving address + 编辑接收地址 + + + + Edit sending address + 编辑发送地址 + + + + The entered address "%1" is already in the address book. + 输入的地址 "%1" 已经存在于地址薄。 + + + + The entered address "%1" is not a valid Bitcoin address. + 您输入的 "%1" 不是合法的比特币地址. + + + + Could not unlock wallet. + 无法解锁钱包 + + + + New key generation failed. + 密钥创建失败. + + + + HelpMessageBox + + + + Bitcoin-Qt + Bitcoin-Qt + + + + version + 版本 + + + + Usage: + 使用: + + + + options + 选项 + + + + UI options + UI选项 + + + + Set language, for example "de_DE" (default: system locale) + 设置语言, 例如 "de_DE" (缺省: 系统语言) + + + + Start minimized + 启动时最小化 + + + + + Show splash screen on startup (default: 1) + 启动时显示版权页 (缺省: 1) + + + + MainOptionsPage + + + 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. + 关闭时分开区块数据库和地址数据库. 这意味着您可以将数据库文件移动至其他文件夹. 钱包文件始终是分开的. + + + + Pay transaction &fee + 支付交易 &费用 + + + + Main + 主选项 + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + 建议支付交易费用,有助于您的交易得到尽快处理. 绝大多数交易的字节数为 1 kB. 建议支付0.01个比特币. + + + + &Start Bitcoin on system login + 启动时&运行 + + + + Automatically start Bitcoin after logging in to the system + 系统启动后自动运行比特币客户端软件 + + + + &Detach databases at shutdown + &关闭客户端时分离数据库 + + + + MessagePage + + + Sign Message + 对消息签名 + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + 您可以用你的地址对消息进行签名,以证明您是该地址的所有人。注意不要对模棱两可的消息签名,以免遭受钓鱼式攻击。请确保消息真实明确的表达了您的意愿。 + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + 用来签名的比特币地址 (例如 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + 从地址簿选择地址 + + + + Alt+A + Alt+A + + + + Paste address from clipboard + 从剪贴板粘贴地址 + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + 请输入您要发送的签名消息 + + + + Copy the current signature to the system clipboard + 复制当前签名至剪切板 + + + + &Copy Signature + &复制签名 + + + + Reset all sign message fields + 清空所有签名消息栏 + + + + Clear &All + 清除 &所有 + + + + Click "Sign Message" to get signature + 单击“发送签名消息"获取签名 + + + + Sign a message to prove you own this address + 发送签名消息以证明您是该比特币地址的拥有者 + + + + &Sign Message + &发送签名消息 + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + 请输入比特币地址 (例如: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + 签名错误 + + + + %1 is not a valid address. + %1 不是合法的比特币地址。 + + + + %1 does not refer to a key. + %1 找不到相关的钥匙. + + + + Private key for %1 is not available. + %1 的秘钥不可用。 + + + + Sign failed + 签名失败 + + + + NetworkOptionsPage + + + Network + 网络 + + + + Map port using &UPnP + 使用 &UPnP 映射端口 + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + 自动在路由器中打开比特币端口。只有当您的路由器开启 UPnP 选项时此功能才有效。 + + + + &Connect through SOCKS4 proxy: + &通过SOCKS4代理连接 + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + 通过一个SOCKS4代理连接到比特币网络 (如使用Tor连接时) + + + + Proxy &IP: + 代理服务器&IP: + + + + &Port: + &端口: + + + + IP address of the proxy (e.g. 127.0.0.1) + 代理服务器IP (如 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + 代理端口 (比如 1234) + + + + OptionsDialog + + + Options + 选项 + + + + OverviewPage + + + Form + 表单 + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + 现在显示的消息可能是过期的. 在连接上比特币网络节点后,您的钱包将自动与网络同步,但是这个过程还没有完成. + + + + Balance: + 余额 + + + + Number of transactions: + 交易笔数 + + + + Unconfirmed: + 未确认: + + + + Wallet + 钱包 + + + + <b>Recent transactions</b> + <b>当前交易</b> + + + + Your current balance + 您的当前余额 + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + 尚未确认的交易总额, 未计入当前余额 + + + + Total number of transactions in wallet + 钱包总交易数量 + + + + + out of sync + 来自同步过程 + + + + QRCodeDialog + + + QR Code Dialog + 二维码对话框 + + + + QR Code + 二维码 + + + + Request Payment + 请求付款 + + + + Amount: + 金额: + + + + BTC + BTC + + + + Label: + 标签: + + + + Message: + 消息: + + + + &Save As... + &另存为 + + + + Error encoding URI into QR Code. + 将 URI 转换成二维码失败. + + + + Resulting URI too long, try to reduce the text for label / message. + URI 太长, 请试着精简标签/消息的内容. + + + + Save QR Code + 保存二维码 + + + + PNG Images (*.png) + PNG图像文件(*.png) + + + + RPCConsole + + + Bitcoin debug window + 调试窗口 + + + + Client name + 客户端名称 + + + + + + + + + + + + N/A + 不可用 + + + + Client version + 客户端版本 + + + + &Information + &信息 + + + + Client + 客户端 + + + + Startup time + 启动时间 + + + + Network + 网络 + + + + Number of connections + 连接数 + + + + On testnet + 当前为比特币测试网络 + + + + Block chain + 区块链 + + + + Current number of blocks + 当前区块数 + + + + Estimated total blocks + 预计区块数 + + + + Last block time + 上一区块时间 + + + + Debug logfile + 调试日志文件 + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + 在当前数据目录打开调试日志文件. 大文件,需要等待几秒. + + + + &Open + &打开 + + + + &Console + &控制台 + + + + Build date + 创建时间 + + + + Clear console + 清空控制台 + + + + Welcome to the Bitcoin RPC console. + 欢迎来到 RPC 控制台. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + 使用上下方向键浏览历史, <b>Ctrl-L</b>清除屏幕. + + + + Type <b>help</b> for an overview of available commands. + 使用 <b>help</b> 命令显示帮助信息. + + + + SendCoinsDialog + + + + + + + + + + Send Coins + 发送货币 + + + + Send to multiple recipients at once + 一次发送给多个接收者 + + + + &Add Recipient + &添加接收人 + + + + Remove all transaction fields + 移除所有交易项 + + + + Clear &All + 清除 &所有 + + + + Balance: + 余额 + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + 确认并发送货币 + + + + &Send + &发送 + + + + <b>%1</b> to %2 (%3) + <b>%1</b> 到 %2 (%3) + + + + Confirm send coins + 确认发送货币 + + + + Are you sure you want to send %1? + 确定您要发送 %1? + + + + and + + + + + The recepient address is not valid, please recheck. + 接收者地址不合法,请检查。 + + + + The amount to pay must be larger than 0. + 支付金额必须大于0. + + + + The amount exceeds your balance. + 金额超出您的账上余额 + + + + The total exceeds your balance when the %1 transaction fee is included. + 计入 %1 交易费后的金额超出您的账上余额. + + + + Duplicate address found, can only send to each address once per send operation. + 发现重复的地址, 每次只能对同一地址发送一次. + + + + Error: Transaction creation failed. + 错误: 创建交易失败. + + + + 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. + 错误: 交易被拒绝. 如果您使用的是备份钱包,可能存在两个钱包不同步的情况,另一个钱包中的比特币已经被使用,但本地的这个钱包尚没有记录。 + + + + SendCoinsEntry + + + Form + 表单 + + + + A&mount: + 金额 + + + + Pay &To: + 支付 &到: + + + + + Enter a label for this address to add it to your address book + 为这个地址输入一个标签,以便将它添加到您的地址簿 + + + + &Label: + &标签: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + 付款地址 (例如: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + 从地址薄选择地址 + + + + Alt+A + Alt+A + + + + Paste address from clipboard + 从剪贴板粘贴地址 + + + + Alt+P + Alt+P + + + + Remove this recipient + 移除此接收者 + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + 请输入比特币地址 (例如: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + 开启 %1 个数据块 + + + + Open until %1 + 至 %1 个数据块时开启 + + + + %1/offline? + %1/离线? + + + + %1/unconfirmed + %1/未确认 + + + + %1 confirmations + %1 确认项 + + + + <b>Status:</b> + <b>状态:</b> + + + + , has not been successfully broadcast yet + , 未被成功广播 + + + + , broadcast through %1 node + ,同过 %1 节点广播 + + + + , broadcast through %1 nodes + ,同过 %1 节点组广播 + + + + <b>Date:</b> + <b>日期:</b> + + + + <b>Source:</b> Generated<br> + <b>来源:</b> 生成<br> + + + + + <b>From:</b> + <b>从:</b> + + + + unknown + 未知 + + + + + + <b>To:</b> + <b>到:</b> + + + + (yours, label: + (您的, 标签: + + + + (yours) + (您的) + + + + + + + <b>Credit:</b> + <b>到帐:</b> + + + + (%1 matures in %2 more blocks) + (%1 成熟于 %2 以上数据块) + + + + (not accepted) + (未接受) + + + + + + <b>Debit:</b> + 支出 + + + + <b>Transaction fee:</b> + 交易费 + + + + <b>Net amount:</b> + <b>网络金额:</b> + + + + Message: + 消息: + + + + Comment: + 备注 + + + + Transaction ID: + 交易ID: + + + + 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. + 新生产的比特币必须等待120个数据块之后才能被使用. 当您生产出此数据块,它将被广播至比特币网络并添加至数据链. 如果添加到数据链失败, 它的状态将变成"不被接受",生产的比特币将不能使用. 在您生产新数据块的几秒钟内, 如果其它节点也生产出同样的数据块,有可能会发生这种情况. + + + + TransactionDescDialog + + + Transaction details + 交易细节 + + + + This pane shows a detailed description of the transaction + 当前面板显示了交易的详细描述 + + + + TransactionTableModel + + + Date + 日期 + + + + Type + 类型 + + + + Address + 地址 + + + + Amount + 数量 + + + + Open for %n block(s) + 开启 %n 个数据块 + + + + Open until %1 + 至 %1 个数据块时开启 + + + + Offline (%1 confirmations) + 离线 (%1 个确认项) + + + + Unconfirmed (%1 of %2 confirmations) + 未确认 (%1 / %2 条确认信息) + + + + Confirmed (%1 confirmations) + 已确认 (%1 条确认信息) + + + + Mined balance will be available in %n more blocks + 挖矿所得将在 %n 个数据块之后可用 + + + + This block was not received by any other nodes and will probably not be accepted! + 此区块未被其他节点接收,并可能不被接受! + + + + Generated but not accepted + 已生成但未被接受 + + + + Received with + 接收于 + + + + Received from + 收款来自 + + + + Sent to + 发送到 + + + + Payment to yourself + 付款给自己 + + + + Mined + 挖矿所得 + + + + (n/a) + (n/a) + + + + Transaction status. Hover over this field to show number of confirmations. + 交易状态。 鼠标移到此区域上可显示确认消息项的数目。 + + + + Date and time that the transaction was received. + 接收交易的时间 + + + + Type of transaction. + 交易类别。 + + + + Destination address of transaction. + 交易目的地址。 + + + + Amount removed from or added to balance. + 从余额添加或移除的金额 + + + + TransactionView + + + + All + 全部 + + + + Today + 今天 + + + + This week + 本周 + + + + This month + 本月 + + + + Last month + 上月 + + + + This year + 今年 + + + + Range... + 范围... + + + + Received with + 接收于 + + + + Sent to + 发送到 + + + + To yourself + 到自己 + + + + Mined + 挖矿所得 + + + + Other + 其他 + + + + Enter address or label to search + 输入地址或标签进行搜索 + + + + Min amount + 最小金额 + + + + Copy address + 复制地址 + + + + Copy label + 复制标签 + + + + Copy amount + 复制金额 + + + + Edit label + 编辑标签 + + + + Show transaction details + 显示交易详情 + + + + Export Transaction Data + 导出交易数据 + + + + Comma separated file (*.csv) + 逗号分隔文件(*.csv) + + + + Confirmed + 已确认 + + + + Date + 日期 + + + + Type + 类别 + + + + Label + 标签 + + + + Address + 地址 + + + + Amount + 金额 + + + + ID + ID + + + + Error exporting + 导出错误 + + + + Could not write to file %1. + 无法写入文件 %1。 + + + + Range: + 范围: + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + 验证签名消息 + + + + 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. + 请在下面输入消息和签名 (注意不要遗漏换行、空格和缩进符这些看不见的字符) 获取用来签名的比特币地址. + + + + Verify a message and obtain the Bitcoin address used to sign the message + 验证消息并获取用来签名的比特币地址 + + + + &Verify Message + &验证消息 + + + + Copy the currently selected address to the system clipboard + 复制当前选中地址到系统剪贴板 + + + + &Copy Address + &复制地址 + + + + Reset all verify message fields + 清空所有验证消息栏 + + + + Clear &All + 清除 &所有 + + + + Enter Bitcoin signature + 输入比特币签名 + + + + Click "Verify Message" to obtain address + 单击 "验证消息" 获取比特币地址 + + + + + Invalid Signature + 非法签名 + + + + The signature could not be decoded. Please check the signature and try again. + 签名无法解码. 请检查签名后再试一次. + + + + The signature did not match the message digest. Please check the signature and try again. + 签名和消息摘要不吻合.请检查签名后再试一次. + + + + Address not found in address book. + 地址簿中找不到该地址. + + + + Address found in address book: %1 + 地址簿中找不到该地址: %1 + + + + WalletModel + + + Sending... + 发送中... + + + + WindowOptionsPage + + + Window + 窗口 + + + + &Minimize to the tray instead of the taskbar + &最小化到托盘 + + + + Show only a tray icon after minimizing the window + 最小化窗口后只显示一个托盘标志 + + + + M&inimize on close + 单击关闭按钮时&最小化 + + + + 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. + 当窗口关闭时程序最小化而不是退出。当使用该选项时,程序只能通过在菜单中选择退出来关闭 + + + + bitcoin-core + + + Bitcoin version + 比特币版本 + + + + Usage: + 使用: + + + + Send command to -server or bitcoind + 发送命令到服务器或者 bitcoind + + + + + List commands + 列出命令 + + + + + Get help for a command + 获得某条命令的帮助 + + + + + Options: + 选项: + + + + + Specify configuration file (default: bitcoin.conf) + 指定配置文件 (默认为 bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + 指定 pid 文件 (默认为 bitcoind.pid) + + + + + Generate coins + 生成货币 + + + + + Don't generate coins + 不要生成货币 + + + + + Specify data directory + 指定数据目录 + + + + + Set database cache size in megabytes (default: 25) + 设置数据库缓冲区大小 (缺省: 25MB) + + + + Set database disk log size in megabytes (default: 100) + 设置数据库磁盘日志大小 (缺省: 100MB) + + + + Specify connection timeout (in milliseconds) + 指定连接超时时间 (微秒) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + 监听端口连接 <port> (缺省: 8333 or testnet: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + 最大连接数 <n> (缺省: 125) + + + + Connect only to the specified node + 只连接到指定节点 + + + + + Connect to a node to retrieve peer addresses, and disconnect + 连接一个节点并获取对端地址, 然后断开连接 + + + + Specify your own public address + 指定您的公共地址 + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + 仅连接指定网络中的节点 <net> (IPv4 or IPv6) + + + + Try to discover public IP address (default: 1) + 尝试发现公共IP地址 (缺省: 1) + + + + Bind to given address. Use [host]:port notation for IPv6 + 绑定指定地址. IPv6 使用 [host]:port + + + + Threshold for disconnecting misbehaving peers (default: 100) + Threshold for disconnecting misbehaving peers (缺省: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + Number of seconds to keep misbehaving peers from reconnecting (缺省: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + Maximum per-connection receive buffer, <n>*1000 bytes (缺省: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + Maximum per-connection send buffer, <n>*1000 bytes (缺省: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + 分离区块数据库和地址数据库. 会延升关闭时间 (缺省: 0) + + + + Accept command line and JSON-RPC commands + 接受命令行和 JSON-RPC 命令 + + + + + Run in the background as a daemon and accept commands + 在后台运行并接受命令 + + + + + + Use the test network + 使用测试网络 + + + + + Output extra debugging information + 输出调试信息 + + + + Prepend debug output with timestamp + 为调试输出信息添加时间戳 + + + + Send trace/debug info to console instead of debug.log file + 跟踪/调试信息输出到控制台,不输出到debug.log文件 + + + + Send trace/debug info to debugger + 跟踪/调试信息输出到 调试器debugger + + + + Username for JSON-RPC connections + JSON-RPC连接用户名 + + + + + Password for JSON-RPC connections + JSON-RPC连接密码 + + + + + Listen for JSON-RPC connections on <port> (default: 8332) + JSON-RPC连接监听<端口> (默认为 8332) + + + + + Allow JSON-RPC connections from specified IP address + 允许从指定IP接受到的JSON-RPC连接 + + + + + Send commands to node running on <ip> (default: 127.0.0.1) + 向IP地址为 <ip> 的节点发送指令 (缺省: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + 当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值) + + + + Upgrade wallet to latest format + 将钱包升级到最新的格式 + + + + Set key pool size to <n> (default: 100) + 设置密钥池大小为 <n> (缺省: 100) + + + + + Rescan the block chain for missing wallet transactions + 重新扫描数据链以查找遗漏的交易 + + + + + How many blocks to check at startup (default: 2500, 0 = all) + 启动时需检查的区块数量 (缺省: 2500, 设置0为检查所有区块) + + + + How thorough the block verification is (0-6, default: 1) + 需要几个确认 (0-6个, 缺省: 1个) + + + + Imports blocks from external blk000?.dat file + 从外来文件 blk000?.dat 导入区块数据 + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL 选项: (SSL 安装教程具体见比特币维基百科) + + + + + Use OpenSSL (https) for JSON-RPC connections + 为 JSON-RPC 连接使用 OpenSSL (https)连接 + + + + Server certificate file (default: server.cert) + 服务器证书 (默认为 server.cert) + + + + + Server private key (default: server.pem) + 服务器私钥 (默认为 server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + 可接受的加密器 (默认为 TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + 警告: 磁盘剩余空间不多了 + + + + This help message + 该帮助信息 + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + 无法给数据目录 %s 加锁。比特币进程可能已在运行。 + + + + Bitcoin + 比特币 + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + 无法绑定本机端口 %s (返回错误消息 %d, %s) + + + + Connect through socks proxy + 通过 socks 代理连接 + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + 选择 socks 代理版本 (socks4 或 socks5, 缺省为socks5) + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + 连接指定网络时不使用代理 <net> (IPv4 or IPv6) + + + + Allow DNS lookups for -addnode, -seednode and -connect + 使用 -addnode, -seednode 和 -connect选项时允许DNS查找 + + + + Pass DNS requests to (SOCKS5) proxy + 将 DNS 请求传递给 (SOCKS5) 代理 + + + + Loading addresses... + 正在加载地址... + + + + Error loading blkindex.dat + blkindex.dat文件加载错误 + + + + Error loading wallet.dat: Wallet corrupted + wallet.dat钱包文件加载错误:钱包损坏 + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + wallet.dat钱包文件加载错误:请升级到最新Bitcoin客户端 + + + + Wallet needed to be rewritten: restart Bitcoin to complete + 钱包文件需要重写:请退出并重新启动Bitcoin客户端 + + + + Error loading wallet.dat + wallet.dat钱包文件加载错误 + + + + Invalid -proxy address: '%s' + 非法的代理地址: '%s' + + + + Unknown network specified in -noproxy: '%s' + 被指定的是未知网络 -noproxy: '%s' + + + + Unknown network specified in -onlynet: '%s' + 被指定的是未知网络 -onlynet: '%s' + + + + Unknown -socks proxy version requested: %i + 被指定的是未知socks代理版本: %i + + + + Cannot resolve -bind address: '%s' + 无法解析 -bind 端口地址: '%s' + + + + Not listening on any port + 未监听任何端口 + + + + Cannot resolve -externalip address: '%s' + 无法解析 -externalip 地址: '%s' + + + + Invalid amount for -paytxfee=<amount>: '%s' + 非法金额 -paytxfee=<amount>: '%s' + + + + Error: could not start node + 错误: 无法启动节点 + + + + Error: Wallet locked, unable to create transaction + 错误: 钱包被锁,无法创建新的交易 + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + 错误: 该交易需支付到少 %s 的交易费,原因可能是该交易数量太小、构成太复杂或者使用了新近接收到的比特币 + + + + Error: Transaction creation failed + 错误:交易创建失败。 + + + + Sending... + 发送中 + + + + 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. + 错误:交易被拒绝。这种情况通常发生在您钱包中的一些货币已经被消费之后,比如您使用了一个wallet.dat的副本,而货币在那个副本中已经被消费,但在当前钱包中未被标记为已消费。 + + + + Invalid amount + 金额不对 + + + + Insufficient funds + 金额不足 + + + + Loading block index... + 加载区块索引... + + + + Add a node to connect to and attempt to keep the connection open + 添加节点并与其保持连接 + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + 无法在本机绑定 %s 端口 . 比特币客户端软件可能已经在运行. + + + + Find peers using internet relay chat (default: 0) + 通过IRC聊天室查找网络上的比特币节点 (缺省: 0) + + + + Accept connections from outside (default: 1) + 接受来自外部的连接 (缺省: 1) + + + + Find peers using DNS lookup (default: 1) + 通过DNS查找网络上的比特币节点 (缺省: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + 使用UPnP映射监听端口 (缺省: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + 使用UPnP映射监听端口 (缺省: 0) + + + + Fee per KB to add to transactions you send + 每发送1KB交易所需的费用 + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + 警告: -paytxfee 交易费用设得有点高. 每当您发送一笔交易,将会向网络支付这么多的交易费. + + + + Loading wallet... + 正在加载钱包... + + + + Cannot downgrade wallet + 无法降级钱包格式 + + + + Cannot initialize keypool + 无法初始化 keypool + + + + Cannot write default address + 无法写入缺省地址 + + + + Rescanning... + 正在重新扫描... + + + + Done loading + 加载完成 + + + + To use the %s option + 使用 %s 选项 + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, 您必须在配置文件中加入选项 rpcpassword : + %s +建议您使用下面的随机密码: +rpcuser=bitcoinrpc +rpcpassword=%s +(您无需记忆该密码) +如果配置文件不存在,请新建,并将文件权限设置为仅允许文件所有者读取. + + + + Error + 错误 + + + + An error occured while setting up the RPC port %i for listening: %s + 将端口 %i 设置为监听端口时发生错误: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + 您必须在配置文件中加入选项 rpcpassword : + %s +如果配置文件不存在,请新建,并将文件权限设置为仅允许文件所有者读取. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + 警告:请确定您当前计算机的日期和时间是正确的。比特币将无法在错误的时间下正常工作。 + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts new file mode 100644 index 0000000..c2b318e --- /dev/null +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -0,0 +1,2541 @@ + +UTF-8 + + AboutDialog + + + About Bitcoin + 關於位元幣 + + + + <b>Bitcoin</b> version + <b>位元幣</b>版本 + + + + Copyright © 2009-2012 Bitcoin Developers + +This is experimental software. + +Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php. + +This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. + 版權為 Bitcoin 開發人員自西元 2009 至 2012 年起所有 + +這是個實驗性的軟體. + +此軟體依據 MIX/X11 軟體授權條款散布, 詳情請見附帶的 license.txt 檔案, 或是以下網站: http://www.opensource.org/licenses/mit-license.php. + +此產品也包含了由 OpenSSL Project 所開發的 OpenSSL Toolkit (http://www.openssl.org/) 軟體, 由 Eric Young (eay@cryptsoft.com) 撰寫的加解密軟體, 以及由 Thomas Bernard 所撰寫的 UPnP 軟體. + + + + AddressBookPage + + + Address Book + 位址簿 + + + + These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. + 這是你用來收款的位元幣位址. 你可以提供不同的位址給不同的付款人, 來追蹤是誰支付給你. + + + + Double-click to edit address or label + 點兩下來修改位址或標記 + + + + Create a new address + 產生新位址 + + + + Copy the currently selected address to the system clipboard + 複製目前選取的位址到系統剪貼簿 + + + + &New Address + 新增位址 + + + + &Copy Address + 複製位址 + + + + Show &QR Code + 顯示 &QR 條碼 + + + + Sign a message to prove you own this address + 簽署一則訊息來證明你擁有這個位址 + + + + &Sign Message + 簽署訊息 + + + + Delete the currently selected address from the list. Only sending addresses can be deleted. + 從列表中刪除目前選取的位址. 只能夠刪除付款位址. + + + + &Delete + 刪除 + + + + Copy &Label + 複製標記 + + + + &Edit + 編輯 + + + + Export Address Book Data + 匯出位址簿資料 + + + + Comma separated file (*.csv) + 逗號區隔資料檔 (*.csv) + + + + Error exporting + 資料匯出有誤 + + + + Could not write to file %1. + 無法寫入檔案 %1. + + + + AddressTableModel + + + Label + 標記 + + + + Address + 位址 + + + + (no label) + (沒有標記) + + + + AskPassphraseDialog + + + Passphrase Dialog + 密碼對話視窗 + + + + Enter passphrase + 輸入密碼 + + + + New passphrase + 新的密碼 + + + + Repeat new passphrase + 重複新密碼 + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. + 輸入錢包的新密碼.<br/>請用<b>10個以上的字元</b>, 或是<b>8個以上的字詞</b>. + + + + Encrypt wallet + 錢包加密 + + + + This operation needs your wallet passphrase to unlock the wallet. + 這個動作需要用你的錢包密碼來解鎖 + + + + Unlock wallet + 錢包解鎖 + + + + This operation needs your wallet passphrase to decrypt the wallet. + 這個動作需要用你的錢包密碼來解密 + + + + Decrypt wallet + 錢包解密 + + + + Change passphrase + 變更密碼 + + + + Enter the old and new passphrase to the wallet. + 輸入錢包的新舊密碼. + + + + Confirm wallet encryption + 錢包加密確認 + + + + WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! +Are you sure you wish to encrypt your wallet? + 警告: 如果將錢包加密後忘記密碼, 你會<b>失去其中所有的位元幣</b>! +你確定要將錢包加密嗎? + + + + + Wallet encrypted + 錢包已加密 + + + + Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + 位元幣現在要關閉以完成加密程序. 請記住, 加密錢包無法完全防止入侵電腦的惡意程式偷取你的位元幣. + + + + + Warning: The Caps Lock key is on. + 警告: 鍵盤輸入鎖定為大寫字母中. + + + + + + + Wallet encryption failed + 錢包加密失敗 + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + 錢包加密因程式內部有誤而失敗. 你的錢包還是沒有加密. + + + + + The supplied passphrases do not match. + 提供的密碼不符. + + + + Wallet unlock failed + 錢包解鎖失敗 + + + + + + The passphrase entered for the wallet decryption was incorrect. + 用來解密錢包的密碼輸入錯誤. + + + + Wallet decryption failed + 錢包解密失敗 + + + + Wallet passphrase was succesfully changed. + 錢包密碼變更成功. + + + + BitcoinGUI + + + Bitcoin Wallet + 位元幣錢包 + + + + Sign &message... + 訊息簽署... + + + + Show/Hide &Bitcoin + 顯示/隱藏位元幣 + + + + Synchronizing with network... + 網路同步中... + + + + &Overview + 總覽 + + + + Show general overview of wallet + 顯示錢包一般總覽 + + + + &Transactions + 交易 + + + + Browse transaction history + 瀏覽交易紀錄 + + + + &Address Book + 位址簿 + + + + Edit the list of stored addresses and labels + 編輯儲存位址與標記的列表 + + + + &Receive coins + 收錢 + + + + Show the list of addresses for receiving payments + 顯示收款位址的列表 + + + + &Send coins + 付錢 + + + + Prove you control an address + 證明你控制一個位址 + + + + E&xit + 結束 + + + + Quit application + 結束應用程式 + + + + &About %1 + 關於%1 + + + + Show information about Bitcoin + 顯示位元幣相關資訊 + + + + About &Qt + 關於 &Qt + + + + Show information about Qt + 顯示有關於 Qt 的資訊 + + + + &Options... + 選項... + + + + &Encrypt Wallet... + 錢包加密... + + + + &Backup Wallet... + 錢包備份... + + + + &Change Passphrase... + 密碼變更... + + + + ~%n block(s) remaining + 剩下 ~%n 個區塊 + + + + Downloaded %1 of %2 blocks of transaction history (%3% done). + 已下載了全部 %2 個中的 %1 個交易紀錄區塊 (已完成 %3%). + + + + &Export... + 匯出... + + + + Send coins to a Bitcoin address + 付錢到一個位元幣位址 + + + + Modify configuration options for Bitcoin + 修改位元幣的設定選項 + + + + Show or hide the Bitcoin window + 顯示或隱藏位元幣的視窗 + + + + Export the data in the current tab to a file + 將目前分頁的資料匯出存成檔案 + + + + Encrypt or decrypt wallet + 將錢包加解密 + + + + Backup wallet to another location + 將錢包備份到其它地方 + + + + Change the passphrase used for wallet encryption + 變更錢包加密用的密碼 + + + + &Debug window + 除錯視窗 + + + + Open debugging and diagnostic console + 開啓除錯與診斷主控台 + + + + &Verify message... + 訊息驗證... + + + + Verify a message signature + 驗證訊息簽章 + + + + &File + 檔案 + + + + &Settings + 設定 + + + + &Help + 求助 + + + + Tabs toolbar + 分頁工具列 + + + + Actions toolbar + 動作工具列 + + + + + [testnet] + [testnet] + + + + + Bitcoin client + 位元幣客戶軟體 + + + + %n active connection(s) to Bitcoin network + 與位元幣網路有 %n 個連線在使用中 + + + + Downloaded %1 blocks of transaction history. + 已下載了 %1 個交易紀錄的區塊. + + + + %n second(s) ago + %n 秒鐘前 + + + + %n minute(s) ago + %n 分鐘前 + + + + %n hour(s) ago + %n 小時前 + + + + %n day(s) ago + %n 天前 + + + + Up to date + 最新狀態 + + + + Catching up... + 進度追趕中... + + + + Last received block was generated %1. + 最近收到的區塊產生於 %1. + + + + This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? + 這筆交易的資料大小超過限制了. 你還是可以付出 %1 的費用來傳送. 這筆費用會付給處理該筆交易的節點, 並幫助維持整個網路. 你願意支付這項費用嗎? + + + + Confirm transaction fee + 確認交易手續費 + + + + Sent transaction + 付款交易 + + + + Incoming transaction + 收款交易 + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 + + 日期: %1 +金額: %2 +類別: %3 +位址: %4 + + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + 錢包<b>已加密</b>並且正<b>解鎖中</b> + + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + 錢包<b>已加密</b>並且正<b>上鎖中</b> + + + + Backup Wallet + 錢包備份 + + + + Wallet Data (*.dat) + 錢包資料檔 (*.dat) + + + + Backup Failed + 備份失敗 + + + + There was an error trying to save the wallet data to the new location. + 儲存錢包資料到新的地方時發生錯誤 + + + + A fatal error occured. Bitcoin can no longer continue safely and will quit. + 發生了致命的錯誤. 位元幣程式將無法繼續安全執行, 只好結束. + + + + ClientModel + + + Network Alert + 網路警報 + + + + DisplayOptionsPage + + + Display + 顯示 + + + + default + 預設 + + + + The user interface language can be set here. This setting will only take effect after restarting Bitcoin. + 可以在這裡設定使用者介面的語言. 這個設定在位元幣程式重啓後才會生效. + + + + User Interface &Language: + 使用界面語言 + + + + &Unit to show amounts in: + 金額顯示單位: + + + + Choose the default subdivision unit to show in the interface, and when sending coins + 選擇操作界面與付錢時預設顯示的細分單位 + + + + &Display addresses in transaction list + 在交易列表顯示位址 + + + + Whether to show Bitcoin addresses in the transaction list + 是否要在交易列表中顯示位元幣位址 + + + + Warning + 警告 + + + + This setting will take effect after restarting Bitcoin. + 這個設定會在位元幣程式重啓後生效. + + + + EditAddressDialog + + + Edit Address + 編輯位址 + + + + &Label + 標記 + + + + The label associated with this address book entry + 與這個位址簿項目關聯的標記 + + + + &Address + 位址 + + + + The address associated with this address book entry. This can only be modified for sending addresses. + 與這個位址簿項目關聯的位址. 只能修改付款位址. + + + + New receiving address + 新收款位址 + + + + New sending address + 新付款位址 + + + + Edit receiving address + 編輯收款位址 + + + + Edit sending address + 編輯付款位址 + + + + The entered address "%1" is already in the address book. + 輸入的位址"%1"已存在於位址簿中. + + + + The entered address "%1" is not a valid Bitcoin address. + 輸入的位址 "%1" 並不是有效的位元幣位址. + + + + Could not unlock wallet. + 無法將錢包解鎖. + + + + New key generation failed. + 新密鑰產生失敗. + + + + HelpMessageBox + + + + Bitcoin-Qt + 位元幣-Qt + + + + version + 版本 + + + + Usage: + 用法: + + + + options + 選項 + + + + UI options + 使用界面選項 + + + + Set language, for example "de_DE" (default: system locale) + 設定語言, 比如說 "de_DE" (預設: 系統語系) + + + + Start minimized + 啓動時最小化 + + + + + Show splash screen on startup (default: 1) + 顯示啓動畫面 (預設: 1) + + + + MainOptionsPage + + + 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. + 關掉程式時卸載區塊與位址的資料庫. 表示說資料庫會被搬到別的資料目錄去, 且會造成程式關掉的比較慢. 錢包則總是會被卸載. + + + + Pay transaction &fee + 付交易手續費 + + + + Main + 主要 + + + + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + 非必要的交易手續費, 以 kB 為計費單位, 且有助於縮短你的交易處理時間. 大部份交易的資料大小是 1 kB. 建議設定為 0.01 元. + + + + &Start Bitcoin on system login + 系統登入時啟動位元幣 + + + + Automatically start Bitcoin after logging in to the system + 在登入系統後自動啓動位元幣 + + + + &Detach databases at shutdown + 關閉時卸載資料庫 + + + + MessagePage + + + Sign Message + 訊息簽署 + + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + 你可以用你的位址來簽署訊息, 以證明你對它的所有權. 但是請小心, 不要簽署語意含糊不清的內容, 因為釣魚式詐騙可能會用騙你簽署的手法來冒充是你. 只有在語句中的細節你都同意時才簽署. + + + + The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + 用來簽署訊息的位址 (比如說 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose adress from address book + 從位址簿中選一個位址 + + + + Alt+A + Alt+A + + + + Paste address from clipboard + 從剪貼簿貼上位址 + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + 在這裡輸入你想簽署的訊息 + + + + Copy the current signature to the system clipboard + 複製目前的簽章到系統剪貼簿 + + + + &Copy Signature + 複製簽章 + + + + Reset all sign message fields + 重置所有訊息簽署欄位 + + + + Clear &All + 全部清掉 + + + + Click "Sign Message" to get signature + 按"簽署訊息"來取得簽章 + + + + Sign a message to prove you own this address + 簽署一則訊息來證明你擁有這個位址 + + + + &Sign Message + 簽署訊息 + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + 輸入位元幣位址 (比如說 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + + + + Error signing + 簽署發生錯誤 + + + + %1 is not a valid address. + %1 不是個有效的位址. + + + + %1 does not refer to a key. + %1 沒有指到任何密鑰. + + + + Private key for %1 is not available. + 沒有 %1 的密鑰. + + + + Sign failed + 簽署失敗 + + + + NetworkOptionsPage + + + Network + 網路 + + + + Map port using &UPnP + 用 &UPnP 設定通訊埠對應 + + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + 自動在路由器上開啟 Bitcoin 的客戶端通訊埠. 只有在你的路由器支援 UPnP 且開啟時才有作用. + + + + &Connect through SOCKS4 proxy: + 透過 SOCKS4 代理伺服器連線: + + + + Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor) + 透過 SOCKS4 代理伺服器連線至位元幣網路 (比如說透過 Tor) + + + + Proxy &IP: + 代理伺服器位址: + + + + &Port: + 通訊埠: + + + + IP address of the proxy (e.g. 127.0.0.1) + 代理伺服器的網際網路位址 (比如說 127.0.0.1) + + + + Port of the proxy (e.g. 1234) + 代理伺服器的通訊埠 (比如說 1234) + + + + OptionsDialog + + + Options + 選項 + + + + OverviewPage + + + Form + 表單 + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + 顯示的資訊可能是過期的. 與位元幣網路的連線建立後, 你的錢包會自動和網路同步, 但這個步驟還沒完成. + + + + Balance: + 餘額: + + + + Number of transactions: + 交易次數: + + + + Unconfirmed: + 未確認額: + + + + Wallet + 錢包 + + + + <b>Recent transactions</b> + <b>最近交易</b> + + + + Your current balance + 目前餘額 + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the current balance + 尚未確認之交易的總額, 不包含在目前餘額中 + + + + Total number of transactions in wallet + 錢包中紀錄的總交易次數 + + + + + out of sync + 沒同步 + + + + QRCodeDialog + + + QR Code Dialog + QR 條碼對話視窗 + + + + QR Code + QR 條碼 + + + + Request Payment + 付款單 + + + + Amount: + 金額: + + + + BTC + BTC + + + + Label: + 標記: + + + + Message: + 訊息: + + + + &Save As... + 儲存為... + + + + Error encoding URI into QR Code. + 將 URI 編碼成 QR 條碼時發生錯誤 + + + + Resulting URI too long, try to reduce the text for label / message. + 造出的網址太長了,請把標籤或訊息的文字縮短再試看看. + + + + Save QR Code + 儲存 QR 條碼 + + + + PNG Images (*.png) + PNG 圖檔 (*.png) + + + + RPCConsole + + + Bitcoin debug window + 位元幣除錯視窗 + + + + Client name + 客戶端程式名稱 + + + + + + + + + + + + N/A + + + + + Client version + 客戶端程式版本 + + + + &Information + 資訊 + + + + Client + 用戶端程式 + + + + Startup time + 啓動時間 + + + + Network + 網路 + + + + Number of connections + 連線數 + + + + On testnet + 位於測試網路 + + + + Block chain + 區塊鎖鏈 + + + + Current number of blocks + 目前區塊數 + + + + Estimated total blocks + 估計總區塊數 + + + + Last block time + 最近區塊時間 + + + + Debug logfile + 除錯紀錄檔 + + + + Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles. + 從目前的資料目錄下開啓位元幣的除錯紀錄檔. 當紀錄檔很大時可能要花好幾秒的時間. + + + + &Open + 開啓 + + + + &Console + 主控台 + + + + Build date + 建置日期 + + + + Clear console + 清主控台 + + + + Welcome to the Bitcoin RPC console. + 歡迎使用位元幣 RPC 主控台. + + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + 請用上下游標鍵來瀏覽歷史指令, 且可用 <b>Ctrl-L</b> 來清理畫面. + + + + Type <b>help</b> for an overview of available commands. + 請打 <b>help</b> 來看可用指令的簡介. + + + + SendCoinsDialog + + + + + + + + + + Send Coins + 付錢 + + + + Send to multiple recipients at once + 一次付給多個人 + + + + &Add Recipient + 加收款人 + + + + Remove all transaction fields + 移除所有交易欄位 + + + + Clear &All + 全部清掉 + + + + Balance: + 餘額: + + + + 123.456 BTC + 123.456 BTC + + + + Confirm the send action + 確認付款動作 + + + + &Send + 付出 + + + + <b>%1</b> to %2 (%3) + <b>%1</b> 給 %2 (%3) + + + + Confirm send coins + 確認付出金額 + + + + Are you sure you want to send %1? + 確定要付出 %1 嗎? + + + + and + + + + + The recepient address is not valid, please recheck. + 無效的收款位址, 請再檢查看看. + + + + The amount to pay must be larger than 0. + 付款金額必須大於 0. + + + + The amount exceeds your balance. + 金額超過了餘額 + + + + The total exceeds your balance when the %1 transaction fee is included. + 包含 %1 的交易手續費後, 總金額超過了你的餘額 + + + + Duplicate address found, can only send to each address once per send operation. + 發現有重複的位址. 在一次付款動作中, 只能付給每個位址一次. + + + + Error: Transaction creation failed. + 錯誤: 交易產生失敗. + + + + 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. + 錯誤: 交易被拒絕. 有時候會發生這種錯誤, 是因為你錢包中的一些錢已經被花掉了. 比如說你複製了錢包檔 wallet.dat, 然後用複製的錢包花掉了錢, 你現在所用的原來的錢包中卻沒有該筆交易紀錄. + + + + SendCoinsEntry + + + Form + 表單 + + + + A&mount: + 金額: + + + + Pay &To: + 付給: + + + + + Enter a label for this address to add it to your address book + 給這個位址輸入一個標記, 並加到位址簿中 + + + + &Label: + 標記: + + + + The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + 付款的目標位址 (比如說 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + Choose address from address book + 從位址簿中選一個位址 + + + + Alt+A + Alt+A + + + + Paste address from clipboard + 從剪貼簿貼上位址 + + + + Alt+P + Alt+P + + + + Remove this recipient + 去掉這個收款人 + + + + Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + 輸入位元幣位址 (比如說 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L) + + + + TransactionDesc + + + Open for %1 blocks + 在 %1 個區塊內未定 + + + + Open until %1 + 在 %1 前未定 + + + + %1/offline? + %1/離線中? + + + + %1/unconfirmed + %1/未確認 + + + + %1 confirmations + 經確認 %1 次 + + + + <b>Status:</b> + <b>狀態:</b> + + + + , has not been successfully broadcast yet + , 尚未成功公告出去 + + + + , broadcast through %1 node + , 已公告至 %1 個節點 + + + + , broadcast through %1 nodes + , 已公告至 %1 個節點 + + + + <b>Date:</b> + <b>日期:</b> + + + + <b>Source:</b> Generated<br> + <b>來源:</b> 生產所得<br> + + + + + <b>From:</b> + <b>來自:</b> + + + + unknown + 未知 + + + + + + <b>To:</b> + <b>目的:</b> + + + + (yours, label: + (你的, 標記為: + + + + (yours) + (你的) + + + + + + + <b>Credit:</b> + <b>入帳:</b> + + + + (%1 matures in %2 more blocks) + (%1 將在 %2 個區塊產出後熟成) + + + + (not accepted) + (不被接受) + + + + + + <b>Debit:</b> + <b>出帳:</b> + + + + <b>Transaction fee:</b> + <b>交易手續費:</b> + + + + <b>Net amount:</b> + <b>淨額:</b> + + + + Message: + 訊息: + + + + Comment: + 附註: + + + + Transaction ID: + 交易識別碼: + + + + 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. + 生產出來的錢要再等 120 個區塊產出之後, 才能夠花用. 當你產出區塊時, 它會被公布到網路上, 以被串連至區塊鎖鏈. 如果串連失敗了, 它的狀態就會變成"不被接受", 且不能被花用. 當你產出區塊的幾秒鐘內, 其他節點也產出了區塊的話, 有時候就會發生這種情形. + + + + TransactionDescDialog + + + Transaction details + 交易明細 + + + + This pane shows a detailed description of the transaction + 此版面顯示交易的詳細說明 + + + + TransactionTableModel + + + Date + 日期 + + + + Type + 種類 + + + + Address + 位址 + + + + Amount + 金額 + + + + Open for %n block(s) + 在 %n 個區塊內未定 + + + + Open until %1 + 在 %1 前未定 + + + + Offline (%1 confirmations) + 離線中 (經確認 %1 次) + + + + Unconfirmed (%1 of %2 confirmations) + 未確認 (經確認 %1 次, 應確認 %2 次) + + + + Confirmed (%1 confirmations) + 已確認 (經確認 %1 次) + + + + Mined balance will be available in %n more blocks + 生產金額將在 %n 個區塊產出後可用 + + + + This block was not received by any other nodes and will probably not be accepted! + 沒有其他節點收到這個區塊, 也許它不被接受! + + + + Generated but not accepted + 產出但不被接受 + + + + Received with + 收受於 + + + + Received from + 收受自 + + + + Sent to + 付出至 + + + + Payment to yourself + 付給自己 + + + + Mined + 開採所得 + + + + (n/a) + (不適用) + + + + Transaction status. Hover over this field to show number of confirmations. + 交易狀態. 移動游標至欄位上方來顯示確認次數. + + + + Date and time that the transaction was received. + 收到交易的日期與時間. + + + + Type of transaction. + 交易的種類. + + + + Destination address of transaction. + 交易的目標位址. + + + + Amount removed from or added to balance. + 減去或加入至餘額的金額 + + + + TransactionView + + + + All + 全部 + + + + Today + 今天 + + + + This week + 這週 + + + + This month + 這個月 + + + + Last month + 上個月 + + + + This year + 今年 + + + + Range... + 指定範圍... + + + + Received with + 收受於 + + + + Sent to + 付出至 + + + + To yourself + 給自己 + + + + Mined + 開採所得 + + + + Other + 其他 + + + + Enter address or label to search + 輸入位址或標記來搜尋 + + + + Min amount + 最小金額 + + + + Copy address + 複製位址 + + + + Copy label + 複製標記 + + + + Copy amount + 複製金額 + + + + Edit label + 編輯標記 + + + + Show transaction details + 顯示交易明細 + + + + Export Transaction Data + 匯出交易資料 + + + + Comma separated file (*.csv) + 逗號分隔資料檔 (*.csv) + + + + Confirmed + 已確認 + + + + Date + 日期 + + + + Type + 種類 + + + + Label + 標記 + + + + Address + 位址 + + + + Amount + 金額 + + + + ID + 識別碼 + + + + Error exporting + 匯出錯誤 + + + + Could not write to file %1. + 無法寫入至 %1 檔案. + + + + Range: + 範圍: + + + + to + + + + + VerifyMessageDialog + + + Verify Signed Message + 驗證簽署過的訊息 + + + + 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. + 請在下面輸入訊息與簽章(有些字元是看不到的, 如換行, 空格, 跳位符號等, 請小心並正確地複製), 以獲知用來簽署該訊息的位元幣位址. + + + + Verify a message and obtain the Bitcoin address used to sign the message + 驗證一則訊息, 並獲知用來簽署該訊息的位元幣位址 + + + + &Verify Message + 驗證訊息 + + + + Copy the currently selected address to the system clipboard + 複製目前選取的位址到系統剪貼簿 + + + + &Copy Address + 複製位址 + + + + Reset all verify message fields + 重置所有訊息驗證欄位 + + + + Clear &All + 全部清掉 + + + + Enter Bitcoin signature + 輸入位元幣簽章 + + + + Click "Verify Message" to obtain address + 按"驗證訊息"來取得位址 + + + + + Invalid Signature + 無效的簽章 + + + + The signature could not be decoded. Please check the signature and try again. + 無法將這個簽章解碼. 請檢查簽章是否正確後再試一次. + + + + The signature did not match the message digest. Please check the signature and try again. + 簽章與訊息的數位摘要不符. 請檢查簽章是否正確後再試一次. + + + + Address not found in address book. + 在位址簿中找不到該位址. + + + + Address found in address book: %1 + 在位址簿中找到此位址: %1 + + + + WalletModel + + + Sending... + 付出中... + + + + WindowOptionsPage + + + Window + 視窗 + + + + &Minimize to the tray instead of the taskbar + 最小化至通知區域而非工作列 + + + + Show only a tray icon after minimizing the window + 視窗最小化時只顯示圖示於通知區域 + + + + M&inimize on close + 關閉時最小化 + + + + 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. + 當視窗關閉時將其最小化, 而非結束應用程式. 當勾選這個選項時, 應用程式只能用選單中的結束來停止執行. + + + + bitcoin-core + + + Bitcoin version + 位元幣版本 + + + + Usage: + 用法: + + + + Send command to -server or bitcoind + 送指令至 -server 或 bitcoind + + + + + List commands + 列出指令 + + + + + Get help for a command + 取得指令說明 + + + + + Options: + 選項: + + + + + Specify configuration file (default: bitcoin.conf) + 指定設定檔 (預設: bitcoin.conf) + + + + + Specify pid file (default: bitcoind.pid) + 指定行程識別碼檔案 (預設: bitcoind.pid) + + + + + Generate coins + 生產位元幣 + + + + + Don't generate coins + 不生產位元幣 + + + + + Specify data directory + 指定資料目錄 + + + + + Set database cache size in megabytes (default: 25) + 設定資料庫快取大小為多少百萬位元組(MB, 預設: 25) + + + + Set database disk log size in megabytes (default: 100) + 設定資料庫的磁碟紀錄大小為多少百萬位元組(MB, 預設: 100) + + + + Specify connection timeout (in milliseconds) + 指定連線逾時時間 (毫秒) + + + + + Listen for connections on <port> (default: 8333 or testnet: 18333) + 在通訊埠 <port> 聽候連線 (預設: 8333, 或若為測試網路: 18333) + + + + Maintain at most <n> connections to peers (default: 125) + 維持與節點連線數的上限為 <n> 個 (預設: 125) + + + + Connect only to the specified node + 只連線至指定節點 + + + + + Connect to a node to retrieve peer addresses, and disconnect + 連線到某個節點以取得其它節點的位址, 然後斷線 + + + + Specify your own public address + 指定自己公開的位址 + + + + Only connect to nodes in network <net> (IPv4 or IPv6) + 只和 <net> 網路上的節點連線 (IPv4 或 IPv6) + + + + Try to discover public IP address (default: 1) + 試著找出公開的網際網路位址 (預設: 1) + + + + Bind to given address. Use [host]:port notation for IPv6 + 與指定的位址繫結. IPv6 要使用 [主機]:通訊埠 的格式 + + + + Threshold for disconnecting misbehaving peers (default: 100) + 與亂搞的節點斷線的臨界值 (預設: 100) + + + + Number of seconds to keep misbehaving peers from reconnecting (default: 86400) + 避免與亂搞的節點連線的秒數 (預設: 86400) + + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000) + 每個連線的接收緩衝區大小上限為 <n>*1000 位元組 (預設: 10000) + + + + Maximum per-connection send buffer, <n>*1000 bytes (default: 10000) + 每個連線的傳送緩衝區大小上限為 <n>*1000 位元組 (預設: 10000) + + + + Detach block and address databases. Increases shutdown time (default: 0) + 卸載區塊與位址的資料庫. 會延長關閉時間 (預設: 0) + + + + Accept command line and JSON-RPC commands + 接受命令列與 JSON-RPC 指令 + + + + + Run in the background as a daemon and accept commands + 以背景程式執行並接受指令 + + + + Use the test network + 使用測試網路 + + + + + Output extra debugging information + 輸出額外的除錯資訊 + + + + Prepend debug output with timestamp + 在除錯輸出內容前附加時間 + + + + Send trace/debug info to console instead of debug.log file + 輸出追蹤或除錯資訊至終端機, 而非 debug.log 檔案 + + + + Send trace/debug info to debugger + 輸出追蹤或除錯資訊給除錯器 + + + + Username for JSON-RPC connections + JSON-RPC 連線使用者名稱 + + + + Password for JSON-RPC connections + JSON-RPC 連線密碼 + + + + Listen for JSON-RPC connections on <port> (default: 8332) + 在通訊埠 <port> 聽候 JSON-RPC 連線 (預設: 8332) + + + + Allow JSON-RPC connections from specified IP address + 只允許從指定網路位址來的 JSON-RPC 連線 + + + + Send commands to node running on <ip> (default: 127.0.0.1) + 送指令給在 <ip> 的節點 (預設: 127.0.0.1) + + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + 當最新區塊改變時所要執行的指令 (指令中的 %s 會被取代為區塊的雜湊值) + + + + Upgrade wallet to latest format + 將錢包升級成最新的格式 + + + + Set key pool size to <n> (default: 100) + 設定密鑰池大小為 <n> (預設: 100) + + + + + Rescan the block chain for missing wallet transactions + 重新掃描區塊鎖鏈, 以尋找錢包所遺漏的交易. + + + + How many blocks to check at startup (default: 2500, 0 = all) + 啓動時檢查多少區塊 (預設: 2500, 0 表示全部) + + + + How thorough the block verification is (0-6, default: 1) + 區塊檢查的仔細程度 (0 至 6, 預設: 1) + + + + Imports blocks from external blk000?.dat file + 從外來的區塊檔 blk000?.dat 匯入區塊 + + + + +SSL options: (see the Bitcoin Wiki for SSL setup instructions) + +SSL 選項: (SSL 設定程序請見 Bitcoin Wiki) + + + + + Use OpenSSL (https) for JSON-RPC connections + 使用 OpenSSL (https) 於JSON-RPC 連線 + + + + + Server certificate file (default: server.cert) + 伺服器憑證檔 (預設: server.cert) + + + + + Server private key (default: server.pem) + 伺服器密鑰檔 (預設: server.pem) + + + + + Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + 可以接受的加密法 (預設: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + + + + + Warning: Disk space is low + 警告: 磁碟空間很少 + + + + This help message + 此協助訊息 + + + + + Cannot obtain a lock on data directory %s. Bitcoin is probably already running. + 無法鎖定資料目錄 %s. 也許位元幣已經在執行了. + + + + Bitcoin + 位元幣 + + + + Unable to bind to %s on this computer (bind returned error %d, %s) + 無法和這台電腦上的 %s 繫結 (繫結回傳錯誤 %d, %s) + + + + Connect through socks proxy + 透過 SOCKS 代理伺服器連線 + + + + Select the version of socks proxy to use (4 or 5, 5 is default) + 選擇 SOCKS 代理伺服器的協定版本(4 或 5, 預設是 5) + + + + Do not use proxy for connections to network <net> (IPv4 or IPv6) + 不透過 SOCKS 代理伺服器連線至 <net> 網路 (IPv4 或 IPv6) + + + + Allow DNS lookups for -addnode, -seednode and -connect + 允許對 -addnode, -seednode, -connect 的參數使用域名查詢 + + + + Pass DNS requests to (SOCKS5) proxy + 透過 (SOCKS5) 代理伺服器送出域名查詢 + + + + Loading addresses... + 載入位址中... + + + + Error loading blkindex.dat + 載入 blkindex.dat 失敗 + + + + Error loading wallet.dat: Wallet corrupted + 載入檔案 wallet.dat 失敗: 錢包壞掉了 + + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin + 載入檔案 wallet.dat 失敗: 此錢包需要新版的 Bitcoin + + + + Wallet needed to be rewritten: restart Bitcoin to complete + 錢包需要重寫: 請重啟位元幣來完成 + + + + Error loading wallet.dat + 載入檔案 wallet.dat 失敗 + + + + Invalid -proxy address: '%s' + 無效的 -proxy 位址: '%s' + + + + Unknown network specified in -noproxy: '%s' + 在 -noproxy 指定了不明的網路別: '%s' + + + + Unknown network specified in -onlynet: '%s' + 在 -onlynet 指定了不明的網路別: '%s' + + + + Unknown -socks proxy version requested: %i + 在 -socks 指定了不明的代理協定版本: %i + + + + Cannot resolve -bind address: '%s' + 無法解析 -bind 位址: '%s' + + + + Not listening on any port + 不在任何通訊埠聽候連線 + + + + Cannot resolve -externalip address: '%s' + 無法解析 -externalip 位址: '%s' + + + + Invalid amount for -paytxfee=<amount>: '%s' + 設定 -paytxfee=<金額> 的金額無效: '%s' + + + + Error: could not start node + 錯誤: 無法啓動節點 + + + + Error: Wallet locked, unable to create transaction + 錯誤: 錢包被上鎖了, 無法產生新的交易 + + + + Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds + 錯誤: 這筆交易需要至少 %s 的手續費, 因為它的金額太大, 或複雜度太高, 或是使用了最近才剛收到的款項 + + + + Error: Transaction creation failed + 錯誤: 交易產生失敗 + + + + Sending... + 付出中... + + + + 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. + 錯誤: 交易被拒絕. 有時候會發生這種錯誤, 是因為你錢包中的一些錢已經被花掉了. 比如說你複製了錢包檔 wallet.dat, 然後用複製的錢包花掉了錢, 你現在所用的原來的錢包中卻沒有該筆交易紀錄. + + + + Invalid amount + 無效的金額 + + + + Insufficient funds + 累積金額不足 + + + + Loading block index... + 載入區塊索引中... + + + + Add a node to connect to and attempt to keep the connection open + 加入一個要連線的節線, 並試著保持對它的連線暢通 + + + + Unable to bind to %s on this computer. Bitcoin is probably already running. + 無法和這台電腦上的 %s 繫結. 也許位元幣已經在執行了. + + + + Find peers using internet relay chat (default: 0) + 是否使用網際網路中繼聊天(IRC)來找節點 (預設: 0) + + + + Accept connections from outside (default: 1) + 是否接受外來連線 (預設: 1) + + + + Find peers using DNS lookup (default: 1) + 是否允許在找節點時使用域名查詢 (預設: 1) + + + + Use Universal Plug and Play to map the listening port (default: 1) + 是否使用通用即插即用(UPnP)來設定聽候連線的通訊埠 (預設: 1) + + + + Use Universal Plug and Play to map the listening port (default: 0) + 是否使用通用即插即用(UPnP)來設定聽候連線的通訊埠 (預設: 0) + + + + Fee per KB to add to transactions you send + 交易付款時每 KB 的交易手續費 + + + + Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction. + 警告: -paytxfee 設定了很高的金額. 這可是你交易付款所要付的手續費. + + + + Loading wallet... + 載入錢包中... + + + + Cannot downgrade wallet + 無法將錢包格式降級 + + + + Cannot initialize keypool + 無法將密鑰池初始化 + + + + Cannot write default address + 無法寫入預設位址 + + + + Rescanning... + 重新掃描中... + + + + Done loading + 載入完成 + + + + To use the %s option + 為了要使用 %s 選項 + + + + %s, you must set a rpcpassword in the configuration file: + %s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +If the file does not exist, create it with owner-readable-only file permissions. + + %s, 你必須在下列設定檔中設定 RPC 密碼(rpcpassword): +%s +建議你使用下列的隨機產生密碼: +rpcuser=bitcoinrpc +rpcpassword=%s +(你不用記住這個密碼) +如果這個檔案還不存在, 請在新增時設定檔案權限為只有擁有者才能讀取. + + + + + Error + 錯誤 + + + + An error occured while setting up the RPC port %i for listening: %s + 設定聽候 RPC 連線的通訊埠 %i 時發生錯誤: %s + + + + You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions. + 你必須在下列設定檔中設定 RPC 密碼(rpcpassword=<password>): +%s +如果這個檔案還不存在, 請在新增時設定檔案權限為只有擁有者才能讀取. + + + + Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly. + 警告: 請檢查電腦時間日期是否正確. 位元幣無法在時鐘不準的情況下正常運作. + + + \ No newline at end of file diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h new file mode 100644 index 0000000..b5ccfed --- /dev/null +++ b/src/qt/macdockiconhandler.h @@ -0,0 +1,45 @@ +#ifndef MACDOCKICONHANDLER_H +#define MACDOCKICONHANDLER_H + +#include + +class QMenu; +class QIcon; +class QWidget; +class objc_object; + +#ifdef __OBJC__ +@class DockIconClickEventHandler; +#else +class DockIconClickEventHandler; +#endif + +/** Macintosh-specific dock icon handler. + */ +class MacDockIconHandler : public QObject +{ + Q_OBJECT +public: + ~MacDockIconHandler(); + + QMenu *dockMenu(); + void setIcon(const QIcon &icon); + + static MacDockIconHandler *instance(); + + void handleDockIconClickEvent(); + +signals: + void dockIconClicked(); + +public slots: + +private: + MacDockIconHandler(); + + DockIconClickEventHandler *m_dockIconClickEventHandler; + QWidget *m_dummyWidget; + QMenu *m_dockMenu; +}; + +#endif // MACDOCKICONCLICKHANDLER_H diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm new file mode 100644 index 0000000..df56e69 --- /dev/null +++ b/src/qt/macdockiconhandler.mm @@ -0,0 +1,99 @@ + +#include "macdockiconhandler.h" + +#include +#include + +extern void qt_mac_set_dock_menu(QMenu*); + +#undef slots +#include + +@interface DockIconClickEventHandler : NSObject +{ + MacDockIconHandler* dockIconHandler; +} + +@end + +@implementation DockIconClickEventHandler + +- (id)initWithDockIconHandler:(MacDockIconHandler *)aDockIconHandler +{ + self = [super init]; + if (self) { + dockIconHandler = aDockIconHandler; + + [[NSAppleEventManager sharedAppleEventManager] + setEventHandler:self + andSelector:@selector(handleDockClickEvent:withReplyEvent:) + forEventClass:kCoreEventClass + andEventID:kAEReopenApplication]; + } + return self; +} + +- (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent +{ + Q_UNUSED(event) + Q_UNUSED(replyEvent) + + if (dockIconHandler) + dockIconHandler->handleDockIconClickEvent(); +} + +@end + +MacDockIconHandler::MacDockIconHandler() : QObject() +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this]; + + this->m_dummyWidget = new QWidget(); + this->m_dockMenu = new QMenu(this->m_dummyWidget); + qt_mac_set_dock_menu(this->m_dockMenu); + [pool release]; +} + +MacDockIconHandler::~MacDockIconHandler() +{ + [this->m_dockIconClickEventHandler release]; + delete this->m_dummyWidget; +} + +QMenu *MacDockIconHandler::dockMenu() +{ + return this->m_dockMenu; +} + +void MacDockIconHandler::setIcon(const QIcon &icon) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSImage *image; + if (icon.isNull()) + image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; + else { + QSize size = icon.actualSize(QSize(128, 128)); + QPixmap pixmap = icon.pixmap(size); + CGImageRef cgImage = pixmap.toMacCGImageRef(); + image = [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize]; + CFRelease(cgImage); + } + + [NSApp setApplicationIconImage:image]; + [image release]; + [pool release]; +} + +MacDockIconHandler *MacDockIconHandler::instance() +{ + static MacDockIconHandler *s_instance = NULL; + if (!s_instance) + s_instance = new MacDockIconHandler(); + return s_instance; +} + +void MacDockIconHandler::handleDockIconClickEvent() +{ + emit this->dockIconClicked(); +} diff --git a/src/qt/monitoreddatamapper.cpp b/src/qt/monitoreddatamapper.cpp new file mode 100644 index 0000000..88948d0 --- /dev/null +++ b/src/qt/monitoreddatamapper.cpp @@ -0,0 +1,36 @@ +#include "monitoreddatamapper.h" + +#include +#include +#include + +MonitoredDataMapper::MonitoredDataMapper(QObject *parent) : + QDataWidgetMapper(parent) +{ +} + + +void MonitoredDataMapper::addMapping(QWidget *widget, int section) +{ + QDataWidgetMapper::addMapping(widget, section); + addChangeMonitor(widget); +} + +void MonitoredDataMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName) +{ + QDataWidgetMapper::addMapping(widget, section, propertyName); + addChangeMonitor(widget); +} + +void MonitoredDataMapper::addChangeMonitor(QWidget *widget) +{ + // Watch user property of widget for changes, and connect + // the signal to our viewModified signal. + QMetaProperty prop = widget->metaObject()->userProperty(); + int signal = prop.notifySignalIndex(); + int method = this->metaObject()->indexOfMethod("viewModified()"); + if(signal != -1 && method != -1) + { + QMetaObject::connect(widget, signal, this, method); + } +} diff --git a/src/qt/monitoreddatamapper.h b/src/qt/monitoreddatamapper.h new file mode 100644 index 0000000..33a874e --- /dev/null +++ b/src/qt/monitoreddatamapper.h @@ -0,0 +1,31 @@ +#ifndef MONITOREDDATAMAPPER_H +#define MONITOREDDATAMAPPER_H + +#include + +QT_BEGIN_NAMESPACE +class QWidget; +QT_END_NAMESPACE + +/** Data to Widget mapper that watches for edits and notifies listeners when a field is edited. + This can be used, for example, to enable a commit/apply button in a configuration dialog. + */ +class MonitoredDataMapper : public QDataWidgetMapper +{ + Q_OBJECT +public: + explicit MonitoredDataMapper(QObject *parent=0); + + void addMapping(QWidget *widget, int section); + void addMapping(QWidget *widget, int section, const QByteArray &propertyName); +private: + void addChangeMonitor(QWidget *widget); + +signals: + void viewModified(); + +}; + + + +#endif // MONITOREDDATAMAPPER_H diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp new file mode 100644 index 0000000..e668079 --- /dev/null +++ b/src/qt/notificator.cpp @@ -0,0 +1,302 @@ +#include "notificator.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_DBUS +#include +#include +#endif + +#ifdef Q_WS_MAC +#include +extern bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret); +#endif + +// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128 +const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128; + +Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, QWidget *parent): + QObject(parent), + parent(parent), + programName(programName), + mode(None), + trayIcon(trayicon) +#ifdef USE_DBUS + ,interface(0) +#endif +{ + if(trayicon && trayicon->supportsMessages()) + { + mode = QSystemTray; + } +#ifdef USE_DBUS + interface = new QDBusInterface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); + if(interface->isValid()) + { + mode = Freedesktop; + } +#endif +#ifdef Q_WS_MAC + // Check if Growl is installed (based on Qt's tray icon implementation) + CFURLRef cfurl; + OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl); + if (status != kLSApplicationNotFoundErr) { + CFBundleRef bundle = CFBundleCreate(0, cfurl); + if (CFStringCompare(CFBundleGetIdentifier(bundle), CFSTR("com.Growl.GrowlHelperApp"), kCFCompareCaseInsensitive | kCFCompareBackwards) == kCFCompareEqualTo) { + if (CFStringHasSuffix(CFURLGetString(cfurl), CFSTR("/Growl.app/"))) + mode = Growl13; + else + mode = Growl12; + } + CFRelease(cfurl); + CFRelease(bundle); + } +#endif +} + +Notificator::~Notificator() +{ +#ifdef USE_DBUS + delete interface; +#endif +} + +#ifdef USE_DBUS + +// Loosely based on http://www.qtcentre.org/archive/index.php/t-25879.html +class FreedesktopImage +{ +public: + FreedesktopImage() {} + FreedesktopImage(const QImage &img); + + static int metaType(); + + // Image to variant that can be marshaled over DBus + static QVariant toVariant(const QImage &img); + +private: + int width, height, stride; + bool hasAlpha; + int channels; + int bitsPerSample; + QByteArray image; + + friend QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i); + friend const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i); +}; + +Q_DECLARE_METATYPE(FreedesktopImage); + +// Image configuration settings +const int CHANNELS = 4; +const int BYTES_PER_PIXEL = 4; +const int BITS_PER_SAMPLE = 8; + +FreedesktopImage::FreedesktopImage(const QImage &img): + width(img.width()), + height(img.height()), + stride(img.width() * BYTES_PER_PIXEL), + hasAlpha(true), + channels(CHANNELS), + bitsPerSample(BITS_PER_SAMPLE) +{ + // Convert 00xAARRGGBB to RGBA bytewise (endian-independent) format + QImage tmp = img.convertToFormat(QImage::Format_ARGB32); + const uint32_t *data = reinterpret_cast(tmp.constBits()); + + unsigned int num_pixels = width * height; + image.resize(num_pixels * BYTES_PER_PIXEL); + + for(unsigned int ptr = 0; ptr < num_pixels; ++ptr) + { + image[ptr*BYTES_PER_PIXEL+0] = data[ptr] >> 16; // R + image[ptr*BYTES_PER_PIXEL+1] = data[ptr] >> 8; // G + image[ptr*BYTES_PER_PIXEL+2] = data[ptr]; // B + image[ptr*BYTES_PER_PIXEL+3] = data[ptr] >> 24; // A + } +} + +QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i) +{ + a.beginStructure(); + a << i.width << i.height << i.stride << i.hasAlpha << i.bitsPerSample << i.channels << i.image; + a.endStructure(); + return a; +} + +const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i) +{ + a.beginStructure(); + a >> i.width >> i.height >> i.stride >> i.hasAlpha >> i.bitsPerSample >> i.channels >> i.image; + a.endStructure(); + return a; +} + +int FreedesktopImage::metaType() +{ + return qDBusRegisterMetaType(); +} + +QVariant FreedesktopImage::toVariant(const QImage &img) +{ + FreedesktopImage fimg(img); + return QVariant(FreedesktopImage::metaType(), &fimg); +} + +void Notificator::notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + Q_UNUSED(cls); + // Arguments for DBus call: + QList args; + + // Program Name: + args.append(programName); + + // Unique ID of this notification type: + args.append(0U); + + // Application Icon, empty string + args.append(QString()); + + // Summary + args.append(title); + + // Body + args.append(text); + + // Actions (none, actions are deprecated) + QStringList actions; + args.append(actions); + + // Hints + QVariantMap hints; + + // If no icon specified, set icon based on class + QIcon tmpicon; + if(icon.isNull()) + { + QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion; + switch(cls) + { + case Information: sicon = QStyle::SP_MessageBoxInformation; break; + case Warning: sicon = QStyle::SP_MessageBoxWarning; break; + case Critical: sicon = QStyle::SP_MessageBoxCritical; break; + default: break; + } + tmpicon = QApplication::style()->standardIcon(sicon); + } + else + { + tmpicon = icon; + } + hints["icon_data"] = FreedesktopImage::toVariant(tmpicon.pixmap(FREEDESKTOP_NOTIFICATION_ICON_SIZE).toImage()); + args.append(hints); + + // Timeout (in msec) + args.append(millisTimeout); + + // "Fire and forget" + interface->callWithArgumentList(QDBus::NoBlock, "Notify", args); +} +#endif + +void Notificator::notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + Q_UNUSED(icon); + QSystemTrayIcon::MessageIcon sicon = QSystemTrayIcon::NoIcon; + switch(cls) // Set icon based on class + { + case Information: sicon = QSystemTrayIcon::Information; break; + case Warning: sicon = QSystemTrayIcon::Warning; break; + case Critical: sicon = QSystemTrayIcon::Critical; break; + } + trayIcon->showMessage(title, text, sicon, millisTimeout); +} + +// Based on Qt's tray icon implementation +#ifdef Q_WS_MAC +void Notificator::notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon) +{ + const QString script( + "tell application \"%5\"\n" + " set the allNotificationsList to {\"Notification\"}\n" // -- Make a list of all the notification types (all) + " set the enabledNotificationsList to {\"Notification\"}\n" // -- Make a list of the notifications (enabled) + " register as application \"%1\" all notifications allNotificationsList default notifications enabledNotificationsList\n" // -- Register our script with Growl + " notify with name \"Notification\" title \"%2\" description \"%3\" application name \"%1\"%4\n" // -- Send a Notification + "end tell" + ); + + QString notificationApp(QApplication::applicationName()); + if (notificationApp.isEmpty()) + notificationApp = "Application"; + + QPixmap notificationIconPixmap; + if (icon.isNull()) { // If no icon specified, set icon based on class + QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion; + switch (cls) + { + case Information: sicon = QStyle::SP_MessageBoxInformation; break; + case Warning: sicon = QStyle::SP_MessageBoxWarning; break; + case Critical: sicon = QStyle::SP_MessageBoxCritical; break; + } + notificationIconPixmap = QApplication::style()->standardPixmap(sicon); + } + else { + QSize size = icon.actualSize(QSize(48, 48)); + notificationIconPixmap = icon.pixmap(size); + } + + QString notificationIcon; + QTemporaryFile notificationIconFile; + if (!notificationIconPixmap.isNull() && notificationIconFile.open()) { + QImageWriter writer(¬ificationIconFile, "PNG"); + if (writer.write(notificationIconPixmap.toImage())) + notificationIcon = QString(" image from location \"file://%1\"").arg(notificationIconFile.fileName()); + } + + QString quotedTitle(title), quotedText(text); + quotedTitle.replace("\\", "\\\\").replace("\"", "\\"); + quotedText.replace("\\", "\\\\").replace("\"", "\\"); + QString growlApp(this->mode == Notificator::Growl13 ? "Growl" : "GrowlHelperApp"); + qt_mac_execute_apple_script(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp), 0); +} +#endif + +void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + switch(mode) + { +#ifdef USE_DBUS + case Freedesktop: + notifyDBus(cls, title, text, icon, millisTimeout); + break; +#endif + case QSystemTray: + notifySystray(cls, title, text, icon, millisTimeout); + break; +#ifdef Q_WS_MAC + case Growl12: + case Growl13: + notifyGrowl(cls, title, text, icon); + break; +#endif + default: + if(cls == Critical) + { + // Fall back to old fashioned popup dialog if critical and no other notification available + QMessageBox::critical(parent, title, text, QMessageBox::Ok, QMessageBox::Ok); + } + break; + } +} diff --git a/src/qt/notificator.h b/src/qt/notificator.h new file mode 100644 index 0000000..0271c26 --- /dev/null +++ b/src/qt/notificator.h @@ -0,0 +1,69 @@ +#ifndef NOTIFICATOR_H +#define NOTIFICATOR_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QSystemTrayIcon; +#ifdef USE_DBUS +class QDBusInterface; +#endif +QT_END_NAMESPACE + +/** Cross-platform desktop notification client. */ +class Notificator: public QObject +{ + Q_OBJECT +public: + /** Create a new notificator. + @note Ownership of trayIcon is not transferred to this object. + */ + Notificator(const QString &programName=QString(), QSystemTrayIcon *trayIcon=0, QWidget *parent=0); + ~Notificator(); + + // Message class + enum Class + { + Information, /**< Informational message */ + Warning, /**< Notify user of potential problem */ + Critical /**< An error occured */ + }; + +public slots: + + /** Show notification message. + @param[in] cls general message class + @param[in] title title shown with message + @param[in] text message content + @param[in] icon optional icon to show with message + @param[in] millisTimeout notification timeout in milliseconds (defaults to 10 seconds) + @note Platform implementations are free to ignore any of the provided fields except for \a text. + */ + void notify(Class cls, const QString &title, const QString &text, + const QIcon &icon = QIcon(), int millisTimeout = 10000); + +private: + QWidget *parent; + enum Mode { + None, /**< Ignore informational notifications, and show a modal pop-up dialog for Critical notifications. */ + Freedesktop, /**< Use DBus org.freedesktop.Notifications */ + QSystemTray, /**< Use QSystemTray::showMessage */ + Growl12, /**< Use the Growl 1.2 notification system (Mac only) */ + Growl13 /**< Use the Growl 1.3 notification system (Mac only) */ + }; + QString programName; + Mode mode; + QSystemTrayIcon *trayIcon; +#ifdef USE_DBUS + QDBusInterface *interface; + + void notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); +#endif + void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); +#ifdef Q_WS_MAC + void notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon); +#endif +}; + +#endif // NOTIFICATOR_H diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp new file mode 100644 index 0000000..da93671 --- /dev/null +++ b/src/qt/optionsdialog.cpp @@ -0,0 +1,241 @@ +#include "optionsdialog.h" +#include "ui_optionsdialog.h" + +#include "bitcoinamountfield.h" +#include "bitcoinunits.h" +#include "monitoreddatamapper.h" +#include "netbase.h" +#include "optionsmodel.h" +#include "qvalidatedlineedit.h" +#include "qvaluecombobox.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +OptionsDialog::OptionsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::OptionsDialog), + model(0), + mapper(0), + fRestartWarningDisplayed_Proxy(false), + fRestartWarningDisplayed_Lang(false), + fProxyIpValid(true) +{ + ui->setupUi(this); + + /* Network elements init */ +#ifndef USE_UPNP + ui->mapPortUpnp->setEnabled(false); +#endif + + ui->socksVersion->setEnabled(false); + ui->socksVersion->addItem("5", 5); + ui->socksVersion->addItem("4", 4); + ui->socksVersion->setCurrentIndex(0); + + ui->proxyIp->setEnabled(false); + ui->proxyPort->setEnabled(false); + ui->proxyPort->setValidator(new QIntValidator(0, 65535, this)); + + 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))); + + ui->proxyIp->installEventFilter(this); + + /* Window elements init */ +#ifdef Q_WS_MAC + ui->tabWindow->setVisible(false); +#endif + + /* Display elements init */ + QDir translations(":translations"); + ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant("")); + foreach(const QString &langStr, translations.entryList()) + { + QLocale locale(langStr); + + /** check if the locale name consists of 2 parts (language_country) */ + if(langStr.contains("_")) + { +#if QT_VERSION >= 0x040800 + /** display language strings as "native language - native country (locale name)", e.g. "Deutsch - Deutschland (de)" */ + ui->lang->addItem(locale.nativeLanguageName() + QString(" - ") + locale.nativeCountryName() + QString(" (") + langStr + QString(")"), QVariant(langStr)); +#else + /** display language strings as "language - country (locale name)", e.g. "German - Germany (de)" */ + ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" - ") + QLocale::countryToString(locale.country()) + QString(" (") + langStr + QString(")"), QVariant(langStr)); +#endif + } + else + { +#if QT_VERSION >= 0x040800 + /** display language strings as "native language (locale name)", e.g. "Deutsch (de)" */ + ui->lang->addItem(locale.nativeLanguageName() + QString(" (") + langStr + QString(")"), QVariant(langStr)); +#else + /** display language strings as "language (locale name)", e.g. "German (de)" */ + ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" (") + langStr + QString(")"), QVariant(langStr)); +#endif + } + } + + ui->unit->setModel(new BitcoinUnits(this)); + + 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 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; + + if(model) + { + connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + + mapper->setModel(model); + setMapper(); + mapper->toFirst(); + } + + // update the display unit, to not use the default ("BTC") + updateDisplayUnit(); +} + +void OptionsDialog::setMapper() +{ + /* 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::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::on_cancelButton_clicked() +{ + reject(); +} + +void OptionsDialog::on_applyButton_clicked() +{ + mapper->submit(); + ui->applyButton->setEnabled(false); +} + +void OptionsDialog::showRestartWarning_Proxy() +{ + if(!fRestartWarningDisplayed_Proxy) + { + QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting CasinoCoin."), QMessageBox::Ok); + fRestartWarningDisplayed_Proxy = true; + } +} + +void OptionsDialog::showRestartWarning_Lang() +{ + if(!fRestartWarningDisplayed_Lang) + { + QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting CasinoCoin."), QMessageBox::Ok); + fRestartWarningDisplayed_Lang = true; + } +} + +void OptionsDialog::updateDisplayUnit() +{ + if(model) + { + // Update transactionFee with the current unit + ui->transactionFee->setDisplayUnit(model->getDisplayUnit()); + } +} + +bool OptionsDialog::eventFilter(QObject *object, QEvent *event) +{ + 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); +} diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h new file mode 100644 index 0000000..7e91c96 --- /dev/null +++ b/src/qt/optionsdialog.h @@ -0,0 +1,54 @@ +#ifndef OPTIONSDIALOG_H +#define OPTIONSDIALOG_H + +#include + +namespace Ui { +class OptionsDialog; +} +class OptionsModel; +class MonitoredDataMapper; + +/** Preferences dialog. */ +class OptionsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit OptionsDialog(QWidget *parent = 0); + ~OptionsDialog(); + + void setModel(OptionsModel *model); + void setMapper(); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private slots: + /* 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: + Ui::OptionsDialog *ui; + OptionsModel *model; + MonitoredDataMapper *mapper; + bool fRestartWarningDisplayed_Proxy; + bool fRestartWarningDisplayed_Lang; + bool fProxyIpValid; +}; + +#endif // OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp new file mode 100644 index 0000000..caa3341 --- /dev/null +++ b/src/qt/optionsmodel.cpp @@ -0,0 +1,284 @@ +#include "optionsmodel.h" +#include "bitcoinunits.h" +#include + +#include "init.h" +#include "walletdb.h" +#include "guiutil.h" + +OptionsModel::OptionsModel(QObject *parent) : + QAbstractListModel(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; + + // These are Qt-only settings: + nDisplayUnit = settings.value("nDisplayUnit", BitcoinUnits::BTC).toInt(); + bDisplayAddresses = settings.value("bDisplayAddresses", false).toBool(); + fMinimizeToTray = settings.value("fMinimizeToTray", false).toBool(); + fMinimizeOnClose = settings.value("fMinimizeOnClose", false).toBool(); + nTransactionFee = settings.value("nTransactionFee").toLongLong(); + language = settings.value("language", "").toString(); + + // These are shared with core Bitcoin; we want + // command-line options to override the GUI settings: + if (settings.contains("fUseUPnP")) + 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()) + SoftSetArg("-lang", language.toStdString()); +} + +bool OptionsModel::Upgrade() +{ + QSettings settings; + + if (settings.contains("bImportFinished")) + return false; // Already upgraded + + settings.setValue("bImportFinished", true); + + // Move settings from old wallet.dat (if any): + CWalletDB walletdb("wallet.dat"); + + QList intOptions; + intOptions << "nDisplayUnit" << "nTransactionFee"; + foreach(QString key, intOptions) + { + int value = 0; + if (walletdb.ReadSetting(key.toStdString(), value)) + { + settings.setValue(key, value); + walletdb.EraseSetting(key.toStdString()); + } + } + QList boolOptions; + boolOptions << "bDisplayAddresses" << "fMinimizeToTray" << "fMinimizeOnClose" << "fUseProxy" << "fUseUPnP"; + foreach(QString key, boolOptions) + { + bool value = false; + if (walletdb.ReadSetting(key.toStdString(), value)) + { + settings.setValue(key, value); + walletdb.EraseSetting(key.toStdString()); + } + } + try + { + CAddress addrProxyAddress; + if (walletdb.ReadSetting("addrProxy", addrProxyAddress)) + { + 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; +} + + +int OptionsModel::rowCount(const QModelIndex & parent) const +{ + return OptionIDRowCount; +} + +QVariant OptionsModel::data(const QModelIndex & index, int role) const +{ + if(role == Qt::EditRole) + { + QSettings settings; + switch(index.row()) + { + case StartAtStartup: + return QVariant(GUIUtil::GetStartOnSystemStartup()); + case MinimizeToTray: + return QVariant(fMinimizeToTray); + case MapPortUPnP: + return settings.value("fUseUPnP", GetBoolArg("-upnp", true)); + case MinimizeOnClose: + return QVariant(fMinimizeOnClose); + case ProxyUse: + return settings.value("fUseProxy", false); + case ProxyIP: { + CService addrProxy; + if (GetProxy(NET_IPV4, addrProxy)) + return QVariant(QString::fromStdString(addrProxy.ToStringIP())); + 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 ProxySocksVersion: + return settings.value("nSocksVersion", 5); + case Fee: + return QVariant(nTransactionFee); + case DisplayUnit: + return QVariant(nDisplayUnit); + case DisplayAddresses: + return QVariant(bDisplayAddresses); + case DetachDatabases: + return QVariant(bitdb.GetDetach()); + case Language: + return settings.value("language", ""); + default: + return QVariant(); + } + } + return QVariant(); +} +bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role) +{ + bool successful = true; /* set to false on parse error */ + if(role == Qt::EditRole) + { + QSettings settings; + switch(index.row()) + { + case StartAtStartup: + successful = GUIUtil::SetStartOnSystemStartup(value.toBool()); + break; + case MinimizeToTray: + fMinimizeToTray = value.toBool(); + settings.setValue("fMinimizeToTray", fMinimizeToTray); + break; + case MapPortUPnP: + fUseUPnP = value.toBool(); + settings.setValue("fUseUPnP", fUseUPnP); + MapPort(); + break; + case MinimizeOnClose: + fMinimizeOnClose = value.toBool(); + settings.setValue("fMinimizeOnClose", fMinimizeOnClose); + break; + case ProxyUse: + settings.setValue("fUseProxy", value.toBool()); + ApplyProxySettings(); + break; + case ProxyIP: + { + CService addrProxy("127.0.0.1", 9050); + GetProxy(NET_IPV4, addrProxy); + CNetAddr addr(value.toString().toStdString()); + addrProxy.SetIP(addr); + settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str()); + successful = ApplyProxySettings(); + } + break; + case ProxyPort: + { + CService addrProxy("127.0.0.1", 9050); + GetProxy(NET_IPV4, addrProxy); + addrProxy.SetPort(value.toInt()); + settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str()); + successful = ApplyProxySettings(); + } + break; + case ProxySocksVersion: + settings.setValue("nSocksVersion", value.toInt()); + ApplyProxySettings(); + break; + case Fee: + nTransactionFee = value.toLongLong(); + settings.setValue("nTransactionFee", nTransactionFee); + break; + case DisplayUnit: + nDisplayUnit = value.toInt(); + settings.setValue("nDisplayUnit", nDisplayUnit); + emit displayUnitChanged(nDisplayUnit); + break; + case DisplayAddresses: + bDisplayAddresses = value.toBool(); + settings.setValue("bDisplayAddresses", bDisplayAddresses); + break; + case DetachDatabases: { + bool fDetachDB = value.toBool(); + bitdb.SetDetach(fDetachDB); + settings.setValue("detachDB", fDetachDB); + } + break; + case Language: + settings.setValue("language", value); + break; + default: + break; + } + } + emit dataChanged(index, index); + + return successful; +} + +qint64 OptionsModel::getTransactionFee() +{ + return nTransactionFee; +} + +bool OptionsModel::getMinimizeToTray() +{ + return fMinimizeToTray; +} + +bool OptionsModel::getMinimizeOnClose() +{ + return fMinimizeOnClose; +} + +int OptionsModel::getDisplayUnit() +{ + return nDisplayUnit; +} + +bool OptionsModel::getDisplayAddresses() +{ + return bDisplayAddresses; +} diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h new file mode 100644 index 0000000..34724ad --- /dev/null +++ b/src/qt/optionsmodel.h @@ -0,0 +1,64 @@ +#ifndef OPTIONSMODEL_H +#define OPTIONSMODEL_H + +#include + +/** Interface from Qt to configuration data structure for Bitcoin client. + To Qt, the options are presented as a list with the different options + laid out vertically. + This can be changed to a tree once the settings become sufficiently + complex. + */ +class OptionsModel : public QAbstractListModel +{ + Q_OBJECT + +public: + explicit OptionsModel(QObject *parent = 0); + + enum OptionID { + StartAtStartup, // bool + MinimizeToTray, // bool + MapPortUPnP, // bool + MinimizeOnClose, // bool + ProxyUse, // bool + ProxyIP, // QString + ProxyPort, // int + ProxySocksVersion, // int + Fee, // qint64 + DisplayUnit, // BitcoinUnits::Unit + DisplayAddresses, // bool + DetachDatabases, // bool + Language, // QString + OptionIDRowCount, + }; + + void Init(); + + /* Migrate settings from wallet.dat after app initialization */ + bool Upgrade(); /* returns true if settings upgraded */ + + int rowCount(const QModelIndex & parent = QModelIndex()) const; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); + + /* Explicit getters */ + qint64 getTransactionFee(); + bool getMinimizeToTray(); + bool getMinimizeOnClose(); + int getDisplayUnit(); + bool getDisplayAddresses(); + QString getLanguage() { return language; } + +private: + int nDisplayUnit; + bool bDisplayAddresses; + bool fMinimizeToTray; + bool fMinimizeOnClose; + QString language; + +signals: + void displayUnitChanged(int unit); +}; + +#endif // OPTIONSMODEL_H diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp new file mode 100644 index 0000000..aa93bda --- /dev/null +++ b/src/qt/overviewpage.cpp @@ -0,0 +1,200 @@ +#include "overviewpage.h" +#include "ui_overviewpage.h" + +#include "walletmodel.h" +#include "bitcoinunits.h" +#include "optionsmodel.h" +#include "transactiontablemodel.h" +#include "transactionfilterproxy.h" +#include "guiutil.h" +#include "guiconstants.h" + +#include +#include + +#define DECORATION_SIZE 64 +#define NUM_ITEMS 3 + +class TxViewDelegate : public QAbstractItemDelegate +{ + Q_OBJECT +public: + TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC) + { + + } + + inline void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index ) const + { + painter->save(); + + QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); + QRect mainRect = option.rect; + QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE)); + int xspace = DECORATION_SIZE + 8; + int ypad = 6; + int halfheight = (mainRect.height() - 2*ypad)/2; + QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight); + QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight); + icon.paint(painter, decorationRect); + + QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime(); + QString address = index.data(Qt::DisplayRole).toString(); + qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong(); + bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool(); + QVariant value = index.data(Qt::ForegroundRole); + QColor foreground = option.palette.color(QPalette::Text); + if(qVariantCanConvert(value)) + { + foreground = qvariant_cast(value); + } + + painter->setPen(foreground); + painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address); + + if(amount < 0) + { + foreground = COLOR_NEGATIVE; + } + else if(!confirmed) + { + foreground = COLOR_UNCONFIRMED; + } + else + { + foreground = option.palette.color(QPalette::Text); + } + painter->setPen(foreground); + QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true); + if(!confirmed) + { + amountText = QString("[") + amountText + QString("]"); + } + painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText); + + painter->setPen(option.palette.color(QPalette::Text)); + painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date)); + + painter->restore(); + } + + inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + { + return QSize(DECORATION_SIZE, DECORATION_SIZE); + } + + int unit; + +}; +#include "overviewpage.moc" + +OverviewPage::OverviewPage(QWidget *parent) : + QWidget(parent), + ui(new Ui::OverviewPage), + currentBalance(-1), + currentUnconfirmedBalance(-1), + currentImmatureBalance(-1), + txdelegate(new TxViewDelegate()), + filter(0) +{ + ui->setupUi(this); + + // Recent transactions + ui->listTransactions->setItemDelegate(txdelegate); + ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE)); + ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2)); + ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false); + + connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex))); + + // init "out of sync" warning labels + ui->labelWalletStatus->setText("(" + tr("Out of sync") + ")"); + ui->labelTransactionsStatus->setText("(" + tr("Out of sync") + ")"); + + // start with displaying the "out of sync" warnings + showOutOfSyncWarning(true); +} + +void OverviewPage::handleTransactionClicked(const QModelIndex &index) +{ + if(filter) + emit transactionClicked(filter->mapToSource(index)); +} + +OverviewPage::~OverviewPage() +{ + delete ui; +} + +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) +{ + ui->labelNumTransactions->setText(QLocale::system().toString(count)); +} + +void OverviewPage::setModel(WalletModel *model) +{ + this->model = model; + if(model && model->getOptionsModel()) + { + // Set up transaction list + filter = new TransactionFilterProxy(); + filter->setSourceModel(model->getTransactionTableModel()); + filter->setLimit(NUM_ITEMS); + filter->setDynamicSortFilter(true); + filter->setSortRole(Qt::EditRole); + filter->sort(TransactionTableModel::Status, Qt::DescendingOrder); + + ui->listTransactions->setModel(filter); + ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); + + // Keep up to date with wallet + 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))); + + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + } + + // update the display unit, to not use the default ("CSC") + updateDisplayUnit(); +} + +void OverviewPage::updateDisplayUnit() +{ + if(model && model->getOptionsModel()) + { + if(currentBalance != -1) + setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance); + + // Update txdelegate->unit with the current unit + txdelegate->unit = model->getOptionsModel()->getDisplayUnit(); + + ui->listTransactions->update(); + } +} + +void OverviewPage::showOutOfSyncWarning(bool fShow) +{ + ui->labelWalletStatus->setVisible(fShow); + ui->labelTransactionsStatus->setVisible(fShow); +} diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h new file mode 100644 index 0000000..00048cc --- /dev/null +++ b/src/qt/overviewpage.h @@ -0,0 +1,51 @@ +#ifndef OVERVIEWPAGE_H +#define OVERVIEWPAGE_H + +#include + +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE + +namespace Ui { + class OverviewPage; +} +class WalletModel; +class TxViewDelegate; +class TransactionFilterProxy; + +/** Overview ("home") page widget */ +class OverviewPage : public QWidget +{ + Q_OBJECT + +public: + explicit OverviewPage(QWidget *parent = 0); + ~OverviewPage(); + + void setModel(WalletModel *model); + void showOutOfSyncWarning(bool fShow); + +public slots: + void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance); + void setNumTransactions(int count); + +signals: + void transactionClicked(const QModelIndex &index); + +private: + Ui::OverviewPage *ui; + WalletModel *model; + qint64 currentBalance; + qint64 currentUnconfirmedBalance; + qint64 currentImmatureBalance; + + TxViewDelegate *txdelegate; + TransactionFilterProxy *filter; + +private slots: + void updateDisplayUnit(); + void handleTransactionClicked(const QModelIndex &index); +}; + +#endif // OVERVIEWPAGE_H diff --git a/src/qt/qrcodedialog.cpp b/src/qt/qrcodedialog.cpp new file mode 100644 index 0000000..e1c8beb --- /dev/null +++ b/src/qt/qrcodedialog.cpp @@ -0,0 +1,171 @@ +#include "qrcodedialog.h" +#include "ui_qrcodedialog.h" + +#include "bitcoinunits.h" +#include "guiconstants.h" +#include "guiutil.h" +#include "optionsmodel.h" + +#include +#include + +#include + +QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent) : + QDialog(parent), + ui(new Ui::QRCodeDialog), + model(0), + address(addr) +{ + ui->setupUi(this); + + setWindowTitle(QString("%1").arg(address)); + + ui->chkReqPayment->setVisible(enableReq); + ui->lblAmount->setVisible(enableReq); + ui->lnReqAmount->setVisible(enableReq); + + ui->lnLabel->setText(label); + + ui->btnSaveAs->setEnabled(false); + + genCode(); +} + +QRCodeDialog::~QRCodeDialog() +{ + delete ui; +} + +void QRCodeDialog::setModel(OptionsModel *model) +{ + this->model = model; + + if (model) + connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + + // update the display unit, to not use the default ("BTC") + updateDisplayUnit(); +} + +void QRCodeDialog::genCode() +{ + QString uri = getURI(); + + if (uri != "") + { + ui->lblQRCode->setText(""); + + QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1); + if (!code) + { + ui->lblQRCode->setText(tr("Error encoding URI into QR Code.")); + return; + } + myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + myImage.fill(0xffffff); + unsigned char *p = code->data; + for (int y = 0; y < code->width; y++) + { + for (int x = 0; x < code->width; x++) + { + myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + p++; + } + } + QRcode_free(code); + + ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300)); + + ui->outUri->setPlainText(uri); + } +} + +QString QRCodeDialog::getURI() +{ + QString ret = QString("casinocoin:%1").arg(address); + int paramCount = 0; + + ui->outUri->clear(); + + if (ui->chkReqPayment->isChecked()) + { + if (ui->lnReqAmount->validate()) + { + // even if we allow a non BTC unit input in lnReqAmount, we generate the URI with BTC as unit (as defined in BIP21) + ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, ui->lnReqAmount->value())); + paramCount++; + } + else + { + ui->btnSaveAs->setEnabled(false); + ui->lblQRCode->setText(tr("The entered amount is invalid, please check.")); + return QString(""); + } + } + + if (!ui->lnLabel->text().isEmpty()) + { + QString lbl(QUrl::toPercentEncoding(ui->lnLabel->text())); + ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl); + paramCount++; + } + + if (!ui->lnMessage->text().isEmpty()) + { + QString msg(QUrl::toPercentEncoding(ui->lnMessage->text())); + ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg); + paramCount++; + } + + // limit URI length to prevent a DoS against the QR-Code dialog + if (ret.length() > MAX_URI_LENGTH) + { + ui->btnSaveAs->setEnabled(false); + ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message.")); + return QString(""); + } + + ui->btnSaveAs->setEnabled(true); + return ret; +} + +void QRCodeDialog::on_lnReqAmount_textChanged() +{ + genCode(); +} + +void QRCodeDialog::on_lnLabel_textChanged() +{ + genCode(); +} + +void QRCodeDialog::on_lnMessage_textChanged() +{ + genCode(); +} + +void QRCodeDialog::on_btnSaveAs_clicked() +{ + QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Images (*.png)")); + if (!fn.isEmpty()) + myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn); +} + +void QRCodeDialog::on_chkReqPayment_toggled(bool fChecked) +{ + if (!fChecked) + // if chkReqPayment is not active, don't display lnReqAmount as invalid + ui->lnReqAmount->setValid(true); + + genCode(); +} + +void QRCodeDialog::updateDisplayUnit() +{ + if (model) + { + // Update lnReqAmount with the current unit + ui->lnReqAmount->setDisplayUnit(model->getDisplayUnit()); + } +} diff --git a/src/qt/qrcodedialog.h b/src/qt/qrcodedialog.h new file mode 100644 index 0000000..c55c34b --- /dev/null +++ b/src/qt/qrcodedialog.h @@ -0,0 +1,41 @@ +#ifndef QRCODEDIALOG_H +#define QRCODEDIALOG_H + +#include +#include + +namespace Ui { + class QRCodeDialog; +} +class OptionsModel; + +class QRCodeDialog : public QDialog +{ + Q_OBJECT + +public: + explicit QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent = 0); + ~QRCodeDialog(); + + void setModel(OptionsModel *model); + +private slots: + void on_lnReqAmount_textChanged(); + void on_lnLabel_textChanged(); + void on_lnMessage_textChanged(); + void on_btnSaveAs_clicked(); + void on_chkReqPayment_toggled(bool fChecked); + + void updateDisplayUnit(); + +private: + Ui::QRCodeDialog *ui; + OptionsModel *model; + QString address; + QImage myImage; + + void genCode(); + QString getURI(); +}; + +#endif // QRCODEDIALOG_H diff --git a/src/qt/qtipcserver.cpp b/src/qt/qtipcserver.cpp new file mode 100644 index 0000000..c4aa9a4 --- /dev/null +++ b/src/qt/qtipcserver.cpp @@ -0,0 +1,124 @@ +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include +#if defined(WIN32) && BOOST_VERSION == 104900 +#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME +#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME +#endif + +#include "qtipcserver.h" +#include "guiconstants.h" +#include "ui_interface.h" +#include "util.h" + +#include +#include +#include + +#if defined(WIN32) && (!defined(BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME) || !defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) || BOOST_VERSION < 104900) +#warning Compiling without BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME and BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME uncommented in boost/interprocess/detail/tmp_dir_helpers.hpp or using a boost version before 1.49 may have unintended results see svn.boost.org/trac/boost/ticket/5392 +#endif + +using namespace boost; +using namespace boost::interprocess; +using namespace boost::posix_time; + +static void ipcThread2(void* pArg); + +#ifdef MAC_OSX +// URI handling not implemented on OSX yet + +void ipcInit() { } + +#else + +static void ipcThread(void* pArg) +{ + IMPLEMENT_RANDOMIZE_STACK(ipcThread(pArg)); + + // Make this thread recognisable as the GUI-IPC thread + RenameThread("bitcoin-gui-ipc"); + + try + { + ipcThread2(pArg); + } + catch (std::exception& e) { + PrintExceptionContinue(&e, "ipcThread()"); + } catch (...) { + PrintExceptionContinue(NULL, "ipcThread()"); + } + printf("ipcThread exited\n"); +} + +static void ipcThread2(void* pArg) +{ + printf("ipcThread started\n"); + + message_queue* mq = (message_queue*)pArg; + char buffer[MAX_URI_LENGTH + 1] = ""; + size_t nSize = 0; + unsigned int nPriority = 0; + + loop + { + ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100); + if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d)) + { + uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize)); + Sleep(1000); + } + + if (fShutdown) + break; + } + + // Remove message queue + message_queue::remove(BITCOINURI_QUEUE_NAME); + // Cleanup allocated memory + delete mq; +} + +void ipcInit() +{ + message_queue* mq = NULL; + char buffer[MAX_URI_LENGTH + 1] = ""; + size_t nSize = 0; + unsigned int nPriority = 0; + + try { + mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH); + + // Make sure we don't lose any casinocoin: URIs + for (int i = 0; i < 2; i++) + { + ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1); + if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d)) + { + uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize)); + } + else + break; + } + + // Make sure only one casinocoin instance is listening + message_queue::remove(BITCOINURI_QUEUE_NAME); + delete mq; + + mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH); + } + catch (interprocess_exception &ex) { + printf("ipcInit() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); + return; + } + + if (!CreateThread(ipcThread, mq)) + { + delete mq; + return; + } +} + +#endif diff --git a/src/qt/qtipcserver.h b/src/qt/qtipcserver.h new file mode 100644 index 0000000..484b622 --- /dev/null +++ b/src/qt/qtipcserver.h @@ -0,0 +1,9 @@ +#ifndef QTIPCSERVER_H +#define QTIPCSERVER_H + +// Define Bitcoin-Qt message queue name +#define BITCOINURI_QUEUE_NAME "BitcoinURI" + +void ipcInit(); + +#endif // QTIPCSERVER_H diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp new file mode 100644 index 0000000..8ca230c --- /dev/null +++ b/src/qt/qvalidatedlineedit.cpp @@ -0,0 +1,45 @@ +#include "qvalidatedlineedit.h" + +#include "guiconstants.h" + +QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) : + QLineEdit(parent), valid(true) +{ + connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid())); +} + +void QValidatedLineEdit::setValid(bool valid) +{ + if(valid == this->valid) + { + return; + } + + if(valid) + { + setStyleSheet(""); + } + else + { + setStyleSheet(STYLE_INVALID); + } + this->valid = valid; +} + +void QValidatedLineEdit::focusInEvent(QFocusEvent *evt) +{ + // Clear invalid flag on focus + setValid(true); + QLineEdit::focusInEvent(evt); +} + +void QValidatedLineEdit::markValid() +{ + setValid(true); +} + +void QValidatedLineEdit::clear() +{ + setValid(true); + QLineEdit::clear(); +} diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h new file mode 100644 index 0000000..66e26be --- /dev/null +++ b/src/qt/qvalidatedlineedit.h @@ -0,0 +1,29 @@ +#ifndef QVALIDATEDLINEEDIT_H +#define QVALIDATEDLINEEDIT_H + +#include + +/** Line edit that can be marked as "invalid" to show input validation feedback. When marked as invalid, + it will get a red background until it is focused. + */ +class QValidatedLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit QValidatedLineEdit(QWidget *parent = 0); + void clear(); + +protected: + void focusInEvent(QFocusEvent *evt); + +private: + bool valid; + +public slots: + void setValid(bool valid); + +private slots: + void markValid(); +}; + +#endif // QVALIDATEDLINEEDIT_H diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp new file mode 100644 index 0000000..d7ce3d0 --- /dev/null +++ b/src/qt/qvaluecombobox.cpp @@ -0,0 +1,27 @@ +#include "qvaluecombobox.h" + +QValueComboBox::QValueComboBox(QWidget *parent) : + QComboBox(parent), role(Qt::UserRole) +{ + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(handleSelectionChanged(int))); +} + +QVariant QValueComboBox::value() const +{ + return itemData(currentIndex(), role); +} + +void QValueComboBox::setValue(const QVariant &value) +{ + setCurrentIndex(findData(value, role)); +} + +void QValueComboBox::setRole(int role) +{ + this->role = role; +} + +void QValueComboBox::handleSelectionChanged(int idx) +{ + emit valueChanged(); +} diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h new file mode 100644 index 0000000..1a47bb6 --- /dev/null +++ b/src/qt/qvaluecombobox.h @@ -0,0 +1,33 @@ +#ifndef QVALUECOMBOBOX_H +#define QVALUECOMBOBOX_H + +#include +#include + +/* QComboBox that can be used with QDataWidgetMapper to select ordinal values from a model. */ +class QValueComboBox : public QComboBox +{ + Q_OBJECT + Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true) +public: + explicit QValueComboBox(QWidget *parent = 0); + + QVariant value() const; + void setValue(const QVariant &value); + + /** Specify model role to use as ordinal value (defaults to Qt::UserRole) */ + void setRole(int role); + +signals: + void valueChanged(); + +public slots: + +private: + int role; + +private slots: + void handleSelectionChanged(int idx); +}; + +#endif // QVALUECOMBOBOX_H diff --git a/src/qt/res/bitcoin-qt.rc b/src/qt/res/bitcoin-qt.rc new file mode 100644 index 0000000..1a1ab53 --- /dev/null +++ b/src/qt/res/bitcoin-qt.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico" diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png new file mode 100644 index 0000000..f98e2a8 Binary files /dev/null and b/src/qt/res/icons/add.png differ diff --git a/src/qt/res/icons/address-book.png b/src/qt/res/icons/address-book.png new file mode 100644 index 0000000..a969997 Binary files /dev/null and b/src/qt/res/icons/address-book.png differ diff --git a/src/qt/res/icons/bitcoin.icns b/src/qt/res/icons/bitcoin.icns new file mode 100644 index 0000000..cf9ccec Binary files /dev/null and b/src/qt/res/icons/bitcoin.icns differ diff --git a/src/qt/res/icons/bitcoin.ico b/src/qt/res/icons/bitcoin.ico new file mode 100644 index 0000000..9434002 Binary files /dev/null and b/src/qt/res/icons/bitcoin.ico differ diff --git a/src/qt/res/icons/bitcoin.png b/src/qt/res/icons/bitcoin.png new file mode 100644 index 0000000..930156f Binary files /dev/null and b/src/qt/res/icons/bitcoin.png differ diff --git a/src/qt/res/icons/bitcoin_testnet.png b/src/qt/res/icons/bitcoin_testnet.png new file mode 100644 index 0000000..ca26832 Binary files /dev/null and b/src/qt/res/icons/bitcoin_testnet.png differ diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png new file mode 100644 index 0000000..448e47f Binary files /dev/null and b/src/qt/res/icons/clock1.png differ diff --git a/src/qt/res/icons/clock2.png b/src/qt/res/icons/clock2.png new file mode 100644 index 0000000..c1a6e99 Binary files /dev/null and b/src/qt/res/icons/clock2.png differ diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png new file mode 100644 index 0000000..e429a40 Binary files /dev/null and b/src/qt/res/icons/clock3.png differ diff --git a/src/qt/res/icons/clock4.png b/src/qt/res/icons/clock4.png new file mode 100644 index 0000000..ba036f4 Binary files /dev/null and b/src/qt/res/icons/clock4.png differ diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png new file mode 100644 index 0000000..411d7a7 Binary files /dev/null and b/src/qt/res/icons/clock5.png differ diff --git a/src/qt/res/icons/configure.png b/src/qt/res/icons/configure.png new file mode 100644 index 0000000..95bd319 Binary files /dev/null and b/src/qt/res/icons/configure.png differ diff --git a/src/qt/res/icons/connect0_16.png b/src/qt/res/icons/connect0_16.png new file mode 100644 index 0000000..66f3ae4 Binary files /dev/null and b/src/qt/res/icons/connect0_16.png differ diff --git a/src/qt/res/icons/connect1_16.png b/src/qt/res/icons/connect1_16.png new file mode 100644 index 0000000..76000be Binary files /dev/null and b/src/qt/res/icons/connect1_16.png differ diff --git a/src/qt/res/icons/connect2_16.png b/src/qt/res/icons/connect2_16.png new file mode 100644 index 0000000..6d9a372 Binary files /dev/null and b/src/qt/res/icons/connect2_16.png differ diff --git a/src/qt/res/icons/connect3_16.png b/src/qt/res/icons/connect3_16.png new file mode 100644 index 0000000..a211700 Binary files /dev/null and b/src/qt/res/icons/connect3_16.png differ diff --git a/src/qt/res/icons/connect4_16.png b/src/qt/res/icons/connect4_16.png new file mode 100644 index 0000000..c1232f5 Binary files /dev/null and b/src/qt/res/icons/connect4_16.png differ diff --git a/src/qt/res/icons/debugwindow.png b/src/qt/res/icons/debugwindow.png new file mode 100644 index 0000000..1712adf Binary files /dev/null and b/src/qt/res/icons/debugwindow.png differ diff --git a/src/qt/res/icons/edit.png b/src/qt/res/icons/edit.png new file mode 100644 index 0000000..1d69145 Binary files /dev/null and b/src/qt/res/icons/edit.png differ diff --git a/src/qt/res/icons/editcopy.png b/src/qt/res/icons/editcopy.png new file mode 100644 index 0000000..f882aa2 Binary files /dev/null and b/src/qt/res/icons/editcopy.png differ diff --git a/src/qt/res/icons/editpaste.png b/src/qt/res/icons/editpaste.png new file mode 100644 index 0000000..a192060 Binary files /dev/null and b/src/qt/res/icons/editpaste.png differ diff --git a/src/qt/res/icons/export.png b/src/qt/res/icons/export.png new file mode 100644 index 0000000..5c17cab Binary files /dev/null and b/src/qt/res/icons/export.png differ diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png new file mode 100644 index 0000000..ae13a15 Binary files /dev/null and b/src/qt/res/icons/filesave.png differ diff --git a/src/qt/res/icons/history.png b/src/qt/res/icons/history.png new file mode 100644 index 0000000..6c460f7 Binary files /dev/null and b/src/qt/res/icons/history.png differ diff --git a/src/qt/res/icons/key.png b/src/qt/res/icons/key.png new file mode 100644 index 0000000..ece0164 Binary files /dev/null and b/src/qt/res/icons/key.png differ diff --git a/src/qt/res/icons/lock_closed.png b/src/qt/res/icons/lock_closed.png new file mode 100644 index 0000000..c566510 Binary files /dev/null and b/src/qt/res/icons/lock_closed.png differ diff --git a/src/qt/res/icons/lock_open.png b/src/qt/res/icons/lock_open.png new file mode 100644 index 0000000..c98ca86 Binary files /dev/null and b/src/qt/res/icons/lock_open.png differ diff --git a/src/qt/res/icons/mining.png b/src/qt/res/icons/mining.png new file mode 100644 index 0000000..72b067a Binary files /dev/null and b/src/qt/res/icons/mining.png differ diff --git a/src/qt/res/icons/mining_active.png b/src/qt/res/icons/mining_active.png new file mode 100644 index 0000000..af91858 Binary files /dev/null and b/src/qt/res/icons/mining_active.png differ diff --git a/src/qt/res/icons/mining_inactive.png b/src/qt/res/icons/mining_inactive.png new file mode 100644 index 0000000..227f505 Binary files /dev/null and b/src/qt/res/icons/mining_inactive.png differ diff --git a/src/qt/res/icons/notsynced.png b/src/qt/res/icons/notsynced.png new file mode 100644 index 0000000..c9e7118 Binary files /dev/null and b/src/qt/res/icons/notsynced.png differ diff --git a/src/qt/res/icons/overview.png b/src/qt/res/icons/overview.png new file mode 100644 index 0000000..3c70b0c Binary files /dev/null and b/src/qt/res/icons/overview.png differ diff --git a/src/qt/res/icons/qrcode.png b/src/qt/res/icons/qrcode.png new file mode 100644 index 0000000..a8d9717 Binary files /dev/null and b/src/qt/res/icons/qrcode.png differ diff --git a/src/qt/res/icons/quit.png b/src/qt/res/icons/quit.png new file mode 100644 index 0000000..0dde6f3 Binary files /dev/null and b/src/qt/res/icons/quit.png differ diff --git a/src/qt/res/icons/receive.png b/src/qt/res/icons/receive.png new file mode 100644 index 0000000..fb355d5 Binary files /dev/null and b/src/qt/res/icons/receive.png differ diff --git a/src/qt/res/icons/remove.png b/src/qt/res/icons/remove.png new file mode 100644 index 0000000..a44b6d1 Binary files /dev/null and b/src/qt/res/icons/remove.png differ diff --git a/src/qt/res/icons/send.png b/src/qt/res/icons/send.png new file mode 100644 index 0000000..3392cf2 Binary files /dev/null and b/src/qt/res/icons/send.png differ diff --git a/src/qt/res/icons/synced.png b/src/qt/res/icons/synced.png new file mode 100644 index 0000000..4d7e0e8 Binary files /dev/null and b/src/qt/res/icons/synced.png differ diff --git a/src/qt/res/icons/toolbar.png b/src/qt/res/icons/toolbar.png new file mode 100644 index 0000000..19ccf7d Binary files /dev/null and b/src/qt/res/icons/toolbar.png differ diff --git a/src/qt/res/icons/toolbar_testnet.png b/src/qt/res/icons/toolbar_testnet.png new file mode 100644 index 0000000..d4242a6 Binary files /dev/null and b/src/qt/res/icons/toolbar_testnet.png differ diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png new file mode 100644 index 0000000..4578666 Binary files /dev/null and b/src/qt/res/icons/transaction0.png differ diff --git a/src/qt/res/icons/transaction2.png b/src/qt/res/icons/transaction2.png new file mode 100644 index 0000000..01bb558 Binary files /dev/null and b/src/qt/res/icons/transaction2.png differ diff --git a/src/qt/res/icons/tx_inout.png b/src/qt/res/icons/tx_inout.png new file mode 100644 index 0000000..5221874 Binary files /dev/null and b/src/qt/res/icons/tx_inout.png differ diff --git a/src/qt/res/icons/tx_input.png b/src/qt/res/icons/tx_input.png new file mode 100644 index 0000000..f089c28 Binary files /dev/null and b/src/qt/res/icons/tx_input.png differ diff --git a/src/qt/res/icons/tx_mined.png b/src/qt/res/icons/tx_mined.png new file mode 100644 index 0000000..525e2de Binary files /dev/null and b/src/qt/res/icons/tx_mined.png differ diff --git a/src/qt/res/icons/tx_output.png b/src/qt/res/icons/tx_output.png new file mode 100644 index 0000000..41d9bba Binary files /dev/null and b/src/qt/res/icons/tx_output.png differ diff --git a/src/qt/res/images/about.png b/src/qt/res/images/about.png new file mode 100644 index 0000000..c9ab951 Binary files /dev/null and b/src/qt/res/images/about.png differ diff --git a/src/qt/res/images/casinocoin-coin.png b/src/qt/res/images/casinocoin-coin.png new file mode 100644 index 0000000..bbb14ce Binary files /dev/null and b/src/qt/res/images/casinocoin-coin.png differ diff --git a/src/qt/res/images/logo.png b/src/qt/res/images/logo.png new file mode 100644 index 0000000..d32e8bb Binary files /dev/null and b/src/qt/res/images/logo.png differ diff --git a/src/qt/res/images/splash2.jpg b/src/qt/res/images/splash2.jpg new file mode 100644 index 0000000..fa075bb Binary files /dev/null and b/src/qt/res/images/splash2.jpg differ diff --git a/src/qt/res/images/wallet.png b/src/qt/res/images/wallet.png new file mode 100644 index 0000000..da9d268 Binary files /dev/null and b/src/qt/res/images/wallet.png differ diff --git a/src/qt/res/movies/update_spinner.mng b/src/qt/res/movies/update_spinner.mng new file mode 100644 index 0000000..7df3baa Binary files /dev/null and b/src/qt/res/movies/update_spinner.mng differ diff --git a/src/qt/res/src/bitcoin.svg b/src/qt/res/src/bitcoin.svg new file mode 100644 index 0000000..96f1017 --- /dev/null +++ b/src/qt/res/src/bitcoin.svg @@ -0,0 +1,115 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock1.svg b/src/qt/res/src/clock1.svg new file mode 100644 index 0000000..793dc7f --- /dev/null +++ b/src/qt/res/src/clock1.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock2.svg b/src/qt/res/src/clock2.svg new file mode 100644 index 0000000..6a78adf --- /dev/null +++ b/src/qt/res/src/clock2.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock3.svg b/src/qt/res/src/clock3.svg new file mode 100644 index 0000000..09ccc25 --- /dev/null +++ b/src/qt/res/src/clock3.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock4.svg b/src/qt/res/src/clock4.svg new file mode 100644 index 0000000..7d9dc37 --- /dev/null +++ b/src/qt/res/src/clock4.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock5.svg b/src/qt/res/src/clock5.svg new file mode 100644 index 0000000..9fd58d9 --- /dev/null +++ b/src/qt/res/src/clock5.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/clock_green.svg b/src/qt/res/src/clock_green.svg new file mode 100644 index 0000000..e31f0e7 --- /dev/null +++ b/src/qt/res/src/clock_green.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/inout.svg b/src/qt/res/src/inout.svg new file mode 100644 index 0000000..bfab8ef --- /dev/null +++ b/src/qt/res/src/inout.svg @@ -0,0 +1,122 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/questionmark.svg b/src/qt/res/src/questionmark.svg new file mode 100644 index 0000000..c03c159 --- /dev/null +++ b/src/qt/res/src/questionmark.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ? + ? + + + ? + + diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp new file mode 100644 index 0000000..8493ac8 --- /dev/null +++ b/src/qt/rpcconsole.cpp @@ -0,0 +1,334 @@ +#include "rpcconsole.h" +#include "ui_rpcconsole.h" + +#include "clientmodel.h" +#include "bitcoinrpc.h" +#include "guiutil.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// TODO: make it possible to filter out categories (esp debug messages when implemented) +// TODO: receive errors and debug messages through ClientModel + +const int CONSOLE_SCROLLBACK = 50; +const int CONSOLE_HISTORY = 50; + +const QSize ICON_SIZE(24, 24); + +const struct { + const char *url; + const char *source; +} ICON_MAPPING[] = { + {"cmd-request", ":/icons/tx_input"}, + {"cmd-reply", ":/icons/tx_output"}, + {"cmd-error", ":/icons/tx_output"}, + {"misc", ":/icons/tx_inout"}, + {NULL, NULL} +}; + +/* Object for executing console RPC commands in a separate thread. +*/ +class RPCExecutor: public QObject +{ + Q_OBJECT +public slots: + void start(); + void request(const QString &command); +signals: + void reply(int category, const QString &command); +}; + +#include "rpcconsole.moc" + +void RPCExecutor::start() +{ + // Nothing to do +} + +void RPCExecutor::request(const QString &command) +{ + // Parse shell-like command line into separate arguments + std::string strMethod; + std::vector strParams; + try { + boost::escaped_list_separator els('\\',' ','\"'); + std::string strCommand = command.toStdString(); + boost::tokenizer > tok(strCommand, els); + + int n = 0; + for(boost::tokenizer >::iterator beg=tok.begin(); beg!=tok.end();++beg,++n) + { + if(n == 0) // First parameter is the command + strMethod = *beg; + else + strParams.push_back(*beg); + } + } + catch(boost::escaped_list_error &e) + { + emit reply(RPCConsole::CMD_ERROR, QString("Parse error")); + return; + } + + try { + std::string strPrint; + json_spirit::Value result = tableRPC.execute(strMethod, RPCConvertValues(strMethod, strParams)); + + // Format result reply + if (result.type() == json_spirit::null_type) + strPrint = ""; + else if (result.type() == json_spirit::str_type) + strPrint = result.get_str(); + else + strPrint = write_string(result, true); + + emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); + } + catch (json_spirit::Object& objError) + { + emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false))); + } + catch (std::exception& e) + { + emit reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what())); + } +} + +RPCConsole::RPCConsole(QWidget *parent) : + QDialog(parent), + ui(new Ui::RPCConsole), + historyPtr(0) +{ + ui->setupUi(this); + +#ifndef Q_WS_MAC + ui->openDebugLogfileButton->setIcon(QIcon(":/icons/export")); + ui->showCLOptionsButton->setIcon(QIcon(":/icons/options")); +#endif + + // Install event filter for up and down arrow + ui->lineEdit->installEventFilter(this); + + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); + + // set OpenSSL version label + ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); + + startExecutor(); + + clear(); +} + +RPCConsole::~RPCConsole() +{ + emit stopExecutor(); + delete ui; +} + +bool RPCConsole::eventFilter(QObject* obj, QEvent *event) +{ + if(obj == ui->lineEdit) + { + if(event->type() == QEvent::KeyPress) + { + QKeyEvent *key = static_cast(event); + switch(key->key()) + { + case Qt::Key_Up: browseHistory(-1); return true; + case Qt::Key_Down: browseHistory(1); return true; + } + } + } + return QDialog::eventFilter(obj, event); +} + +void RPCConsole::setClientModel(ClientModel *model) +{ + this->clientModel = model; + if(model) + { + // Subscribe to information, replies, messages, errors + connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); + connect(model, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int))); + + // Provide initial values + ui->clientVersion->setText(model->formatFullVersion()); + ui->clientName->setText(model->clientName()); + ui->startupTime->setText(model->formatClientStartupTime()); + + setNumConnections(model->getNumConnections()); + ui->isTestNet->setChecked(model->isTestNet()); + + setNumBlocks(model->getNumBlocks(), model->getNumBlocksOfPeers()); + } +} + +static QString categoryClass(int category) +{ + switch(category) + { + case RPCConsole::CMD_REQUEST: return "cmd-request"; break; + case RPCConsole::CMD_REPLY: return "cmd-reply"; break; + case RPCConsole::CMD_ERROR: return "cmd-error"; break; + default: return "misc"; + } +} + +void RPCConsole::clear() +{ + ui->messagesWidget->clear(); + ui->lineEdit->clear(); + ui->lineEdit->setFocus(); + + // Add smoothly scaled icon images. + // (when using width/height on an img, Qt uses nearest instead of linear interpolation) + for(int i=0; ICON_MAPPING[i].url; ++i) + { + ui->messagesWidget->document()->addResource( + QTextDocument::ImageResource, + QUrl(ICON_MAPPING[i].url), + QImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + } + + // Set default style sheet + ui->messagesWidget->document()->setDefaultStyleSheet( + "table { }" + "td.time { color: #808080; padding-top: 3px; } " + "td.message { font-family: Monospace; font-size: 12px; } " + "td.cmd-request { color: #006060; } " + "td.cmd-error { color: red; } " + "b { color: #006060; } " + ); + + message(CMD_REPLY, (tr("Welcome to the CasinoCoin RPC console.") + "
" + + tr("Use up and down arrows to navigate history, and Ctrl-L to clear screen.") + "
" + + tr("Type help for an overview of available commands.")), true); +} + +void RPCConsole::message(int category, const QString &message, bool html) +{ + QTime time = QTime::currentTime(); + QString timeString = time.toString(); + QString out; + out += ""; + out += ""; + out += "
" + timeString + ""; + if(html) + out += message; + else + out += GUIUtil::HtmlEscape(message, true); + out += "
"; + ui->messagesWidget->append(out); +} + +void RPCConsole::setNumConnections(int count) +{ + ui->numberOfConnections->setText(QString::number(count)); +} + +void RPCConsole::setNumBlocks(int count, int countOfPeers) +{ + ui->numberOfBlocks->setText(QString::number(count)); + ui->totalBlocks->setText(QString::number(countOfPeers)); + if(clientModel) + { + // If there is no current number available display N/A instead of 0, which can't ever be true + ui->totalBlocks->setText(clientModel->getNumBlocksOfPeers() == 0 ? tr("N/A") : QString::number(clientModel->getNumBlocksOfPeers())); + ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString()); + } +} + +void RPCConsole::on_lineEdit_returnPressed() +{ + QString cmd = ui->lineEdit->text(); + ui->lineEdit->clear(); + + if(!cmd.isEmpty()) + { + message(CMD_REQUEST, cmd); + emit cmdRequest(cmd); + // Truncate history from current position + history.erase(history.begin() + historyPtr, history.end()); + // Append command to history + history.append(cmd); + // Enforce maximum history size + while(history.size() > CONSOLE_HISTORY) + history.removeFirst(); + // Set pointer to end of history + historyPtr = history.size(); + // Scroll console view to end + scrollToEnd(); + } +} + +void RPCConsole::browseHistory(int offset) +{ + historyPtr += offset; + if(historyPtr < 0) + historyPtr = 0; + if(historyPtr > history.size()) + historyPtr = history.size(); + QString cmd; + if(historyPtr < history.size()) + cmd = history.at(historyPtr); + ui->lineEdit->setText(cmd); +} + +void RPCConsole::startExecutor() +{ + QThread* thread = new QThread; + RPCExecutor *executor = new RPCExecutor(); + executor->moveToThread(thread); + + // Notify executor when thread started (in executor thread) + connect(thread, SIGNAL(started()), executor, SLOT(start())); + // Replies from executor object must go to this object + connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString))); + // Requests from this object must go to executor + connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString))); + // On stopExecutor signal + // - queue executor for deletion (in execution thread) + // - quit the Qt event loop in the execution thread + connect(this, SIGNAL(stopExecutor()), executor, SLOT(deleteLater())); + connect(this, SIGNAL(stopExecutor()), thread, SLOT(quit())); + // Queue the thread for deletion (in this thread) when it is finished + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + + // Default implementation of QThread::run() simply spins up an event loop in the thread, + // which is what we want. + thread->start(); +} + +void RPCConsole::on_tabWidget_currentChanged(int index) +{ + if(ui->tabWidget->widget(index) == ui->tab_console) + { + ui->lineEdit->setFocus(); + } +} + +void RPCConsole::on_openDebugLogfileButton_clicked() +{ + GUIUtil::openDebugLogfile(); +} + +void RPCConsole::scrollToEnd() +{ + QScrollBar *scrollbar = ui->messagesWidget->verticalScrollBar(); + scrollbar->setValue(scrollbar->maximum()); +} + +void RPCConsole::on_showCLOptionsButton_clicked() +{ + GUIUtil::HelpMessageBox help; + help.exec(); +} diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h new file mode 100644 index 0000000..3c38b4b --- /dev/null +++ b/src/qt/rpcconsole.h @@ -0,0 +1,66 @@ +#ifndef RPCCONSOLE_H +#define RPCCONSOLE_H + +#include + +namespace Ui { + class RPCConsole; +} +class ClientModel; + +/** Local Bitcoin RPC console. */ +class RPCConsole: public QDialog +{ + Q_OBJECT + +public: + explicit RPCConsole(QWidget *parent = 0); + ~RPCConsole(); + + void setClientModel(ClientModel *model); + + enum MessageClass { + MC_ERROR, + MC_DEBUG, + CMD_REQUEST, + CMD_REPLY, + CMD_ERROR + }; + +protected: + virtual bool eventFilter(QObject* obj, QEvent *event); + +private slots: + void on_lineEdit_returnPressed(); + 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(); + void message(int category, const QString &message, bool html = false); + /** Set number of connections shown in the UI */ + void setNumConnections(int count); + /** Set number of blocks shown in the UI */ + void setNumBlocks(int count, int countOfPeers); + /** Go forward or back in history */ + void browseHistory(int offset); + /** Scroll console view to end */ + void scrollToEnd(); +signals: + // For RPC command executor + void stopExecutor(); + void cmdRequest(const QString &command); + +private: + Ui::RPCConsole *ui; + ClientModel *clientModel; + QStringList history; + int historyPtr; + + void startExecutor(); +}; + +#endif // RPCCONSOLE_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp new file mode 100644 index 0000000..86c2b01 --- /dev/null +++ b/src/qt/sendcoinsdialog.cpp @@ -0,0 +1,301 @@ +#include "sendcoinsdialog.h" +#include "ui_sendcoinsdialog.h" +#include "walletmodel.h" +#include "bitcoinunits.h" +#include "addressbookpage.h" +#include "optionsmodel.h" +#include "sendcoinsentry.h" +#include "guiutil.h" +#include "askpassphrasedialog.h" + +#include +#include +#include +#include + +SendCoinsDialog::SendCoinsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SendCoinsDialog), + model(0) +{ + ui->setupUi(this); + +#ifdef Q_WS_MAC // Icons on push buttons are very uncommon on Mac + ui->addButton->setIcon(QIcon()); + ui->clearButton->setIcon(QIcon()); + ui->sendButton->setIcon(QIcon()); +#endif + + addEntry(); + + connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry())); + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); + + fNewRecipientAllowed = true; +} + +void SendCoinsDialog::setModel(WalletModel *model) +{ + this->model = model; + + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + { + entry->setModel(model); + } + } + if(model && model->getOptionsModel()) + { + setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance()); + connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64))); + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + } +} + +SendCoinsDialog::~SendCoinsDialog() +{ + delete ui; +} + +void SendCoinsDialog::on_sendButton_clicked() +{ + QList recipients; + bool valid = true; + + if(!model) + return; + + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + { + if(entry->validate()) + { + recipients.append(entry->getValue()); + } + else + { + valid = false; + } + } + } + + if(!valid || recipients.isEmpty()) + { + return; + } + + // Format confirmation message + QStringList formatted; + foreach(const SendCoinsRecipient &rcp, recipients) + { + formatted.append(tr("%1 to %2 (%3)").arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, rcp.amount), Qt::escape(rcp.label), rcp.address)); + } + + fNewRecipientAllowed = false; + + QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"), + tr("Are you sure you want to send %1?").arg(formatted.join(tr(" and "))), + QMessageBox::Yes|QMessageBox::Cancel, + QMessageBox::Cancel); + + if(retval != QMessageBox::Yes) + { + fNewRecipientAllowed = true; + return; + } + + WalletModel::UnlockContext ctx(model->requestUnlock()); + if(!ctx.isValid()) + { + // Unlock wallet was cancelled + fNewRecipientAllowed = true; + return; + } + + WalletModel::SendCoinsReturn sendstatus = model->sendCoins(recipients); + switch(sendstatus.status) + { + case WalletModel::InvalidAddress: + QMessageBox::warning(this, tr("Send Coins"), + tr("The recepient address is not valid, please recheck."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::InvalidAmount: + QMessageBox::warning(this, tr("Send Coins"), + tr("The amount to pay must be larger than 0."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::AmountExceedsBalance: + QMessageBox::warning(this, tr("Send Coins"), + tr("The amount exceeds your balance."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::AmountWithFeeExceedsBalance: + QMessageBox::warning(this, tr("Send Coins"), + tr("The total exceeds your balance when the %1 transaction fee is included."). + arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, sendstatus.fee)), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::DuplicateAddress: + QMessageBox::warning(this, tr("Send Coins"), + tr("Duplicate address found, can only send to each address once per send operation."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::TransactionCreationFailed: + QMessageBox::warning(this, tr("Send Coins"), + tr("Error: Transaction creation failed."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::TransactionCommitFailed: + QMessageBox::warning(this, tr("Send Coins"), + tr("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."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::Aborted: // User aborted, nothing to do + break; + case WalletModel::OK: + accept(); + break; + } + fNewRecipientAllowed = true; +} + +void SendCoinsDialog::clear() +{ + // Remove entries until only one left + while(ui->entries->count()) + { + delete ui->entries->takeAt(0)->widget(); + } + addEntry(); + + updateRemoveEnabled(); + + ui->sendButton->setDefault(true); +} + +void SendCoinsDialog::reject() +{ + clear(); +} + +void SendCoinsDialog::accept() +{ + clear(); +} + +SendCoinsEntry *SendCoinsDialog::addEntry() +{ + SendCoinsEntry *entry = new SendCoinsEntry(this); + entry->setModel(model); + ui->entries->addWidget(entry); + connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*))); + + updateRemoveEnabled(); + + // Focus the field, so that entry can start immediately + entry->clear(); + entry->setFocus(); + ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint()); + QCoreApplication::instance()->processEvents(); + QScrollBar* bar = ui->scrollArea->verticalScrollBar(); + if(bar) + bar->setSliderPosition(bar->maximum()); + return entry; +} + +void SendCoinsDialog::updateRemoveEnabled() +{ + // Remove buttons are enabled as soon as there is more than one send-entry + bool enabled = (ui->entries->count() > 1); + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + { + entry->setRemoveEnabled(enabled); + } + } + setupTabChain(0); +} + +void SendCoinsDialog::removeEntry(SendCoinsEntry* entry) +{ + delete entry; + updateRemoveEnabled(); +} + +QWidget *SendCoinsDialog::setupTabChain(QWidget *prev) +{ + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + { + prev = entry->setupTabChain(prev); + } + } + QWidget::setTabOrder(prev, ui->addButton); + QWidget::setTabOrder(ui->addButton, ui->sendButton); + return ui->sendButton; +} + +void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) +{ + if(!fNewRecipientAllowed) + return; + + SendCoinsEntry *entry = 0; + // Replace the first entry if it is still unused + if(ui->entries->count() == 1) + { + SendCoinsEntry *first = qobject_cast(ui->entries->itemAt(0)->widget()); + if(first->isClear()) + { + entry = first; + } + } + if(!entry) + { + entry = addEntry(); + } + + entry->setValue(rv); +} + +bool SendCoinsDialog::handleURI(const QString &uri) +{ + SendCoinsRecipient rv; + // URI has to be valid + if (GUIUtil::parseBitcoinURI(uri, &rv)) + { + pasteEntry(rv); + return true; + } + + return false; +} + +void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance) +{ + Q_UNUSED(unconfirmedBalance); + Q_UNUSED(immatureBalance); + if(!model || !model->getOptionsModel()) + return; + + int unit = model->getOptionsModel()->getDisplayUnit(); + ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance)); +} + +void SendCoinsDialog::updateDisplayUnit() +{ + if(model && model->getOptionsModel()) + { + // Update labelBalance with the current balance and the current unit + ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->getBalance())); + } +} diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h new file mode 100644 index 0000000..def2f83 --- /dev/null +++ b/src/qt/sendcoinsdialog.h @@ -0,0 +1,54 @@ +#ifndef SENDCOINSDIALOG_H +#define SENDCOINSDIALOG_H + +#include + +namespace Ui { + class SendCoinsDialog; +} +class WalletModel; +class SendCoinsEntry; +class SendCoinsRecipient; + +QT_BEGIN_NAMESPACE +class QUrl; +QT_END_NAMESPACE + +/** Dialog for sending bitcoins */ +class SendCoinsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SendCoinsDialog(QWidget *parent = 0); + ~SendCoinsDialog(); + + void setModel(WalletModel *model); + + /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907). + */ + QWidget *setupTabChain(QWidget *prev); + + void pasteEntry(const SendCoinsRecipient &rv); + bool handleURI(const QString &uri); + +public slots: + void clear(); + void reject(); + void accept(); + SendCoinsEntry *addEntry(); + void updateRemoveEnabled(); + void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance); + +private: + Ui::SendCoinsDialog *ui; + WalletModel *model; + bool fNewRecipientAllowed; + +private slots: + void on_sendButton_clicked(); + void removeEntry(SendCoinsEntry* entry); + void updateDisplayUnit(); +}; + +#endif // SENDCOINSDIALOG_H diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp new file mode 100644 index 0000000..9dc53bc --- /dev/null +++ b/src/qt/sendcoinsentry.cpp @@ -0,0 +1,172 @@ +#include "sendcoinsentry.h" +#include "ui_sendcoinsentry.h" +#include "guiutil.h" +#include "bitcoinunits.h" +#include "addressbookpage.h" +#include "walletmodel.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" + +#include +#include + +SendCoinsEntry::SendCoinsEntry(QWidget *parent) : + QFrame(parent), + ui(new Ui::SendCoinsEntry), + model(0) +{ + ui->setupUi(this); + +#ifdef Q_WS_MAC + ui->payToLayout->setSpacing(4); +#endif +#if QT_VERSION >= 0x040700 + /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book")); + ui->payTo->setPlaceholderText(tr("Enter a CasinoCoin address (e.g. Ler4HNAEfwYhBmGXcFP2Po1NpRUEiK8km2)")); +#endif + setFocusPolicy(Qt::TabFocus); + setFocusProxy(ui->payTo); + + GUIUtil::setupAddressWidget(ui->payTo, this); +} + +SendCoinsEntry::~SendCoinsEntry() +{ + delete ui; +} + +void SendCoinsEntry::on_pasteButton_clicked() +{ + // Paste text from clipboard into recipient field + ui->payTo->setText(QApplication::clipboard()->text()); +} + +void SendCoinsEntry::on_addressBookButton_clicked() +{ + if(!model) + return; + AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::SendingTab, this); + dlg.setModel(model->getAddressTableModel()); + if(dlg.exec()) + { + ui->payTo->setText(dlg.getReturnValue()); + ui->payAmount->setFocus(); + } +} + +void SendCoinsEntry::on_payTo_textChanged(const QString &address) +{ + if(!model) + return; + // Fill in label from address book, if address has an associated label + QString associatedLabel = model->getAddressTableModel()->labelForAddress(address); + if(!associatedLabel.isEmpty()) + ui->addAsLabel->setText(associatedLabel); +} + +void SendCoinsEntry::setModel(WalletModel *model) +{ + this->model = model; + + if(model && model->getOptionsModel()) + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + + clear(); +} + +void SendCoinsEntry::setRemoveEnabled(bool enabled) +{ + ui->deleteButton->setEnabled(enabled); +} + +void SendCoinsEntry::clear() +{ + ui->payTo->clear(); + ui->addAsLabel->clear(); + ui->payAmount->clear(); + ui->payTo->setFocus(); + // update the display unit, to not use the default ("BTC") + updateDisplayUnit(); +} + +void SendCoinsEntry::on_deleteButton_clicked() +{ + emit removeEntry(this); +} + +bool SendCoinsEntry::validate() +{ + // Check input validity + bool retval = true; + + if(!ui->payAmount->validate()) + { + retval = false; + } + else + { + if(ui->payAmount->value() <= 0) + { + // Cannot send 0 coins or less + ui->payAmount->setValid(false); + retval = false; + } + } + + if(!ui->payTo->hasAcceptableInput() || + (model && !model->validateAddress(ui->payTo->text()))) + { + ui->payTo->setValid(false); + retval = false; + } + + return retval; +} + +SendCoinsRecipient SendCoinsEntry::getValue() +{ + SendCoinsRecipient rv; + + rv.address = ui->payTo->text(); + rv.label = ui->addAsLabel->text(); + rv.amount = ui->payAmount->value(); + + return rv; +} + +QWidget *SendCoinsEntry::setupTabChain(QWidget *prev) +{ + QWidget::setTabOrder(prev, ui->payTo); + QWidget::setTabOrder(ui->payTo, ui->addressBookButton); + QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton); + QWidget::setTabOrder(ui->pasteButton, ui->deleteButton); + QWidget::setTabOrder(ui->deleteButton, ui->addAsLabel); + return ui->payAmount->setupTabChain(ui->addAsLabel); +} + +void SendCoinsEntry::setValue(const SendCoinsRecipient &value) +{ + ui->payTo->setText(value.address); + ui->addAsLabel->setText(value.label); + ui->payAmount->setValue(value.amount); +} + +bool SendCoinsEntry::isClear() +{ + return ui->payTo->text().isEmpty(); +} + +void SendCoinsEntry::setFocus() +{ + ui->payTo->setFocus(); +} + +void SendCoinsEntry::updateDisplayUnit() +{ + if(model && model->getOptionsModel()) + { + // Update payAmount with the current unit + ui->payAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit()); + } +} diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h new file mode 100644 index 0000000..db6cba0 --- /dev/null +++ b/src/qt/sendcoinsentry.h @@ -0,0 +1,55 @@ +#ifndef SENDCOINSENTRY_H +#define SENDCOINSENTRY_H + +#include + +namespace Ui { + class SendCoinsEntry; +} +class WalletModel; +class SendCoinsRecipient; + +/** A single entry in the dialog for sending bitcoins. */ +class SendCoinsEntry : public QFrame +{ + Q_OBJECT + +public: + explicit SendCoinsEntry(QWidget *parent = 0); + ~SendCoinsEntry(); + + void setModel(WalletModel *model); + bool validate(); + SendCoinsRecipient getValue(); + + /** Return whether the entry is still empty and unedited */ + bool isClear(); + + void setValue(const SendCoinsRecipient &value); + + /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907). + */ + QWidget *setupTabChain(QWidget *prev); + + void setFocus(); + +public slots: + void setRemoveEnabled(bool enabled); + void clear(); + +signals: + void removeEntry(SendCoinsEntry *entry); + +private slots: + void on_deleteButton_clicked(); + void on_payTo_textChanged(const QString &address); + void on_addressBookButton_clicked(); + void on_pasteButton_clicked(); + void updateDisplayUnit(); + +private: + Ui::SendCoinsEntry *ui; + WalletModel *model; +}; + +#endif // SENDCOINSENTRY_H diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp new file mode 100644 index 0000000..f8edbf8 --- /dev/null +++ b/src/qt/signverifymessagedialog.cpp @@ -0,0 +1,274 @@ +#include "signverifymessagedialog.h" +#include "ui_signverifymessagedialog.h" + +#include "addressbookpage.h" +#include "base58.h" +#include "guiutil.h" +#include "init.h" +#include "main.h" +#include "optionsmodel.h" +#include "walletmodel.h" +#include "wallet.h" + +#include +#include + +#include + +SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SignVerifyMessageDialog), + model(0) +{ + ui->setupUi(this); + +#if (QT_VERSION >= 0x040700) + /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + ui->addressIn_SM->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)")); + ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature")); + + ui->addressIn_VM->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)")); + ui->signatureIn_VM->setPlaceholderText(tr("Enter Bitcoin signature")); +#endif + + GUIUtil::setupAddressWidget(ui->addressIn_SM, this); + GUIUtil::setupAddressWidget(ui->addressIn_VM, this); + + ui->addressIn_SM->installEventFilter(this); + ui->messageIn_SM->installEventFilter(this); + ui->signatureOut_SM->installEventFilter(this); + ui->addressIn_VM->installEventFilter(this); + ui->messageIn_VM->installEventFilter(this); + ui->signatureIn_VM->installEventFilter(this); + + ui->signatureOut_SM->setFont(GUIUtil::bitcoinAddressFont()); + ui->signatureIn_VM->setFont(GUIUtil::bitcoinAddressFont()); +} + +SignVerifyMessageDialog::~SignVerifyMessageDialog() +{ + delete ui; +} + +void SignVerifyMessageDialog::setModel(WalletModel *model) +{ + this->model = model; +} + +void SignVerifyMessageDialog::setAddress_SM(QString address) +{ + ui->addressIn_SM->setText(address); + ui->messageIn_SM->setFocus(); +} + +void SignVerifyMessageDialog::setAddress_VM(QString address) +{ + ui->addressIn_VM->setText(address); + ui->messageIn_VM->setFocus(); +} + +void SignVerifyMessageDialog::showTab_SM(bool fShow) +{ + ui->tabWidget->setCurrentIndex(0); + + if (fShow) + this->show(); +} + +void SignVerifyMessageDialog::showTab_VM(bool fShow) +{ + ui->tabWidget->setCurrentIndex(1); + if (fShow) + this->show(); +} + +void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() +{ + if (model && model->getAddressTableModel()) + { + AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::ReceivingTab, this); + dlg.setModel(model->getAddressTableModel()); + if (dlg.exec()) + { + setAddress_SM(dlg.getReturnValue()); + } + } +} + +void SignVerifyMessageDialog::on_pasteButton_SM_clicked() +{ + setAddress_SM(QApplication::clipboard()->text()); +} + +void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() +{ + /* Clear old signature to ensure users don't get confused on error with an old signature displayed */ + ui->signatureOut_SM->clear(); + + CBitcoinAddress addr(ui->addressIn_SM->text().toStdString()); + if (!addr.IsValid()) + { + ui->addressIn_SM->setValid(false); + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); + return; + } + CKeyID keyID; + if (!addr.GetKeyID(keyID)) + { + ui->addressIn_SM->setValid(false); + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); + return; + } + + WalletModel::UnlockContext ctx(model->requestUnlock()); + if (!ctx.isValid()) + { + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(tr("Wallet unlock was canceled.")); + return; + } + + CKey key; + if (!pwalletMain->GetKey(keyID, key)) + { + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(tr("Private key for the entered address is not available.")); + return; + } + + CDataStream ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << ui->messageIn_SM->document()->toPlainText().toStdString(); + + std::vector vchSig; + if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) + { + ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_SM->setText(QString("") + tr("Message signing failed.") + QString("")); + return; + } + + ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }"); + ui->statusLabel_SM->setText(QString("") + tr("Message signed.") + QString("")); + + ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size()))); +} + +void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked() +{ + QApplication::clipboard()->setText(ui->signatureOut_SM->text()); +} + +void SignVerifyMessageDialog::on_clearButton_SM_clicked() +{ + ui->addressIn_SM->clear(); + ui->messageIn_SM->clear(); + ui->signatureOut_SM->clear(); + ui->statusLabel_SM->clear(); + + ui->addressIn_SM->setFocus(); +} + +void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() +{ + if (model && model->getAddressTableModel()) + { + AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::SendingTab, this); + dlg.setModel(model->getAddressTableModel()); + if (dlg.exec()) + { + setAddress_VM(dlg.getReturnValue()); + } + } +} + +void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() +{ + CBitcoinAddress addr(ui->addressIn_VM->text().toStdString()); + if (!addr.IsValid()) + { + ui->addressIn_VM->setValid(false); + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); + return; + } + CKeyID keyID; + if (!addr.GetKeyID(keyID)) + { + ui->addressIn_VM->setValid(false); + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); + return; + } + + bool fInvalid = false; + std::vector vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid); + + if (fInvalid) + { + ui->signatureIn_VM->setValid(false); + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->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->messageIn_VM->document()->toPlainText().toStdString(); + + CKey key; + if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig)) + { + ui->signatureIn_VM->setValid(false); + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again.")); + return; + } + + if (!(CBitcoinAddress(key.GetPubKey().GetID()) == addr)) + { + ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel_VM->setText(QString("") + tr("Message verification failed.") + QString("")); + return; + } + + ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }"); + ui->statusLabel_VM->setText(QString("") + tr("Message verified.") + QString("")); +} + +void SignVerifyMessageDialog::on_clearButton_VM_clicked() +{ + ui->addressIn_VM->clear(); + ui->signatureIn_VM->clear(); + ui->messageIn_VM->clear(); + ui->statusLabel_VM->clear(); + + ui->addressIn_VM->setFocus(); +} + +bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn) + { + if (ui->tabWidget->currentIndex() == 0) + { + /* Clear status message on focus change */ + ui->statusLabel_SM->clear(); + + /* Select generated signature */ + if (object == ui->signatureOut_SM) + { + ui->signatureOut_SM->selectAll(); + return true; + } + } + else if (ui->tabWidget->currentIndex() == 1) + { + /* Clear status message on focus change */ + ui->statusLabel_VM->clear(); + } + } + return QDialog::eventFilter(object, event); +} diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h new file mode 100644 index 0000000..5569c8b --- /dev/null +++ b/src/qt/signverifymessagedialog.h @@ -0,0 +1,49 @@ +#ifndef SIGNVERIFYMESSAGEDIALOG_H +#define SIGNVERIFYMESSAGEDIALOG_H + +#include + +namespace Ui { + class SignVerifyMessageDialog; +} +class WalletModel; + +QT_BEGIN_NAMESPACE +QT_END_NAMESPACE + +class SignVerifyMessageDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SignVerifyMessageDialog(QWidget *parent = 0); + ~SignVerifyMessageDialog(); + + void setModel(WalletModel *model); + void setAddress_SM(QString address); + void setAddress_VM(QString address); + + void showTab_SM(bool fShow); + void showTab_VM(bool fShow); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private: + Ui::SignVerifyMessageDialog *ui; + WalletModel *model; + +private slots: + /* sign message */ + void on_addressBookButton_SM_clicked(); + void on_pasteButton_SM_clicked(); + void on_signMessageButton_SM_clicked(); + void on_copySignatureButton_SM_clicked(); + void on_clearButton_SM_clicked(); + /* verify message */ + void on_addressBookButton_VM_clicked(); + void on_verifyMessageButton_VM_clicked(); + void on_clearButton_VM_clicked(); +}; + +#endif // SIGNVERIFYMESSAGEDIALOG_H diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp new file mode 100644 index 0000000..3ac31e6 --- /dev/null +++ b/src/qt/test/test_main.cpp @@ -0,0 +1,11 @@ +#include +#include + +#include "uritests.h" + +// This is all you need to run all the tests +int main(int argc, char *argv[]) +{ + URITests test1; + QTest::qExec(&test1); +} diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp new file mode 100644 index 0000000..a281c39 --- /dev/null +++ b/src/qt/test/uritests.cpp @@ -0,0 +1,71 @@ +#include "uritests.h" +#include "../guiutil.h" +#include "../walletmodel.h" + +#include + +/* +struct SendCoinsRecipient +{ + QString address; + QString label; + qint64 amount; +}; +*/ + +void URITests::uriTests() +{ + SendCoinsRecipient rv; + QUrl uri; + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-dontexist=")); + QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?dontexist=")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.amount == 0); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Wikipedia Example Address")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString("Wikipedia Example Address")); + QVERIFY(rv.amount == 0); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=0.001")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.amount == 100000); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1.001")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.amount == 100100000); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=100&label=Wikipedia Example")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.amount == 10000000000); + QVERIFY(rv.label == QString("Wikipedia Example")); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address")); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + + QVERIFY(GUIUtil::parseBitcoinURI("bitcoin://175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address", &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + + // We currently don't implement the message parameter (ok, yea, we break spec...) + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-message=Wikipedia Example Address")); + QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000&label=Wikipedia Example")); + QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); + + uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000.0&label=Wikipedia Example")); + QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); +} diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h new file mode 100644 index 0000000..1237516 --- /dev/null +++ b/src/qt/test/uritests.h @@ -0,0 +1,15 @@ +#ifndef URITESTS_H +#define URITESTS_H + +#include +#include + +class URITests : public QObject +{ + Q_OBJECT + +private slots: + void uriTests(); +}; + +#endif // URITESTS_H diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp new file mode 100644 index 0000000..5007d21 --- /dev/null +++ b/src/qt/transactiondesc.cpp @@ -0,0 +1,276 @@ +#include "transactiondesc.h" + +#include "guiutil.h" +#include "bitcoinunits.h" + +#include "main.h" +#include "wallet.h" +#include "db.h" +#include "ui_interface.h" +#include "base58.h" + +QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) +{ + if (!wtx.IsFinal()) + { + if (wtx.nLockTime < LOCKTIME_THRESHOLD) + return tr("Open for %n block(s)", "", nBestHeight - wtx.nLockTime); + else + return tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.nLockTime)); + } + else + { + int nDepth = wtx.GetDepthInMainChain(); + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + return tr("%1/offline").arg(nDepth); + else if (nDepth < 6) + return tr("%1/unconfirmed").arg(nDepth); + else + return tr("%1 confirmations").arg(nDepth); + } +} + +QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) +{ + QString strHTML; + + { + LOCK(wallet->cs_wallet); + strHTML.reserve(4000); + strHTML += ""; + + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + + strHTML += "" + tr("Status") + ": " + FormatTxStatus(wtx); + int nRequests = wtx.GetRequestCount(); + if (nRequests != -1) + { + if (nRequests == 0) + strHTML += tr(", has not been successfully broadcast yet"); + else if (nRequests > 0) + strHTML += tr(", broadcast through %n node(s)", "", nRequests); + } + strHTML += "
"; + + strHTML += "" + tr("Date") + ": " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "
"; + + // + // From + // + if (wtx.IsCoinBase()) + { + strHTML += "" + tr("Source") + ": " + tr("Generated") + "
"; + } + else if (!wtx.mapValue["from"].empty()) + { + // Online transaction + if (!wtx.mapValue["from"].empty()) + strHTML += "" + tr("From") + ": " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "
"; + } + else + { + // Offline transaction + if (nNet > 0) + { + // Credit + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if (wallet->IsMine(txout)) + { + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) + { + if (wallet->mapAddressBook.count(address)) + { + strHTML += "" + tr("From") + ": " + tr("unknown") + "
"; + strHTML += "" + tr("To") + ": "; + strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); + if (!wallet->mapAddressBook[address].empty()) + strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")"; + else + strHTML += " (" + tr("own address") + ")"; + strHTML += "
"; + } + } + break; + } + } + } + } + + // + // To + // + if (!wtx.mapValue["to"].empty()) + { + // Online transaction + std::string strAddress = wtx.mapValue["to"]; + strHTML += "" + tr("To") + ": "; + CTxDestination dest = CBitcoinAddress(strAddress).Get(); + if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].empty()) + strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest]) + " "; + strHTML += GUIUtil::HtmlEscape(strAddress) + "
"; + } + + // + // Amount + // + if (wtx.IsCoinBase() && nCredit == 0) + { + // + // Coinbase + // + int64 nUnmatured = 0; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + nUnmatured += wallet->GetCredit(txout); + strHTML += "" + tr("Credit") + ": "; + if (wtx.IsInMainChain()) + strHTML += BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")"; + else + strHTML += "(" + tr("not accepted") + ")"; + strHTML += "
"; + } + else if (nNet > 0) + { + // + // Credit + // + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nNet) + "
"; + } + else + { + bool fAllFromMe = true; + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && wallet->IsMine(txin); + + bool fAllToMe = true; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && wallet->IsMine(txout); + + if (fAllFromMe) + { + // + // Debit + // + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if (wallet->IsMine(txout)) + continue; + + if (wtx.mapValue["to"].empty()) + { + // Offline transaction + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address)) + { + strHTML += "" + tr("To") + ": "; + if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty()) + strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " "; + strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); + strHTML += "
"; + } + } + + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -txout.nValue) + "
"; + } + + if (fAllToMe) + { + // Payment to self + int64 nChange = wtx.GetChange(); + int64 nValue = nCredit - nChange; + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -nValue) + "
"; + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nValue) + "
"; + } + + int64 nTxFee = nDebit - wtx.GetValueOut(); + if (nTxFee > 0) + strHTML += "" + tr("Transaction fee") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -nTxFee) + "
"; + } + else + { + // + // Mixed debit transaction + // + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + if (wallet->IsMine(txin)) + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "
"; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (wallet->IsMine(txout)) + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "
"; + } + } + + strHTML += "" + tr("Net amount") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nNet, true) + "
"; + + // + // Message + // + if (!wtx.mapValue["message"].empty()) + strHTML += "
" + tr("Message") + ":
" + GUIUtil::HtmlEscape(wtx.mapValue["message"], true) + "
"; + if (!wtx.mapValue["comment"].empty()) + strHTML += "
" + tr("Comment") + ":
" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "
"; + + strHTML += "" + tr("Transaction ID") + ": " + wtx.GetHash().ToString().c_str() + "
"; + + if (wtx.IsCoinBase()) + strHTML += "
" + tr("Generated coins must mature 8 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, its 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.") + "
"; + + // + // Debug view + // + if (fDebug) + { + strHTML += "

" + tr("Debug information") + "

"; + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + if(wallet->IsMine(txin)) + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "
"; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if(wallet->IsMine(txout)) + strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "
"; + + strHTML += "
" + tr("Transaction") + ":
"; + strHTML += GUIUtil::HtmlEscape(wtx.ToString(), true); + + CTxDB txdb("r"); // To fetch source txouts + + strHTML += "
" + tr("Inputs") + ":"; + strHTML += "
    "; + + { + LOCK(wallet->cs_wallet); + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + { + COutPoint prevout = txin.prevout; + + CTransaction prev; + if(txdb.ReadDiskTx(prevout.hash, prev)) + { + if (prevout.n < prev.vout.size()) + { + strHTML += "
  • "; + const CTxOut &vout = prev.vout[prevout.n]; + 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(CBitcoinAddress(address).ToString()); + } + strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, vout.nValue); + strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? tr("true") : tr("false")) + "
  • "; + } + } + } + } + + strHTML += "
"; + } + + strHTML += "
"; + } + return strHTML; +} diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h new file mode 100644 index 0000000..2523f9a --- /dev/null +++ b/src/qt/transactiondesc.h @@ -0,0 +1,24 @@ +#ifndef TRANSACTIONDESC_H +#define TRANSACTIONDESC_H + +#include +#include +#include + +class CWallet; +class CWalletTx; + +/** Provide a human-readable extended HTML description of a transaction. + */ +class TransactionDesc: public QObject +{ + Q_OBJECT +public: + static QString toHTML(CWallet *wallet, CWalletTx &wtx); +private: + TransactionDesc() {} + + static QString FormatTxStatus(const CWalletTx& wtx); +}; + +#endif // TRANSACTIONDESC_H diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp new file mode 100644 index 0000000..3bd4808 --- /dev/null +++ b/src/qt/transactiondescdialog.cpp @@ -0,0 +1,20 @@ +#include "transactiondescdialog.h" +#include "ui_transactiondescdialog.h" + +#include "transactiontablemodel.h" + +#include + +TransactionDescDialog::TransactionDescDialog(const QModelIndex &idx, QWidget *parent) : + QDialog(parent), + ui(new Ui::TransactionDescDialog) +{ + ui->setupUi(this); + QString desc = idx.data(TransactionTableModel::LongDescriptionRole).toString(); + ui->detailText->setHtml(desc); +} + +TransactionDescDialog::~TransactionDescDialog() +{ + delete ui; +} diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h new file mode 100644 index 0000000..e86fb58 --- /dev/null +++ b/src/qt/transactiondescdialog.h @@ -0,0 +1,26 @@ +#ifndef TRANSACTIONDESCDIALOG_H +#define TRANSACTIONDESCDIALOG_H + +#include + +namespace Ui { + class TransactionDescDialog; +} +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE + +/** Dialog showing transaction details. */ +class TransactionDescDialog : public QDialog +{ + Q_OBJECT + +public: + explicit TransactionDescDialog(const QModelIndex &idx, QWidget *parent = 0); + ~TransactionDescDialog(); + +private: + Ui::TransactionDescDialog *ui; +}; + +#endif // TRANSACTIONDESCDIALOG_H diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp new file mode 100644 index 0000000..16fb4da --- /dev/null +++ b/src/qt/transactionfilterproxy.cpp @@ -0,0 +1,86 @@ +#include "transactionfilterproxy.h" +#include "transactiontablemodel.h" + +#include + +#include + +// Earliest date that can be represented (far in the past) +const QDateTime TransactionFilterProxy::MIN_DATE = QDateTime::fromTime_t(0); +// Last date that can be represented (far in the future) +const QDateTime TransactionFilterProxy::MAX_DATE = QDateTime::fromTime_t(0xFFFFFFFF); + +TransactionFilterProxy::TransactionFilterProxy(QObject *parent) : + QSortFilterProxyModel(parent), + dateFrom(MIN_DATE), + dateTo(MAX_DATE), + addrPrefix(), + typeFilter(ALL_TYPES), + minAmount(0), + limitRows(-1) +{ +} + +bool TransactionFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + + int type = index.data(TransactionTableModel::TypeRole).toInt(); + QDateTime datetime = index.data(TransactionTableModel::DateRole).toDateTime(); + QString address = index.data(TransactionTableModel::AddressRole).toString(); + QString label = index.data(TransactionTableModel::LabelRole).toString(); + qint64 amount = llabs(index.data(TransactionTableModel::AmountRole).toLongLong()); + + if(!(TYPE(type) & typeFilter)) + return false; + if(datetime < dateFrom || datetime > dateTo) + return false; + if (!address.contains(addrPrefix, Qt::CaseInsensitive) && !label.contains(addrPrefix, Qt::CaseInsensitive)) + return false; + if(amount < minAmount) + return false; + + return true; +} + +void TransactionFilterProxy::setDateRange(const QDateTime &from, const QDateTime &to) +{ + this->dateFrom = from; + this->dateTo = to; + invalidateFilter(); +} + +void TransactionFilterProxy::setAddressPrefix(const QString &addrPrefix) +{ + this->addrPrefix = addrPrefix; + invalidateFilter(); +} + +void TransactionFilterProxy::setTypeFilter(quint32 modes) +{ + this->typeFilter = modes; + invalidateFilter(); +} + +void TransactionFilterProxy::setMinAmount(qint64 minimum) +{ + this->minAmount = minimum; + invalidateFilter(); +} + +void TransactionFilterProxy::setLimit(int limit) +{ + this->limitRows = limit; +} + +int TransactionFilterProxy::rowCount(const QModelIndex &parent) const +{ + if(limitRows != -1) + { + return std::min(QSortFilterProxyModel::rowCount(parent), limitRows); + } + else + { + return QSortFilterProxyModel::rowCount(parent); + } +} diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h new file mode 100644 index 0000000..8d6829d --- /dev/null +++ b/src/qt/transactionfilterproxy.h @@ -0,0 +1,52 @@ +#ifndef TRANSACTIONFILTERPROXY_H +#define TRANSACTIONFILTERPROXY_H + +#include +#include + +/** Filter the transaction list according to pre-specified rules. */ +class TransactionFilterProxy : public QSortFilterProxyModel +{ + Q_OBJECT +public: + explicit TransactionFilterProxy(QObject *parent = 0); + + /** Earliest date that can be represented (far in the past) */ + static const QDateTime MIN_DATE; + /** Last date that can be represented (far in the future) */ + static const QDateTime MAX_DATE; + /** Type filter bit field (all types) */ + static const quint32 ALL_TYPES = 0xFFFFFFFF; + + static quint32 TYPE(int type) { return 1< TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx) +{ + QList parts; + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(true); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + uint256 hash = wtx.GetHash(); + std::map mapValue = wtx.mapValue; + + if (nNet > 0 || wtx.IsCoinBase()) + { + // + // Credit + // + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if(wallet->IsMine(txout)) + { + TransactionRecord sub(hash, nTime); + CTxDestination address; + sub.idx = parts.size(); // sequence number + sub.credit = txout.nValue; + if (wtx.IsCoinBase()) + { + // Generated + sub.type = TransactionRecord::Generated; + } + else if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) + { + // Received by Bitcoin Address + sub.type = TransactionRecord::RecvWithAddress; + sub.address = CBitcoinAddress(address).ToString(); + } + else + { + // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction + sub.type = TransactionRecord::RecvFromOther; + sub.address = mapValue["from"]; + } + + parts.append(sub); + } + } + } + else + { + bool fAllFromMe = true; + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && wallet->IsMine(txin); + + bool fAllToMe = true; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && wallet->IsMine(txout); + + if (fAllFromMe && fAllToMe) + { + // Payment to self + int64 nChange = wtx.GetChange(); + + parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", + -(nDebit - nChange), nCredit - nChange)); + } + else if (fAllFromMe) + { + // + // Debit + // + int64 nTxFee = nDebit - wtx.GetValueOut(); + + for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) + { + const CTxOut& txout = wtx.vout[nOut]; + TransactionRecord sub(hash, nTime); + sub.idx = parts.size(); + + if(wallet->IsMine(txout)) + { + // Ignore parts sent to self, as this is usually the change + // from a transaction sent back to our own address. + continue; + } + + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address)) + { + // Sent to Bitcoin Address + sub.type = TransactionRecord::SendToAddress; + sub.address = CBitcoinAddress(address).ToString(); + } + else + { + // Sent to IP, or other non-address transaction like OP_EVAL + sub.type = TransactionRecord::SendToOther; + sub.address = mapValue["to"]; + } + + int64 nValue = txout.nValue; + /* Add fee to first output */ + if (nTxFee > 0) + { + nValue += nTxFee; + nTxFee = 0; + } + sub.debit = -nValue; + + parts.append(sub); + } + } + else + { + // + // Mixed debit transaction, can't break down payees + // + parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0)); + } + } + + return parts; +} + +void TransactionRecord::updateStatus(const CWalletTx &wtx) +{ + // Determine transaction status + + // Find the block the tx is in + CBlockIndex* pindex = NULL; + std::map::iterator mi = mapBlockIndex.find(wtx.hashBlock); + if (mi != mapBlockIndex.end()) + pindex = (*mi).second; + + // Sort order, unrecorded transactions sort to the top + status.sortKey = strprintf("%010d-%01d-%010u-%03d", + (pindex ? pindex->nHeight : std::numeric_limits::max()), + (wtx.IsCoinBase() ? 1 : 0), + wtx.nTimeReceived, + idx); + status.confirmed = wtx.IsConfirmed(); + status.depth = wtx.GetDepthInMainChain(); + status.cur_num_blocks = nBestHeight; + + if (!wtx.IsFinal()) + { + if (wtx.nLockTime < LOCKTIME_THRESHOLD) + { + status.status = TransactionStatus::OpenUntilBlock; + status.open_for = nBestHeight - wtx.nLockTime; + } + else + { + status.status = TransactionStatus::OpenUntilDate; + status.open_for = wtx.nLockTime; + } + } + else + { + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + { + status.status = TransactionStatus::Offline; + } + else if (status.depth < NumConfirmations) + { + status.status = TransactionStatus::Unconfirmed; + } + else + { + status.status = TransactionStatus::HaveConfirmations; + } + } + + // For generated transactions, determine maturity + if(type == TransactionRecord::Generated) + { + int64 nCredit = wtx.GetCredit(true); + if (nCredit == 0) + { + status.maturity = TransactionStatus::Immature; + + if (wtx.IsInMainChain()) + { + status.matures_in = wtx.GetBlocksToMaturity(); + + // Check if the block was requested by anyone + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + status.maturity = TransactionStatus::MaturesWarning; + } + else + { + status.maturity = TransactionStatus::NotAccepted; + } + } + else + { + status.maturity = TransactionStatus::Mature; + } + } +} + +bool TransactionRecord::statusUpdateNeeded() +{ + return status.cur_num_blocks != nBestHeight; +} + +std::string TransactionRecord::getTxID() +{ + return hash.ToString() + strprintf("-%03d", idx); +} + diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h new file mode 100644 index 0000000..db06374 --- /dev/null +++ b/src/qt/transactionrecord.h @@ -0,0 +1,129 @@ +#ifndef TRANSACTIONRECORD_H +#define TRANSACTIONRECORD_H + +#include "uint256.h" + +#include + +class CWallet; +class CWalletTx; + +/** UI model for transaction status. The transaction status is the part of a transaction that will change over time. + */ +class TransactionStatus +{ +public: + TransactionStatus(): + confirmed(false), sortKey(""), maturity(Mature), + matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1) + { } + + enum Maturity + { + Immature, + Mature, + MaturesWarning, /**< Transaction will likely not mature because no nodes have confirmed */ + NotAccepted + }; + + enum Status { + OpenUntilDate, + OpenUntilBlock, + Offline, + Unconfirmed, + HaveConfirmations + }; + + bool confirmed; + std::string sortKey; + + /** @name Generated (mined) transactions + @{*/ + Maturity maturity; + int matures_in; + /**@}*/ + + /** @name Reported status + @{*/ + Status status; + int64 depth; + int64 open_for; /**< Timestamp if status==OpenUntilDate, otherwise number of blocks */ + /**@}*/ + + /** Current number of blocks (to know whether cached status is still valid) */ + int cur_num_blocks; +}; + +/** UI model for a transaction. A core transaction can be represented by multiple UI transactions if it has + multiple outputs. + */ +class TransactionRecord +{ +public: + enum Type + { + Other, + Generated, + SendToAddress, + SendToOther, + RecvWithAddress, + RecvFromOther, + SendToSelf + }; + + /** Number of confirmation needed for transaction */ + static const int NumConfirmations = 6; + + TransactionRecord(): + hash(), time(0), type(Other), address(""), debit(0), credit(0), idx(0) + { + } + + TransactionRecord(uint256 hash, int64 time): + hash(hash), time(time), type(Other), address(""), debit(0), + credit(0), idx(0) + { + } + + TransactionRecord(uint256 hash, int64 time, + Type type, const std::string &address, + int64 debit, int64 credit): + hash(hash), time(time), type(type), address(address), debit(debit), credit(credit), + idx(0) + { + } + + /** Decompose CWallet transaction to model transaction records. + */ + static bool showTransaction(const CWalletTx &wtx); + static QList decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx); + + /** @name Immutable transaction attributes + @{*/ + uint256 hash; + int64 time; + Type type; + std::string address; + int64 debit; + int64 credit; + /**@}*/ + + /** Subtransaction index, for sort key */ + int idx; + + /** Status: can change with block chain update */ + TransactionStatus status; + + /** Return the unique identifier for this transaction (part) */ + std::string getTxID(); + + /** Update status from core wallet tx. + */ + void updateStatus(const CWalletTx &wtx); + + /** Return whether a status update is needed. + */ + bool statusUpdateNeeded(); +}; + +#endif // TRANSACTIONRECORD_H diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp new file mode 100644 index 0000000..b3e001e --- /dev/null +++ b/src/qt/transactiontablemodel.cpp @@ -0,0 +1,633 @@ +#include "transactiontablemodel.h" +#include "guiutil.h" +#include "transactionrecord.h" +#include "guiconstants.h" +#include "transactiondesc.h" +#include "walletmodel.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" +#include "bitcoinunits.h" + +#include "wallet.h" +#include "ui_interface.h" + +#include +#include +#include +#include +#include +#include +#include + +// Amount column is right-aligned it contains numbers +static int column_alignments[] = { + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignRight|Qt::AlignVCenter + }; + +// Comparison operator for sort/binary search of model tx list +struct TxLessThan +{ + bool operator()(const TransactionRecord &a, const TransactionRecord &b) const + { + return a.hash < b.hash; + } + bool operator()(const TransactionRecord &a, const uint256 &b) const + { + return a.hash < b; + } + bool operator()(const uint256 &a, const TransactionRecord &b) const + { + return a < b.hash; + } +}; + +// Private implementation +class TransactionTablePriv +{ +public: + TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent): + wallet(wallet), + parent(parent) + { + } + CWallet *wallet; + TransactionTableModel *parent; + + /* Local cache of wallet. + * As it is in the same order as the CWallet, by definition + * this is sorted by sha256. + */ + QList cachedWallet; + + /* Query entire wallet anew from core. + */ + void refreshWallet() + { + OutputDebugStringF("refreshWallet\n"); + cachedWallet.clear(); + { + LOCK(wallet->cs_wallet); + for(std::map::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it) + { + if(TransactionRecord::showTransaction(it->second)) + cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second)); + } + } + } + + /* Update our model of the wallet incrementally, to synchronize our model of the wallet + with that of the core. + + Call with transaction that was added, removed or changed. + */ + void updateWallet(const uint256 &hash, int status) + { + OutputDebugStringF("updateWallet %s %i\n", hash.ToString().c_str(), status); + { + LOCK(wallet->cs_wallet); + + // Find transaction in wallet + std::map::iterator mi = wallet->mapWallet.find(hash); + bool inWallet = mi != wallet->mapWallet.end(); + + // Find bounds of this transaction in model + QList::iterator lower = qLowerBound( + cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); + QList::iterator upper = qUpperBound( + cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); + int lowerIndex = (lower - cachedWallet.begin()); + int upperIndex = (upper - cachedWallet.begin()); + bool inModel = (lower != upper); + + // Determine whether to show transaction or not + bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); + + if(status == CT_UPDATED) + { + if(showTransaction && !inModel) + status = CT_NEW; /* Not in model, but want to show, treat as new */ + if(!showTransaction && inModel) + status = CT_DELETED; /* In model, but want to hide, treat as deleted */ + } + + OutputDebugStringF(" inWallet=%i inModel=%i Index=%i-%i showTransaction=%i derivedStatus=%i\n", + inWallet, inModel, lowerIndex, upperIndex, showTransaction, status); + + switch(status) + { + case CT_NEW: + if(inModel) + { + OutputDebugStringF("Warning: updateWallet: Got CT_NEW, but transaction is already in model\n"); + break; + } + if(!inWallet) + { + OutputDebugStringF("Warning: updateWallet: Got CT_NEW, but transaction is not in wallet\n"); + break; + } + if(showTransaction) + { + // Added -- insert at the right position + QList toInsert = + TransactionRecord::decomposeTransaction(wallet, mi->second); + if(!toInsert.isEmpty()) /* only if something to insert */ + { + parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); + int insert_idx = lowerIndex; + foreach(const TransactionRecord &rec, toInsert) + { + cachedWallet.insert(insert_idx, rec); + insert_idx += 1; + } + parent->endInsertRows(); + } + } + break; + case CT_DELETED: + if(!inModel) + { + OutputDebugStringF("Warning: updateWallet: Got CT_DELETED, but transaction is not in model\n"); + break; + } + // Removed -- remove entire transaction from table + parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); + cachedWallet.erase(lower, upper); + parent->endRemoveRows(); + break; + case CT_UPDATED: + // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for + // visible transactions. + break; + } + } + } + + int size() + { + return cachedWallet.size(); + } + + TransactionRecord *index(int idx) + { + if(idx >= 0 && idx < cachedWallet.size()) + { + TransactionRecord *rec = &cachedWallet[idx]; + + // If a status update is needed (blocks came in since last check), + // update the status of this transaction from the wallet. Otherwise, + // simply re-use the cached status. + if(rec->statusUpdateNeeded()) + { + { + LOCK(wallet->cs_wallet); + std::map::iterator mi = wallet->mapWallet.find(rec->hash); + + if(mi != wallet->mapWallet.end()) + { + rec->updateStatus(mi->second); + } + } + } + return rec; + } + else + { + return 0; + } + } + + QString describe(TransactionRecord *rec) + { + { + LOCK(wallet->cs_wallet); + std::map::iterator mi = wallet->mapWallet.find(rec->hash); + if(mi != wallet->mapWallet.end()) + { + return TransactionDesc::toHTML(wallet, mi->second); + } + } + return QString(""); + } + +}; + +TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *parent): + QAbstractTableModel(parent), + wallet(wallet), + walletModel(parent), + priv(new TransactionTablePriv(wallet, this)), + cachedNumBlocks(0) +{ + columns << QString() << tr("Date") << tr("Type") << tr("Address") << tr("Amount"); + + priv->refreshWallet(); + + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(updateConfirmations())); + timer->start(MODEL_UPDATE_DELAY); + + connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); +} + +TransactionTableModel::~TransactionTableModel() +{ + delete priv; +} + +void TransactionTableModel::updateTransaction(const QString &hash, int status) +{ + uint256 updated; + updated.SetHex(hash.toStdString()); + + priv->updateWallet(updated, status); +} + +void TransactionTableModel::updateConfirmations() +{ + if(nBestHeight != cachedNumBlocks) + { + cachedNumBlocks = nBestHeight; + // Blocks came in since last poll. + // Invalidate status (number of confirmations) and (possibly) description + // for all rows. Qt is smart enough to only actually request the data for the + // visible rows. + emit dataChanged(index(0, Status), index(priv->size()-1, Status)); + emit dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress)); + } +} + +int TransactionTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int TransactionTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns.length(); +} + +QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) const +{ + QString status; + + switch(wtx->status.status) + { + case TransactionStatus::OpenUntilBlock: + status = tr("Open for %n block(s)","",wtx->status.open_for); + break; + case TransactionStatus::OpenUntilDate: + status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for)); + break; + case TransactionStatus::Offline: + status = tr("Offline (%1 confirmations)").arg(wtx->status.depth); + break; + case TransactionStatus::Unconfirmed: + status = tr("Unconfirmed (%1 of %2 confirmations)").arg(wtx->status.depth).arg(TransactionRecord::NumConfirmations); + break; + case TransactionStatus::HaveConfirmations: + status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth); + break; + } + if(wtx->type == TransactionRecord::Generated) + { + switch(wtx->status.maturity) + { + case TransactionStatus::Immature: + 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; + case TransactionStatus::MaturesWarning: + status += "\n" + tr("This block was not received by any other nodes and will probably not be accepted!"); + break; + case TransactionStatus::NotAccepted: + status += "\n" + tr("Generated but not accepted"); + break; + } + } + + return status; +} + +QString TransactionTableModel::formatTxDate(const TransactionRecord *wtx) const +{ + if(wtx->time) + { + return GUIUtil::dateTimeStr(wtx->time); + } + else + { + return QString(); + } +} + +/* Look up address in address book, if found return label (address) + otherwise just return (address) + */ +QString TransactionTableModel::lookupAddress(const std::string &address, bool tooltip) const +{ + QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(address)); + QString description; + if(!label.isEmpty()) + { + description += label + QString(" "); + } + if(label.isEmpty() || walletModel->getOptionsModel()->getDisplayAddresses() || tooltip) + { + description += QString("(") + QString::fromStdString(address) + QString(")"); + } + return description; +} + +QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const +{ + switch(wtx->type) + { + case TransactionRecord::RecvWithAddress: + return tr("Received with"); + case TransactionRecord::RecvFromOther: + return tr("Received from"); + case TransactionRecord::SendToAddress: + case TransactionRecord::SendToOther: + return tr("Sent to"); + case TransactionRecord::SendToSelf: + return tr("Payment to yourself"); + case TransactionRecord::Generated: + return tr("Mined"); + default: + return QString(); + } +} + +QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx) const +{ + switch(wtx->type) + { + case TransactionRecord::Generated: + return QIcon(":/icons/tx_mined"); + case TransactionRecord::RecvWithAddress: + case TransactionRecord::RecvFromOther: + return QIcon(":/icons/tx_input"); + case TransactionRecord::SendToAddress: + case TransactionRecord::SendToOther: + return QIcon(":/icons/tx_output"); + default: + return QIcon(":/icons/tx_inout"); + } + return QVariant(); +} + +QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const +{ + switch(wtx->type) + { + case TransactionRecord::RecvFromOther: + return QString::fromStdString(wtx->address); + case TransactionRecord::RecvWithAddress: + case TransactionRecord::SendToAddress: + return lookupAddress(wtx->address, tooltip); + case TransactionRecord::SendToOther: + return QString::fromStdString(wtx->address); + case TransactionRecord::SendToSelf: + case TransactionRecord::Generated: + default: + return tr("(n/a)"); + } +} + +QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const +{ + // Show addresses without label in a less visible color + switch(wtx->type) + { + case TransactionRecord::RecvWithAddress: + case TransactionRecord::SendToAddress: + { + QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address)); + if(label.isEmpty()) + return COLOR_BAREADDRESS; + } break; + case TransactionRecord::SendToSelf: + case TransactionRecord::Generated: + return COLOR_BAREADDRESS; + default: + break; + } + return QVariant(); +} + +QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed) const +{ + QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit); + if(showUnconfirmed) + { + if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature) + { + str = QString("[") + str + QString("]"); + } + } + return QString(str); +} + +QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) const +{ + if(wtx->type == TransactionRecord::Generated) + { + switch(wtx->status.maturity) + { + case TransactionStatus::Immature: { + int total = wtx->status.depth + wtx->status.matures_in; + int part = (wtx->status.depth * 4 / total) + 1; + return QIcon(QString(":/icons/transaction_%1").arg(part)); + } + case TransactionStatus::Mature: + return QIcon(":/icons/transaction_confirmed"); + case TransactionStatus::MaturesWarning: + case TransactionStatus::NotAccepted: + return QIcon(":/icons/transaction_0"); + } + } + else + { + switch(wtx->status.status) + { + case TransactionStatus::OpenUntilBlock: + case TransactionStatus::OpenUntilDate: + return QColor(64,64,255); + break; + case TransactionStatus::Offline: + return QColor(192,192,192); + case TransactionStatus::Unconfirmed: + switch(wtx->status.depth) + { + case 0: return QIcon(":/icons/transaction_0"); + case 1: return QIcon(":/icons/transaction_1"); + case 2: return QIcon(":/icons/transaction_2"); + case 3: return QIcon(":/icons/transaction_3"); + case 4: return QIcon(":/icons/transaction_4"); + default: return QIcon(":/icons/transaction_5"); + }; + case TransactionStatus::HaveConfirmations: + return QIcon(":/icons/transaction_confirmed"); + } + } + return QColor(0,0,0); +} + +QString TransactionTableModel::formatTooltip(const TransactionRecord *rec) const +{ + QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec); + if(rec->type==TransactionRecord::RecvFromOther || rec->type==TransactionRecord::SendToOther || + rec->type==TransactionRecord::SendToAddress || rec->type==TransactionRecord::RecvWithAddress) + { + tooltip += QString(" ") + formatTxToAddress(rec, true); + } + return tooltip; +} + +QVariant TransactionTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + TransactionRecord *rec = static_cast(index.internalPointer()); + + switch(role) + { + case Qt::DecorationRole: + switch(index.column()) + { + case Status: + return txStatusDecoration(rec); + case ToAddress: + return txAddressDecoration(rec); + } + break; + case Qt::DisplayRole: + switch(index.column()) + { + case Date: + return formatTxDate(rec); + case Type: + return formatTxType(rec); + case ToAddress: + return formatTxToAddress(rec, false); + case Amount: + return formatTxAmount(rec); + } + break; + case Qt::EditRole: + // Edit role is used for sorting, so return the unformatted values + switch(index.column()) + { + case Status: + return QString::fromStdString(rec->status.sortKey); + case Date: + return rec->time; + case Type: + return formatTxType(rec); + case ToAddress: + return formatTxToAddress(rec, true); + case Amount: + return rec->credit + rec->debit; + } + break; + case Qt::ToolTipRole: + return formatTooltip(rec); + case Qt::TextAlignmentRole: + return column_alignments[index.column()]; + case Qt::ForegroundRole: + // Non-confirmed transactions are grey + if(!rec->status.confirmed) + { + return COLOR_UNCONFIRMED; + } + if(index.column() == Amount && (rec->credit+rec->debit) < 0) + { + return COLOR_NEGATIVE; + } + if(index.column() == ToAddress) + { + return addressColor(rec); + } + break; + case TypeRole: + return rec->type; + case DateRole: + return QDateTime::fromTime_t(static_cast(rec->time)); + case LongDescriptionRole: + return priv->describe(rec); + case AddressRole: + return QString::fromStdString(rec->address); + case LabelRole: + return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); + case AmountRole: + return rec->credit + rec->debit; + case TxIDRole: + return QString::fromStdString(rec->getTxID()); + case ConfirmedRole: + // Return True if transaction counts for balance + return rec->status.confirmed && !(rec->type == TransactionRecord::Generated && + rec->status.maturity != TransactionStatus::Mature); + case FormattedAmountRole: + return formatTxAmount(rec, false); + } + return QVariant(); +} + +QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole) + { + return columns[section]; + } + else if (role == Qt::TextAlignmentRole) + { + return column_alignments[section]; + } else if (role == Qt::ToolTipRole) + { + switch(section) + { + case Status: + return tr("Transaction status. Hover over this field to show number of confirmations."); + case Date: + return tr("Date and time that the transaction was received."); + case Type: + return tr("Type of transaction."); + case ToAddress: + return tr("Destination address of transaction."); + case Amount: + return tr("Amount removed from or added to balance."); + } + } + } + return QVariant(); +} + +QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + TransactionRecord *data = priv->index(row); + if(data) + { + return createIndex(row, column, priv->index(row)); + } + else + { + return QModelIndex(); + } +} + +void TransactionTableModel::updateDisplayUnit() +{ + // emit dataChanged to update Amount column with the current unit + emit dataChanged(index(0, Amount), index(priv->size()-1, Amount)); +} diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h new file mode 100644 index 0000000..fd321ce --- /dev/null +++ b/src/qt/transactiontablemodel.h @@ -0,0 +1,85 @@ +#ifndef TRANSACTIONTABLEMODEL_H +#define TRANSACTIONTABLEMODEL_H + +#include +#include + +class CWallet; +class TransactionTablePriv; +class TransactionRecord; +class WalletModel; + +/** UI model for the transaction table of a wallet. + */ +class TransactionTableModel : public QAbstractTableModel +{ + Q_OBJECT +public: + explicit TransactionTableModel(CWallet* wallet, WalletModel *parent = 0); + ~TransactionTableModel(); + + enum ColumnIndex { + Status = 0, + Date = 1, + Type = 2, + ToAddress = 3, + Amount = 4 + }; + + /** Roles to get specific information from a transaction row. + These are independent of column. + */ + enum RoleIndex { + /** Type of transaction */ + TypeRole = Qt::UserRole, + /** Date and time this transaction was created */ + DateRole, + /** Long description (HTML format) */ + LongDescriptionRole, + /** Address of transaction */ + AddressRole, + /** Label of address related to transaction */ + LabelRole, + /** Net amount of transaction */ + AmountRole, + /** Unique identifier */ + TxIDRole, + /** Is transaction confirmed? */ + ConfirmedRole, + /** Formatted amount, without brackets when unconfirmed */ + FormattedAmountRole + }; + + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; +private: + CWallet* wallet; + WalletModel *walletModel; + QStringList columns; + TransactionTablePriv *priv; + int cachedNumBlocks; + + QString lookupAddress(const std::string &address, bool tooltip) const; + QVariant addressColor(const TransactionRecord *wtx) const; + QString formatTxStatus(const TransactionRecord *wtx) const; + QString formatTxDate(const TransactionRecord *wtx) const; + QString formatTxType(const TransactionRecord *wtx) const; + QString formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const; + QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true) const; + QString formatTooltip(const TransactionRecord *rec) const; + QVariant txStatusDecoration(const TransactionRecord *wtx) const; + QVariant txAddressDecoration(const TransactionRecord *wtx) const; + +public slots: + void updateTransaction(const QString &hash, int status); + void updateConfirmations(); + void updateDisplayUnit(); + + friend class TransactionTablePriv; +}; + +#endif + diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp new file mode 100644 index 0000000..1370a30 --- /dev/null +++ b/src/qt/transactionview.cpp @@ -0,0 +1,431 @@ +#include "transactionview.h" + +#include "transactionfilterproxy.h" +#include "transactionrecord.h" +#include "walletmodel.h" +#include "addresstablemodel.h" +#include "transactiontablemodel.h" +#include "bitcoinunits.h" +#include "csvmodelwriter.h" +#include "transactiondescdialog.h" +#include "editaddressdialog.h" +#include "optionsmodel.h" +#include "guiutil.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +TransactionView::TransactionView(QWidget *parent) : + QWidget(parent), model(0), transactionProxyModel(0), + transactionView(0) +{ + // Build filter row + setContentsMargins(0,0,0,0); + + QHBoxLayout *hlayout = new QHBoxLayout(); + hlayout->setContentsMargins(0,0,0,0); +#ifdef Q_WS_MAC + hlayout->setSpacing(5); + hlayout->addSpacing(26); +#else + hlayout->setSpacing(0); + hlayout->addSpacing(23); +#endif + + dateWidget = new QComboBox(this); +#ifdef Q_WS_MAC + dateWidget->setFixedWidth(121); +#else + dateWidget->setFixedWidth(120); +#endif + dateWidget->addItem(tr("All"), All); + dateWidget->addItem(tr("Today"), Today); + dateWidget->addItem(tr("This week"), ThisWeek); + dateWidget->addItem(tr("This month"), ThisMonth); + dateWidget->addItem(tr("Last month"), LastMonth); + dateWidget->addItem(tr("This year"), ThisYear); + dateWidget->addItem(tr("Range..."), Range); + hlayout->addWidget(dateWidget); + + typeWidget = new QComboBox(this); +#ifdef Q_WS_MAC + typeWidget->setFixedWidth(121); +#else + typeWidget->setFixedWidth(120); +#endif + + typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES); + typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) | + TransactionFilterProxy::TYPE(TransactionRecord::RecvFromOther)); + typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) | + TransactionFilterProxy::TYPE(TransactionRecord::SendToOther)); + typeWidget->addItem(tr("To yourself"), TransactionFilterProxy::TYPE(TransactionRecord::SendToSelf)); + typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated)); + typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other)); + + hlayout->addWidget(typeWidget); + + addressWidget = new QLineEdit(this); +#if QT_VERSION >= 0x040700 + /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + addressWidget->setPlaceholderText(tr("Enter address or label to search")); +#endif + hlayout->addWidget(addressWidget); + + amountWidget = new QLineEdit(this); +#if QT_VERSION >= 0x040700 + /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + amountWidget->setPlaceholderText(tr("Min amount")); +#endif +#ifdef Q_WS_MAC + amountWidget->setFixedWidth(97); +#else + amountWidget->setFixedWidth(100); +#endif + amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this)); + hlayout->addWidget(amountWidget); + + QVBoxLayout *vlayout = new QVBoxLayout(this); + vlayout->setContentsMargins(0,0,0,0); + vlayout->setSpacing(0); + + QTableView *view = new QTableView(this); + vlayout->addLayout(hlayout); + vlayout->addWidget(createDateRangeWidget()); + vlayout->addWidget(view); + vlayout->setSpacing(0); + int width = view->verticalScrollBar()->sizeHint().width(); + // Cover scroll bar width with spacing +#ifdef Q_WS_MAC + hlayout->addSpacing(width+2); +#else + hlayout->addSpacing(width); +#endif + // Always show scroll bar + view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + view->setTabKeyNavigation(false); + view->setContextMenuPolicy(Qt::CustomContextMenu); + + transactionView = view; + + // Actions + QAction *copyAddressAction = new QAction(tr("Copy address"), this); + QAction *copyLabelAction = new QAction(tr("Copy label"), this); + QAction *copyAmountAction = new QAction(tr("Copy amount"), this); + QAction *editLabelAction = new QAction(tr("Edit label"), this); + QAction *showDetailsAction = new QAction(tr("Show transaction details"), this); + + contextMenu = new QMenu(); + contextMenu->addAction(copyAddressAction); + contextMenu->addAction(copyLabelAction); + contextMenu->addAction(copyAmountAction); + contextMenu->addAction(editLabelAction); + contextMenu->addAction(showDetailsAction); + + // Connect actions + connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int))); + connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int))); + connect(addressWidget, SIGNAL(textChanged(QString)), this, SLOT(changedPrefix(QString))); + connect(amountWidget, SIGNAL(textChanged(QString)), this, SLOT(changedAmount(QString))); + + connect(view, SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(doubleClicked(QModelIndex))); + connect(view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); + + connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); + connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); + connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); + connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel())); + connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); +} + +void TransactionView::setModel(WalletModel *model) +{ + this->model = model; + if(model) + { + transactionProxyModel = new TransactionFilterProxy(this); + transactionProxyModel->setSourceModel(model->getTransactionTableModel()); + transactionProxyModel->setDynamicSortFilter(true); + transactionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + + transactionProxyModel->setSortRole(Qt::EditRole); + + transactionView->setModel(transactionProxyModel); + transactionView->setAlternatingRowColors(true); + transactionView->setSelectionBehavior(QAbstractItemView::SelectRows); + transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection); + transactionView->setSortingEnabled(true); + transactionView->sortByColumn(TransactionTableModel::Status, Qt::DescendingOrder); + transactionView->verticalHeader()->hide(); + + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Status, 23); + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Date, 120); + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Type, 120); + transactionView->horizontalHeader()->setResizeMode( + TransactionTableModel::ToAddress, QHeaderView::Stretch); + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Amount, 100); + } +} + +void TransactionView::chooseDate(int idx) +{ + if(!transactionProxyModel) + return; + QDate current = QDate::currentDate(); + dateRangeWidget->setVisible(false); + switch(dateWidget->itemData(idx).toInt()) + { + case All: + transactionProxyModel->setDateRange( + TransactionFilterProxy::MIN_DATE, + TransactionFilterProxy::MAX_DATE); + break; + case Today: + transactionProxyModel->setDateRange( + QDateTime(current), + TransactionFilterProxy::MAX_DATE); + break; + case ThisWeek: { + // Find last monday + QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1)); + transactionProxyModel->setDateRange( + QDateTime(startOfWeek), + TransactionFilterProxy::MAX_DATE); + + } break; + case ThisMonth: + transactionProxyModel->setDateRange( + QDateTime(QDate(current.year(), current.month(), 1)), + TransactionFilterProxy::MAX_DATE); + break; + case LastMonth: + transactionProxyModel->setDateRange( + QDateTime(QDate(current.year(), current.month()-1, 1)), + QDateTime(QDate(current.year(), current.month(), 1))); + break; + case ThisYear: + transactionProxyModel->setDateRange( + QDateTime(QDate(current.year(), 1, 1)), + TransactionFilterProxy::MAX_DATE); + break; + case Range: + dateRangeWidget->setVisible(true); + dateRangeChanged(); + break; + } +} + +void TransactionView::chooseType(int idx) +{ + if(!transactionProxyModel) + return; + transactionProxyModel->setTypeFilter( + typeWidget->itemData(idx).toInt()); +} + +void TransactionView::changedPrefix(const QString &prefix) +{ + if(!transactionProxyModel) + return; + transactionProxyModel->setAddressPrefix(prefix); +} + +void TransactionView::changedAmount(const QString &amount) +{ + if(!transactionProxyModel) + return; + qint64 amount_parsed = 0; + if(BitcoinUnits::parse(model->getOptionsModel()->getDisplayUnit(), amount, &amount_parsed)) + { + transactionProxyModel->setMinAmount(amount_parsed); + } + else + { + transactionProxyModel->setMinAmount(0); + } +} + +void TransactionView::exportClicked() +{ + // CSV is currently the only supported format + QString filename = GUIUtil::getSaveFileName( + this, + tr("Export Transaction Data"), QString(), + tr("Comma separated file (*.csv)")); + + if (filename.isNull()) return; + + CSVModelWriter writer(filename); + + // name, column, role + writer.setModel(transactionProxyModel); + writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole); + writer.addColumn(tr("Date"), 0, TransactionTableModel::DateRole); + writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole); + writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole); + writer.addColumn(tr("Address"), 0, TransactionTableModel::AddressRole); + writer.addColumn(tr("Amount"), 0, TransactionTableModel::FormattedAmountRole); + writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole); + + if(!writer.write()) + { + QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename), + QMessageBox::Abort, QMessageBox::Abort); + } +} + +void TransactionView::contextualMenu(const QPoint &point) +{ + QModelIndex index = transactionView->indexAt(point); + if(index.isValid()) + { + contextMenu->exec(QCursor::pos()); + } +} + +void TransactionView::copyAddress() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::AddressRole); +} + +void TransactionView::copyLabel() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::LabelRole); +} + +void TransactionView::copyAmount() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::FormattedAmountRole); +} + +void TransactionView::editLabel() +{ + if(!transactionView->selectionModel() ||!model) + return; + QModelIndexList selection = transactionView->selectionModel()->selectedRows(); + if(!selection.isEmpty()) + { + AddressTableModel *addressBook = model->getAddressTableModel(); + if(!addressBook) + return; + QString address = selection.at(0).data(TransactionTableModel::AddressRole).toString(); + if(address.isEmpty()) + { + // If this transaction has no associated address, exit + return; + } + // Is address in address book? Address book can miss address when a transaction is + // sent from outside the UI. + int idx = addressBook->lookupAddress(address); + if(idx != -1) + { + // Edit sending / receiving address + QModelIndex modelIdx = addressBook->index(idx, 0, QModelIndex()); + // Determine type of address, launch appropriate editor dialog type + QString type = modelIdx.data(AddressTableModel::TypeRole).toString(); + + EditAddressDialog dlg(type==AddressTableModel::Receive + ? EditAddressDialog::EditReceivingAddress + : EditAddressDialog::EditSendingAddress, + this); + dlg.setModel(addressBook); + dlg.loadRow(idx); + dlg.exec(); + } + else + { + // Add sending address + EditAddressDialog dlg(EditAddressDialog::NewSendingAddress, + this); + dlg.setModel(addressBook); + dlg.setAddress(address); + dlg.exec(); + } + } +} + +void TransactionView::showDetails() +{ + if(!transactionView->selectionModel()) + return; + QModelIndexList selection = transactionView->selectionModel()->selectedRows(); + if(!selection.isEmpty()) + { + TransactionDescDialog dlg(selection.at(0)); + dlg.exec(); + } +} + +QWidget *TransactionView::createDateRangeWidget() +{ + dateRangeWidget = new QFrame(); + dateRangeWidget->setFrameStyle(QFrame::Panel | QFrame::Raised); + dateRangeWidget->setContentsMargins(1,1,1,1); + QHBoxLayout *layout = new QHBoxLayout(dateRangeWidget); + layout->setContentsMargins(0,0,0,0); + layout->addSpacing(23); + layout->addWidget(new QLabel(tr("Range:"))); + + dateFrom = new QDateTimeEdit(this); + dateFrom->setDisplayFormat("dd/MM/yy"); + dateFrom->setCalendarPopup(true); + dateFrom->setMinimumWidth(100); + dateFrom->setDate(QDate::currentDate().addDays(-7)); + layout->addWidget(dateFrom); + layout->addWidget(new QLabel(tr("to"))); + + dateTo = new QDateTimeEdit(this); + dateTo->setDisplayFormat("dd/MM/yy"); + dateTo->setCalendarPopup(true); + dateTo->setMinimumWidth(100); + dateTo->setDate(QDate::currentDate()); + layout->addWidget(dateTo); + layout->addStretch(); + + // Hide by default + dateRangeWidget->setVisible(false); + + // Notify on change + connect(dateFrom, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged())); + connect(dateTo, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged())); + + return dateRangeWidget; +} + +void TransactionView::dateRangeChanged() +{ + if(!transactionProxyModel) + return; + transactionProxyModel->setDateRange( + QDateTime(dateFrom->date()), + QDateTime(dateTo->date()).addDays(1)); +} + +void TransactionView::focusTransaction(const QModelIndex &idx) +{ + if(!transactionProxyModel) + return; + QModelIndex targetIdx = transactionProxyModel->mapFromSource(idx); + transactionView->scrollTo(targetIdx); + transactionView->setCurrentIndex(targetIdx); + transactionView->setFocus(); +} diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h new file mode 100644 index 0000000..4ade3ec --- /dev/null +++ b/src/qt/transactionview.h @@ -0,0 +1,82 @@ +#ifndef TRANSACTIONVIEW_H +#define TRANSACTIONVIEW_H + +#include + +class WalletModel; +class TransactionFilterProxy; + +QT_BEGIN_NAMESPACE +class QTableView; +class QComboBox; +class QLineEdit; +class QModelIndex; +class QMenu; +class QFrame; +class QDateTimeEdit; +QT_END_NAMESPACE + +/** Widget showing the transaction list for a wallet, including a filter row. + Using the filter row, the user can view or export a subset of the transactions. + */ +class TransactionView : public QWidget +{ + Q_OBJECT +public: + explicit TransactionView(QWidget *parent = 0); + + void setModel(WalletModel *model); + + // Date ranges for filter + enum DateEnum + { + All, + Today, + ThisWeek, + ThisMonth, + LastMonth, + ThisYear, + Range + }; + +private: + WalletModel *model; + TransactionFilterProxy *transactionProxyModel; + QTableView *transactionView; + + QComboBox *dateWidget; + QComboBox *typeWidget; + QLineEdit *addressWidget; + QLineEdit *amountWidget; + + QMenu *contextMenu; + + QFrame *dateRangeWidget; + QDateTimeEdit *dateFrom; + QDateTimeEdit *dateTo; + + QWidget *createDateRangeWidget(); + +private slots: + void contextualMenu(const QPoint &); + void dateRangeChanged(); + void showDetails(); + void copyAddress(); + void editLabel(); + void copyLabel(); + void copyAmount(); + +signals: + void doubleClicked(const QModelIndex&); + +public slots: + void chooseDate(int idx); + void chooseType(int idx); + void changedPrefix(const QString &prefix); + void changedAmount(const QString &amount); + void exportClicked(); + void focusTransaction(const QModelIndex&); + +}; + +#endif // TRANSACTIONVIEW_H diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp new file mode 100644 index 0000000..3568616 --- /dev/null +++ b/src/qt/walletmodel.cpp @@ -0,0 +1,376 @@ +#include "walletmodel.h" +#include "guiconstants.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" +#include "transactiontablemodel.h" + +#include "ui_interface.h" +#include "wallet.h" +#include "walletdb.h" // for BackupWallet +#include "base58.h" + +#include +#include + +WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : + QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), + transactionTableModel(0), + cachedBalance(0), cachedUnconfirmedBalance(0), cachedImmatureBalance(0), + cachedNumTransactions(0), + cachedEncryptionStatus(Unencrypted), + cachedNumBlocks(0) +{ + addressTableModel = new AddressTableModel(wallet, this); + transactionTableModel = new TransactionTableModel(wallet, this); + + // This timer will be fired repeatedly to update the balance + pollTimer = new QTimer(this); + connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollBalanceChanged())); + pollTimer->start(MODEL_UPDATE_DELAY); + + subscribeToCoreSignals(); +} + +WalletModel::~WalletModel() +{ + unsubscribeFromCoreSignals(); +} + +qint64 WalletModel::getBalance() const +{ + return wallet->GetBalance(); +} + +qint64 WalletModel::getUnconfirmedBalance() const +{ + return wallet->GetUnconfirmedBalance(); +} + +qint64 WalletModel::getImmatureBalance() const +{ + return wallet->GetImmatureBalance(); +} + +int WalletModel::getNumTransactions() const +{ + int numTransactions = 0; + { + LOCK(wallet->cs_wallet); + numTransactions = wallet->mapWallet.size(); + } + return numTransactions; +} + +void WalletModel::updateStatus() +{ + EncryptionStatus newEncryptionStatus = getEncryptionStatus(); + + if(cachedEncryptionStatus != newEncryptionStatus) + emit encryptionStatusChanged(newEncryptionStatus); +} + +void WalletModel::pollBalanceChanged() +{ + if(nBestHeight != cachedNumBlocks) + { + // Balance and number of transactions might have changed + cachedNumBlocks = nBestHeight; + checkBalanceChanged(); + } +} + +void WalletModel::checkBalanceChanged() +{ + qint64 newBalance = getBalance(); + qint64 newUnconfirmedBalance = getUnconfirmedBalance(); + qint64 newImmatureBalance = getImmatureBalance(); + + if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance) + { + cachedBalance = newBalance; + cachedUnconfirmedBalance = newUnconfirmedBalance; + cachedImmatureBalance = newImmatureBalance; + emit balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance); + } +} + +void WalletModel::updateTransaction(const QString &hash, int status) +{ + if(transactionTableModel) + transactionTableModel->updateTransaction(hash, status); + + // Balance and number of transactions might have changed + checkBalanceChanged(); + + int newNumTransactions = getNumTransactions(); + if(cachedNumTransactions != newNumTransactions) + { + cachedNumTransactions = newNumTransactions; + emit numTransactionsChanged(newNumTransactions); + } +} + +void WalletModel::updateAddressBook(const QString &address, const QString &label, bool isMine, int status) +{ + if(addressTableModel) + addressTableModel->updateEntry(address, label, isMine, status); +} + +bool WalletModel::validateAddress(const QString &address) +{ + CBitcoinAddress addressParsed(address.toStdString()); + return addressParsed.IsValid(); +} + +WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList &recipients) +{ + qint64 total = 0; + QSet setAddress; + QString hex; + + if(recipients.empty()) + { + return OK; + } + + // Pre-check input data for validity + foreach(const SendCoinsRecipient &rcp, recipients) + { + if(!validateAddress(rcp.address)) + { + return InvalidAddress; + } + setAddress.insert(rcp.address); + + if(rcp.amount <= 0) + { + return InvalidAmount; + } + total += rcp.amount; + } + + if(recipients.size() > setAddress.size()) + { + return DuplicateAddress; + } + + if(total > getBalance()) + { + return AmountExceedsBalance; + } + + if((total + nTransactionFee) > getBalance()) + { + return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); + } + + { + LOCK2(cs_main, wallet->cs_wallet); + + // Sendmany + std::vector > vecSend; + foreach(const SendCoinsRecipient &rcp, recipients) + { + CScript scriptPubKey; + scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); + vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); + } + + CWalletTx wtx; + CReserveKey keyChange(wallet); + int64 nFeeRequired = 0; + bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); + + if(!fCreated) + { + if((total + nFeeRequired) > wallet->GetBalance()) + { + return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); + } + return TransactionCreationFailed; + } + if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) + { + return Aborted; + } + if(!wallet->CommitTransaction(wtx, keyChange)) + { + return TransactionCommitFailed; + } + hex = QString::fromStdString(wtx.GetHash().GetHex()); + } + + // Add addresses / update labels that we've sent to to the address book + foreach(const SendCoinsRecipient &rcp, recipients) + { + std::string strAddress = rcp.address.toStdString(); + CTxDestination dest = CBitcoinAddress(strAddress).Get(); + std::string strLabel = rcp.label.toStdString(); + { + LOCK(wallet->cs_wallet); + + std::map::iterator mi = wallet->mapAddressBook.find(dest); + + // Check if we have a new address or an updated label + if (mi == wallet->mapAddressBook.end() || mi->second != strLabel) + { + wallet->SetAddressBookName(dest, strLabel); + } + } + } + + return SendCoinsReturn(OK, 0, hex); +} + +OptionsModel *WalletModel::getOptionsModel() +{ + return optionsModel; +} + +AddressTableModel *WalletModel::getAddressTableModel() +{ + return addressTableModel; +} + +TransactionTableModel *WalletModel::getTransactionTableModel() +{ + return transactionTableModel; +} + +WalletModel::EncryptionStatus WalletModel::getEncryptionStatus() const +{ + if(!wallet->IsCrypted()) + { + return Unencrypted; + } + else if(wallet->IsLocked()) + { + return Locked; + } + else + { + return Unlocked; + } +} + +bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphrase) +{ + if(encrypted) + { + // Encrypt + return wallet->EncryptWallet(passphrase); + } + else + { + // Decrypt -- TODO; not supported yet + return false; + } +} + +bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase) +{ + if(locked) + { + // Lock + return wallet->Lock(); + } + else + { + // Unlock + return wallet->Unlock(passPhrase); + } +} + +bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass) +{ + bool retval; + { + LOCK(wallet->cs_wallet); + wallet->Lock(); // Make sure wallet is locked before attempting pass change + retval = wallet->ChangeWalletPassphrase(oldPass, newPass); + } + return retval; +} + +bool WalletModel::backupWallet(const QString &filename) +{ + return BackupWallet(*wallet, filename.toLocal8Bit().data()); +} + +// Handlers for core signals +static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet) +{ + OutputDebugStringF("NotifyKeyStoreStatusChanged\n"); + QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection); +} + +static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status) +{ + OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", CBitcoinAddress(address).ToString().c_str(), label.c_str(), isMine, status); + QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())), + Q_ARG(QString, QString::fromStdString(label)), + Q_ARG(bool, isMine), + Q_ARG(int, status)); +} + +static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status) +{ + OutputDebugStringF("NotifyTransactionChanged %s status=%i\n", hash.GetHex().c_str(), status); + QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(hash.GetHex())), + Q_ARG(int, status)); +} + +void WalletModel::subscribeToCoreSignals() +{ + // Connect signals to wallet + wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1)); + wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5)); + wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); +} + +void WalletModel::unsubscribeFromCoreSignals() +{ + // Disconnect signals from wallet + wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1)); + wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5)); + wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); +} + +// WalletModel::UnlockContext implementation +WalletModel::UnlockContext WalletModel::requestUnlock() +{ + bool was_locked = getEncryptionStatus() == Locked; + if(was_locked) + { + // Request UI to unlock wallet + emit requireUnlock(); + } + // If wallet is still locked, unlock was failed or cancelled, mark context as invalid + bool valid = getEncryptionStatus() != Locked; + + return UnlockContext(this, valid, was_locked); +} + +WalletModel::UnlockContext::UnlockContext(WalletModel *wallet, bool valid, bool relock): + wallet(wallet), + valid(valid), + relock(relock) +{ +} + +WalletModel::UnlockContext::~UnlockContext() +{ + if(valid && relock) + { + wallet->setWalletLocked(true); + } +} + +void WalletModel::UnlockContext::CopyFrom(const UnlockContext& rhs) +{ + // Transfer context; old object no longer relocks wallet + *this = rhs; + rhs.relock = false; +} diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h new file mode 100644 index 0000000..62558a4 --- /dev/null +++ b/src/qt/walletmodel.h @@ -0,0 +1,165 @@ +#ifndef WALLETMODEL_H +#define WALLETMODEL_H + +#include + +#include "allocators.h" /* for SecureString */ + +class OptionsModel; +class AddressTableModel; +class TransactionTableModel; +class CWallet; + +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + +class SendCoinsRecipient +{ +public: + QString address; + QString label; + qint64 amount; +}; + +/** Interface to Bitcoin wallet from Qt view code. */ +class WalletModel : public QObject +{ + Q_OBJECT +public: + explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); + ~WalletModel(); + + enum StatusCode // Returned by sendCoins + { + OK, + InvalidAmount, + InvalidAddress, + AmountExceedsBalance, + AmountWithFeeExceedsBalance, + DuplicateAddress, + TransactionCreationFailed, // Error returned when wallet is still locked + TransactionCommitFailed, + Aborted + }; + + enum EncryptionStatus + { + Unencrypted, // !wallet->IsCrypted() + Locked, // wallet->IsCrypted() && wallet->IsLocked() + Unlocked // wallet->IsCrypted() && !wallet->IsLocked() + }; + + OptionsModel *getOptionsModel(); + AddressTableModel *getAddressTableModel(); + TransactionTableModel *getTransactionTableModel(); + + qint64 getBalance() const; + qint64 getUnconfirmedBalance() const; + qint64 getImmatureBalance() const; + int getNumTransactions() const; + EncryptionStatus getEncryptionStatus() const; + + // Check address for validity + bool validateAddress(const QString &address); + + // Return status record for SendCoins, contains error id + information + struct SendCoinsReturn + { + SendCoinsReturn(StatusCode status, + qint64 fee=0, + QString hex=QString()): + status(status), fee(fee), hex(hex) {} + StatusCode status; + qint64 fee; // is used in case status is "AmountWithFeeExceedsBalance" + QString hex; // is filled with the transaction hash if status is "OK" + }; + + // Send coins to a list of recipients + SendCoinsReturn sendCoins(const QList &recipients); + + // Wallet encryption + bool setWalletEncrypted(bool encrypted, const SecureString &passphrase); + // Passphrase only needed when unlocking + bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString()); + bool changePassphrase(const SecureString &oldPass, const SecureString &newPass); + // Wallet backup + bool backupWallet(const QString &filename); + + // RAI object for unlocking wallet, returned by requestUnlock() + class UnlockContext + { + public: + UnlockContext(WalletModel *wallet, bool valid, bool relock); + ~UnlockContext(); + + bool isValid() const { return valid; } + + // Copy operator and constructor transfer the context + UnlockContext(const UnlockContext& obj) { CopyFrom(obj); } + UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; } + private: + WalletModel *wallet; + bool valid; + mutable bool relock; // mutable, as it can be set to false by copying + + void CopyFrom(const UnlockContext& rhs); + }; + + UnlockContext requestUnlock(); + +private: + CWallet *wallet; + + // Wallet has an options model for wallet-specific options + // (transaction fee, for example) + OptionsModel *optionsModel; + + AddressTableModel *addressTableModel; + TransactionTableModel *transactionTableModel; + + // Cache some values to be able to detect changes + qint64 cachedBalance; + qint64 cachedUnconfirmedBalance; + qint64 cachedImmatureBalance; + qint64 cachedNumTransactions; + EncryptionStatus cachedEncryptionStatus; + int cachedNumBlocks; + + QTimer *pollTimer; + + void subscribeToCoreSignals(); + void unsubscribeFromCoreSignals(); + void checkBalanceChanged(); + +signals: + // Signal that balance in wallet changed + void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance); + + // Number of transactions in wallet changed + void numTransactionsChanged(int count); + + // Encryption status of wallet changed + void encryptionStatusChanged(int status); + + // Signal emitted when wallet needs to be unlocked + // It is valid behaviour for listeners to keep the wallet locked after this signal; + // this means that the unlocking failed or was cancelled. + void requireUnlock(); + + // Asynchronous error notification + void error(const QString &title, const QString &message, bool modal); + +public slots: + /* Wallet status might have changed */ + void updateStatus(); + /* New transaction, or transaction changed status */ + void updateTransaction(const QString &hash, int status); + /* New, updated or removed address book entry */ + void updateAddressBook(const QString &address, const QString &label, bool isMine, int status); + /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */ + void pollBalanceChanged(); +}; + + +#endif // WALLETMODEL_H diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp new file mode 100644 index 0000000..0f6f55b --- /dev/null +++ b/src/rpcdump.cpp @@ -0,0 +1,93 @@ +// Copyright (c) 2009-2012 Bitcoin Developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "init.h" // for pwalletMain +#include "bitcoinrpc.h" +#include "ui_interface.h" +#include "base58.h" + +#include + +#define printf OutputDebugStringF + +using namespace json_spirit; +using namespace std; + +class CTxDump +{ +public: + CBlockIndex *pindex; + int64 nValue; + bool fSpent; + CWalletTx* ptx; + int nOut; + CTxDump(CWalletTx* ptx = NULL, int nOut = -1) + { + pindex = NULL; + nValue = 0; + fSpent = false; + this->ptx = ptx; + this->nOut = nOut; + } +}; + +Value importprivkey(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "importprivkey [label]\n" + "Adds a private key (as returned by dumpprivkey) to your wallet."); + + string strSecret = params[0].get_str(); + string strLabel = ""; + if (params.size() > 1) + strLabel = params[1].get_str(); + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(strSecret); + + if (!fGood) throw JSONRPCError(-5,"Invalid private key"); + + CKey key; + bool fCompressed; + CSecret secret = vchSecret.GetSecret(fCompressed); + key.SetSecret(secret, fCompressed); + CKeyID vchAddress = key.GetPubKey().GetID(); + { + LOCK2(cs_main, pwalletMain->cs_wallet); + + pwalletMain->MarkDirty(); + pwalletMain->SetAddressBookName(vchAddress, strLabel); + + if (!pwalletMain->AddKey(key)) + throw JSONRPCError(-4,"Error adding key to wallet"); + + pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true); + pwalletMain->ReacceptWalletTransactions(); + } + + return Value::null; +} + +Value dumpprivkey(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "dumpprivkey \n" + "Reveals the private key corresponding to ."); + + string strAddress = params[0].get_str(); + CBitcoinAddress address; + if (!address.SetString(strAddress)) + throw JSONRPCError(-5, "Invalid CasinoCoin address"); + CKeyID keyID; + if (!address.GetKeyID(keyID)) + throw JSONRPCError(-3, "Address does not refer to a key"); + CSecret vchSecret; + bool fCompressed; + if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed)) + throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known"); + return CBitcoinSecret(vchSecret, fCompressed).ToString(); +} diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp new file mode 100644 index 0000000..c716fb4 --- /dev/null +++ b/src/rpcnet.cpp @@ -0,0 +1,69 @@ +// Copyright (c) 2009-2012 Bitcoin Developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "net.h" +#include "bitcoinrpc.h" + +using namespace json_spirit; +using namespace std; + +Value getconnectioncount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getconnectioncount\n" + "Returns the number of connections to other nodes."); + + LOCK(cs_vNodes); + return (int)vNodes.size(); +} + +static void CopyNodeStats(std::vector& vstats) +{ + vstats.clear(); + + LOCK(cs_vNodes); + vstats.reserve(vNodes.size()); + BOOST_FOREACH(CNode* pnode, vNodes) { + CNodeStats stats; + pnode->copyStats(stats); + vstats.push_back(stats); + } +} + +Value getpeerinfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getpeerinfo\n" + "Returns data about each connected network node."); + + vector vstats; + CopyNodeStats(vstats); + + Array ret; + + BOOST_FOREACH(const CNodeStats& stats, vstats) { + Object obj; + + obj.push_back(Pair("addr", stats.addrName)); + obj.push_back(Pair("services", strprintf("%08"PRI64x, stats.nServices))); + obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend)); + obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv)); + obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected)); + obj.push_back(Pair("version", stats.nVersion)); + obj.push_back(Pair("subver", stats.strSubVer)); + obj.push_back(Pair("inbound", stats.fInbound)); + obj.push_back(Pair("releasetime", (boost::int64_t)stats.nReleaseTime)); + obj.push_back(Pair("startingheight", stats.nStartingHeight)); + obj.push_back(Pair("banscore", stats.nMisbehavior)); + + ret.push_back(obj); + } + + return ret; +} + diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp new file mode 100644 index 0000000..66e4d85 --- /dev/null +++ b/src/rpcrawtransaction.cpp @@ -0,0 +1,504 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include "base58.h" +#include "bitcoinrpc.h" +#include "db.h" +#include "init.h" +#include "main.h" +#include "net.h" +#include "wallet.h" + +using namespace std; +using namespace boost; +using namespace boost::assign; +using namespace json_spirit; + +// These are all in bitcoinrpc.cpp: +extern Object JSONRPCError(int code, const string& message); +extern int64 AmountFromValue(const Value& value); +extern Value ValueFromAmount(int64 amount); +extern std::string HelpRequiringPassphrase(); +extern void EnsureWalletIsUnlocked(); + +void +ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out) +{ + txnouttype type; + vector addresses; + int nRequired; + + out.push_back(Pair("asm", scriptPubKey.ToString())); + out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + + if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) + { + out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD))); + return; + } + + out.push_back(Pair("reqSigs", nRequired)); + out.push_back(Pair("type", GetTxnOutputType(type))); + + Array a; + BOOST_FOREACH(const CTxDestination& addr, addresses) + a.push_back(CBitcoinAddress(addr).ToString()); + out.push_back(Pair("addresses", a)); +} + +void +TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) +{ + entry.push_back(Pair("txid", tx.GetHash().GetHex())); + entry.push_back(Pair("version", tx.nVersion)); + entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); + Array vin; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + Object in; + if (tx.IsCoinBase()) + in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + else + { + in.push_back(Pair("txid", txin.prevout.hash.GetHex())); + in.push_back(Pair("vout", (boost::int64_t)txin.prevout.n)); + Object o; + o.push_back(Pair("asm", txin.scriptSig.ToString())); + o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + in.push_back(Pair("scriptSig", o)); + } + in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); + vin.push_back(in); + } + entry.push_back(Pair("vin", vin)); + Array vout; + for (unsigned int i = 0; i < tx.vout.size(); i++) + { + const CTxOut& txout = tx.vout[i]; + Object out; + out.push_back(Pair("value", ValueFromAmount(txout.nValue))); + out.push_back(Pair("n", (boost::int64_t)i)); + Object o; + ScriptPubKeyToJSON(txout.scriptPubKey, o); + out.push_back(Pair("scriptPubKey", o)); + vout.push_back(out); + } + entry.push_back(Pair("vout", vout)); + + if (hashBlock != 0) + { + entry.push_back(Pair("blockhash", hashBlock.GetHex())); + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end() && (*mi).second) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + { + entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); + entry.push_back(Pair("time", (boost::int64_t)pindex->nTime)); + } + else + entry.push_back(Pair("confirmations", 0)); + } + } +} + +Value getrawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "getrawtransaction [verbose=0]\n" + "If verbose=0, returns a string that is\n" + "serialized, hex-encoded data for .\n" + "If verbose is non-zero, returns an Object\n" + "with information about ."); + + uint256 hash; + hash.SetHex(params[0].get_str()); + + bool fVerbose = false; + if (params.size() > 1) + fVerbose = (params[1].get_int() != 0); + + CTransaction tx; + uint256 hashBlock = 0; + if (!GetTransaction(hash, tx, hashBlock)) + throw JSONRPCError(-5, "No information available about transaction"); + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + string strHex = HexStr(ssTx.begin(), ssTx.end()); + + if (!fVerbose) + return strHex; + + Object result; + result.push_back(Pair("hex", strHex)); + TxToJSON(tx, hashBlock, result); + return result; +} + +Value listunspent(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 2) + throw runtime_error( + "listunspent [minconf=1] [maxconf=999999]\n" + "Returns array of unspent transaction outputs\n" + "with between minconf and maxconf (inclusive) confirmations.\n" + "Results are an array of Objects, each of which has:\n" + "{txid, vout, scriptPubKey, amount, confirmations}"); + + RPCTypeCheck(params, list_of(int_type)(int_type)); + + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + int nMaxDepth = 999999; + if (params.size() > 1) + nMaxDepth = params[1].get_int(); + + Array results; + vector vecOutputs; + pwalletMain->AvailableCoins(vecOutputs, false); + BOOST_FOREACH(const COutput& out, vecOutputs) + { + if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) + continue; + + int64 nValue = out.tx->vout[out.i].nValue; + const CScript& pk = out.tx->vout[out.i].scriptPubKey; + Object entry; + entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); + entry.push_back(Pair("vout", out.i)); + entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); + entry.push_back(Pair("amount",ValueFromAmount(nValue))); + entry.push_back(Pair("confirmations",out.nDepth)); + results.push_back(entry); + } + + return results; +} + +Value createrawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error( + "createrawtransaction [{\"txid\":txid,\"vout\":n},...] {address:amount,...}\n" + "Create a transaction spending given inputs\n" + "(array of objects containing transaction id and output number),\n" + "sending to given address(es).\n" + "Returns hex-encoded raw transaction.\n" + "Note that the transaction's inputs are not signed, and\n" + "it is not stored in the wallet or transmitted to the network."); + + RPCTypeCheck(params, list_of(array_type)(obj_type)); + + Array inputs = params[0].get_array(); + Object sendTo = params[1].get_obj(); + + CTransaction rawTx; + + BOOST_FOREACH(Value& input, inputs) + { + const Object& o = input.get_obj(); + + const Value& txid_v = find_value(o, "txid"); + if (txid_v.type() != str_type) + throw JSONRPCError(-8, "Invalid parameter, missing txid key"); + string txid = txid_v.get_str(); + if (!IsHex(txid)) + throw JSONRPCError(-8, "Invalid parameter, expected hex txid"); + + const Value& vout_v = find_value(o, "vout"); + if (vout_v.type() != int_type) + throw JSONRPCError(-8, "Invalid parameter, missing vout key"); + int nOutput = vout_v.get_int(); + if (nOutput < 0) + throw JSONRPCError(-8, "Invalid parameter, vout must be positive"); + + CTxIn in(COutPoint(uint256(txid), nOutput)); + rawTx.vin.push_back(in); + } + + set setAddress; + BOOST_FOREACH(const Pair& s, sendTo) + { + CBitcoinAddress address(s.name_); + if (!address.IsValid()) + throw JSONRPCError(-5, string("Invalid Bitcoin address:")+s.name_); + + if (setAddress.count(address)) + throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_); + setAddress.insert(address); + + CScript scriptPubKey; + scriptPubKey.SetDestination(address.Get()); + int64 nAmount = AmountFromValue(s.value_); + + CTxOut out(nAmount, scriptPubKey); + rawTx.vout.push_back(out); + } + + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << rawTx; + return HexStr(ss.begin(), ss.end()); +} + +Value decoderawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "decoderawtransaction \n" + "Return a JSON object representing the serialized, hex-encoded transaction."); + + RPCTypeCheck(params, list_of(str_type)); + + vector txData(ParseHex(params[0].get_str())); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + try { + ssData >> tx; + } + catch (std::exception &e) { + throw JSONRPCError(-22, "TX decode failed"); + } + + Object result; + TxToJSON(tx, 0, result); + + return result; +} + +Value signrawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 4) + throw runtime_error( + "signrawtransaction [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [,...] [sighashtype=\"ALL\"]\n" + "Sign inputs for raw transaction (serialized, hex-encoded).\n" + "Second optional argument is an array of previous transaction outputs that\n" + "this transaction depends on but may not yet be in the blockchain.\n" + "Third optional argument is an array of base58-encoded private\n" + "keys that, if given, will be the only keys used to sign the transaction.\n" + "Fourth option is a string that is one of six values; ALL, NONE, SINGLE or\n" + "ALL|ANYONECANPAY, NONE|ANYONECANPAY, SINGLE|ANYONECANPAY.\n" + "Returns json object with keys:\n" + " hex : raw transaction with signature(s) (hex-encoded string)\n" + " complete : 1 if transaction has a complete set of signature (0 if not)" + + HelpRequiringPassphrase()); + + if (params.size() < 3) + EnsureWalletIsUnlocked(); + + RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)); + + vector txData(ParseHex(params[0].get_str())); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + vector txVariants; + while (!ssData.empty()) + { + try { + CTransaction tx; + ssData >> tx; + txVariants.push_back(tx); + } + catch (std::exception &e) { + throw JSONRPCError(-22, "TX decode failed"); + } + } + + if (txVariants.empty()) + throw JSONRPCError(-22, "Missing transaction"); + + // mergedTx will end up with all the signatures; it + // starts as a clone of the rawtx: + CTransaction mergedTx(txVariants[0]); + bool fComplete = true; + + // Fetch previous transactions (inputs): + map mapPrevOut; + { + MapPrevTx mapPrevTx; + CTxDB txdb("r"); + map unused; + bool fInvalid; + mergedTx.FetchInputs(txdb, unused, false, false, mapPrevTx, fInvalid); + + // Copy results into mapPrevOut: + BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) + { + const uint256& prevHash = txin.prevout.hash; + if (mapPrevTx.count(prevHash)) + mapPrevOut[txin.prevout] = mapPrevTx[prevHash].second.vout[txin.prevout.n].scriptPubKey; + } + } + + // Add previous txouts given in the RPC call: + if (params.size() > 1) + { + Array prevTxs = params[1].get_array(); + BOOST_FOREACH(Value& p, prevTxs) + { + if (p.type() != obj_type) + throw JSONRPCError(-22, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); + + Object prevOut = p.get_obj(); + + RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); + + string txidHex = find_value(prevOut, "txid").get_str(); + if (!IsHex(txidHex)) + throw JSONRPCError(-22, "txid must be hexadecimal"); + uint256 txid; + txid.SetHex(txidHex); + + int nOut = find_value(prevOut, "vout").get_int(); + if (nOut < 0) + throw JSONRPCError(-22, "vout must be positive"); + + string pkHex = find_value(prevOut, "scriptPubKey").get_str(); + if (!IsHex(pkHex)) + throw JSONRPCError(-22, "scriptPubKey must be hexadecimal"); + vector pkData(ParseHex(pkHex)); + CScript scriptPubKey(pkData.begin(), pkData.end()); + + COutPoint outpoint(txid, nOut); + if (mapPrevOut.count(outpoint)) + { + // Complain if scriptPubKey doesn't match + if (mapPrevOut[outpoint] != scriptPubKey) + { + string err("Previous output scriptPubKey mismatch:\n"); + err = err + mapPrevOut[outpoint].ToString() + "\nvs:\n"+ + scriptPubKey.ToString(); + throw JSONRPCError(-22, err); + } + } + else + mapPrevOut[outpoint] = scriptPubKey; + } + } + + bool fGivenKeys = false; + CBasicKeyStore tempKeystore; + if (params.size() > 2) + { + fGivenKeys = true; + Array keys = params[2].get_array(); + BOOST_FOREACH(Value k, keys) + { + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(k.get_str()); + if (!fGood) + throw JSONRPCError(-5,"Invalid private key"); + CKey key; + bool fCompressed; + CSecret secret = vchSecret.GetSecret(fCompressed); + key.SetSecret(secret, fCompressed); + tempKeystore.AddKey(key); + } + } + const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain); + + int nHashType = SIGHASH_ALL; + if (params.size() > 3) + { + static map mapSigHashValues = + boost::assign::map_list_of + (string("ALL"), int(SIGHASH_ALL)) + (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)) + (string("NONE"), int(SIGHASH_NONE)) + (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)) + (string("SINGLE"), int(SIGHASH_SINGLE)) + (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)) + ; + string strHashType = params[3].get_str(); + if (mapSigHashValues.count(strHashType)) + nHashType = mapSigHashValues[strHashType]; + else + throw JSONRPCError(-8, "Invalid sighash param"); + } + + // Sign what we can: + for (unsigned int i = 0; i < mergedTx.vin.size(); i++) + { + CTxIn& txin = mergedTx.vin[i]; + if (mapPrevOut.count(txin.prevout) == 0) + { + fComplete = false; + continue; + } + const CScript& prevPubKey = mapPrevOut[txin.prevout]; + + txin.scriptSig.clear(); + SignSignature(keystore, prevPubKey, mergedTx, i, nHashType); + + // ... and merge in other signatures: + BOOST_FOREACH(const CTransaction& txv, txVariants) + { + txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); + } + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, true, 0)) + fComplete = false; + } + + Object result; + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << mergedTx; + result.push_back(Pair("hex", HexStr(ssTx.begin(), ssTx.end()))); + result.push_back(Pair("complete", fComplete)); + + return result; +} + +Value sendrawtransaction(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1) + throw runtime_error( + "sendrawtransaction \n" + "Submits raw transaction (serialized, hex-encoded) to local node and network."); + + RPCTypeCheck(params, list_of(str_type)); + + // parse hex string from parameter + vector txData(ParseHex(params[0].get_str())); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + + // deserialize binary data stream + try { + ssData >> tx; + } + catch (std::exception &e) { + throw JSONRPCError(-22, "TX decode failed"); + } + uint256 hashTx = tx.GetHash(); + + // See if the transaction is already in a block + // or in the memory pool: + CTransaction existingTx; + uint256 hashBlock = 0; + if (GetTransaction(hashTx, existingTx, hashBlock)) + { + if (hashBlock != 0) + throw JSONRPCError(-5, string("transaction already in block ")+hashBlock.GetHex()); + // Not in block, but already in the memory pool; will drop + // through to re-relay it. + } + else + { + // push to local node + CTxDB txdb("r"); + if (!tx.AcceptToMemoryPool(txdb)) + throw JSONRPCError(-22, "TX rejected"); + + SyncWithWallets(tx, NULL, true); + } + RelayMessage(CInv(MSG_TX, hashTx), tx); + + return hashTx.GetHex(); +} diff --git a/src/script.cpp b/src/script.cpp new file mode 100644 index 0000000..b32180c --- /dev/null +++ b/src/script.cpp @@ -0,0 +1,1868 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include +#include + +using namespace std; +using namespace boost; + +#include "script.h" +#include "keystore.h" +#include "bignum.h" +#include "key.h" +#include "main.h" +#include "sync.h" +#include "util.h" + +bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); + + + +typedef vector valtype; +static const valtype vchFalse(0); +static const valtype vchZero(0); +static const valtype vchTrue(1, 1); +static const CBigNum bnZero(0); +static const CBigNum bnOne(1); +static const CBigNum bnFalse(0); +static const CBigNum bnTrue(1); +static const size_t nMaxNumSize = 4; + + +CBigNum CastToBigNum(const valtype& vch) +{ + if (vch.size() > nMaxNumSize) + throw runtime_error("CastToBigNum() : overflow"); + // Get rid of extra leading zeros + return CBigNum(CBigNum(vch).getvch()); +} + +bool CastToBool(const valtype& vch) +{ + for (unsigned int i = 0; i < vch.size(); i++) + { + if (vch[i] != 0) + { + // Can be negative zero + if (i == vch.size()-1 && vch[i] == 0x80) + return false; + return true; + } + } + return false; +} + +void MakeSameSize(valtype& vch1, valtype& vch2) +{ + // Lengthen the shorter one + if (vch1.size() < vch2.size()) + vch1.resize(vch2.size(), 0); + if (vch2.size() < vch1.size()) + vch2.resize(vch1.size(), 0); +} + + + +// +// Script is a stack machine (like Forth) that evaluates a predicate +// returning a bool indicating valid or not. There are no loops. +// +#define stacktop(i) (stack.at(stack.size()+(i))) +#define altstacktop(i) (altstack.at(altstack.size()+(i))) +static inline void popstack(vector& stack) +{ + if (stack.empty()) + throw runtime_error("popstack() : stack empty"); + stack.pop_back(); +} + + +const char* GetTxnOutputType(txnouttype t) +{ + switch (t) + { + case TX_NONSTANDARD: return "nonstandard"; + case TX_PUBKEY: return "pubkey"; + case TX_PUBKEYHASH: return "pubkeyhash"; + case TX_SCRIPTHASH: return "scripthash"; + case TX_MULTISIG: return "multisig"; + } + return NULL; +} + + +const char* GetOpName(opcodetype opcode) +{ + switch (opcode) + { + // push value + case OP_0 : return "0"; + case OP_PUSHDATA1 : return "OP_PUSHDATA1"; + case OP_PUSHDATA2 : return "OP_PUSHDATA2"; + case OP_PUSHDATA4 : return "OP_PUSHDATA4"; + case OP_1NEGATE : return "-1"; + case OP_RESERVED : return "OP_RESERVED"; + case OP_1 : return "1"; + case OP_2 : return "2"; + case OP_3 : return "3"; + case OP_4 : return "4"; + case OP_5 : return "5"; + case OP_6 : return "6"; + case OP_7 : return "7"; + case OP_8 : return "8"; + case OP_9 : return "9"; + case OP_10 : return "10"; + case OP_11 : return "11"; + case OP_12 : return "12"; + case OP_13 : return "13"; + case OP_14 : return "14"; + case OP_15 : return "15"; + case OP_16 : return "16"; + + // control + case OP_NOP : return "OP_NOP"; + case OP_VER : return "OP_VER"; + case OP_IF : return "OP_IF"; + case OP_NOTIF : return "OP_NOTIF"; + case OP_VERIF : return "OP_VERIF"; + case OP_VERNOTIF : return "OP_VERNOTIF"; + case OP_ELSE : return "OP_ELSE"; + case OP_ENDIF : return "OP_ENDIF"; + case OP_VERIFY : return "OP_VERIFY"; + case OP_RETURN : return "OP_RETURN"; + + // stack ops + case OP_TOALTSTACK : return "OP_TOALTSTACK"; + case OP_FROMALTSTACK : return "OP_FROMALTSTACK"; + case OP_2DROP : return "OP_2DROP"; + case OP_2DUP : return "OP_2DUP"; + case OP_3DUP : return "OP_3DUP"; + case OP_2OVER : return "OP_2OVER"; + case OP_2ROT : return "OP_2ROT"; + case OP_2SWAP : return "OP_2SWAP"; + case OP_IFDUP : return "OP_IFDUP"; + case OP_DEPTH : return "OP_DEPTH"; + case OP_DROP : return "OP_DROP"; + case OP_DUP : return "OP_DUP"; + case OP_NIP : return "OP_NIP"; + case OP_OVER : return "OP_OVER"; + case OP_PICK : return "OP_PICK"; + case OP_ROLL : return "OP_ROLL"; + case OP_ROT : return "OP_ROT"; + case OP_SWAP : return "OP_SWAP"; + case OP_TUCK : return "OP_TUCK"; + + // splice ops + case OP_CAT : return "OP_CAT"; + case OP_SUBSTR : return "OP_SUBSTR"; + case OP_LEFT : return "OP_LEFT"; + case OP_RIGHT : return "OP_RIGHT"; + case OP_SIZE : return "OP_SIZE"; + + // bit logic + case OP_INVERT : return "OP_INVERT"; + case OP_AND : return "OP_AND"; + case OP_OR : return "OP_OR"; + case OP_XOR : return "OP_XOR"; + case OP_EQUAL : return "OP_EQUAL"; + case OP_EQUALVERIFY : return "OP_EQUALVERIFY"; + case OP_RESERVED1 : return "OP_RESERVED1"; + case OP_RESERVED2 : return "OP_RESERVED2"; + + // numeric + case OP_1ADD : return "OP_1ADD"; + case OP_1SUB : return "OP_1SUB"; + case OP_2MUL : return "OP_2MUL"; + case OP_2DIV : return "OP_2DIV"; + case OP_NEGATE : return "OP_NEGATE"; + case OP_ABS : return "OP_ABS"; + case OP_NOT : return "OP_NOT"; + case OP_0NOTEQUAL : return "OP_0NOTEQUAL"; + case OP_ADD : return "OP_ADD"; + case OP_SUB : return "OP_SUB"; + case OP_MUL : return "OP_MUL"; + case OP_DIV : return "OP_DIV"; + case OP_MOD : return "OP_MOD"; + case OP_LSHIFT : return "OP_LSHIFT"; + case OP_RSHIFT : return "OP_RSHIFT"; + case OP_BOOLAND : return "OP_BOOLAND"; + case OP_BOOLOR : return "OP_BOOLOR"; + case OP_NUMEQUAL : return "OP_NUMEQUAL"; + case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY"; + case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL"; + case OP_LESSTHAN : return "OP_LESSTHAN"; + case OP_GREATERTHAN : return "OP_GREATERTHAN"; + case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL"; + case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL"; + case OP_MIN : return "OP_MIN"; + case OP_MAX : return "OP_MAX"; + case OP_WITHIN : return "OP_WITHIN"; + + // crypto + case OP_RIPEMD160 : return "OP_RIPEMD160"; + case OP_SHA1 : return "OP_SHA1"; + case OP_SHA256 : return "OP_SHA256"; + case OP_HASH160 : return "OP_HASH160"; + case OP_HASH256 : return "OP_HASH256"; + case OP_CODESEPARATOR : return "OP_CODESEPARATOR"; + case OP_CHECKSIG : return "OP_CHECKSIG"; + case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY"; + case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG"; + case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY"; + + // expanson + case OP_NOP1 : return "OP_NOP1"; + case OP_NOP2 : return "OP_NOP2"; + case OP_NOP3 : return "OP_NOP3"; + case OP_NOP4 : return "OP_NOP4"; + case OP_NOP5 : return "OP_NOP5"; + case OP_NOP6 : return "OP_NOP6"; + case OP_NOP7 : return "OP_NOP7"; + case OP_NOP8 : return "OP_NOP8"; + case OP_NOP9 : return "OP_NOP9"; + case OP_NOP10 : return "OP_NOP10"; + + + + // template matching params + case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; + case OP_PUBKEY : return "OP_PUBKEY"; + + case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; + default: + return "OP_UNKNOWN"; + } +} + +bool EvalScript(vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + CAutoBN_CTX pctx; + CScript::const_iterator pc = script.begin(); + CScript::const_iterator pend = script.end(); + CScript::const_iterator pbegincodehash = script.begin(); + opcodetype opcode; + valtype vchPushValue; + vector vfExec; + vector altstack; + if (script.size() > 10000) + return false; + int nOpCount = 0; + + + try + { + while (pc < pend) + { + bool fExec = !count(vfExec.begin(), vfExec.end(), false); + + // + // Read instruction + // + if (!script.GetOp(pc, opcode, vchPushValue)) + return false; + if (vchPushValue.size() > 520) + return false; + if (opcode > OP_16 && ++nOpCount > 201) + return false; + + if (opcode == OP_CAT || + opcode == OP_SUBSTR || + opcode == OP_LEFT || + opcode == OP_RIGHT || + opcode == OP_INVERT || + opcode == OP_AND || + opcode == OP_OR || + opcode == OP_XOR || + opcode == OP_2MUL || + opcode == OP_2DIV || + opcode == OP_MUL || + opcode == OP_DIV || + opcode == OP_MOD || + opcode == OP_LSHIFT || + opcode == OP_RSHIFT) + return false; + + if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) + stack.push_back(vchPushValue); + else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) + switch (opcode) + { + // + // Push value + // + case OP_1NEGATE: + case OP_1: + case OP_2: + case OP_3: + case OP_4: + case OP_5: + case OP_6: + case OP_7: + case OP_8: + case OP_9: + case OP_10: + case OP_11: + case OP_12: + case OP_13: + case OP_14: + case OP_15: + case OP_16: + { + // ( -- value) + CBigNum bn((int)opcode - (int)(OP_1 - 1)); + stack.push_back(bn.getvch()); + } + break; + + + // + // Control + // + case OP_NOP: + case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: + case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: + break; + + case OP_IF: + case OP_NOTIF: + { + // if [statements] [else [statements]] endif + bool fValue = false; + if (fExec) + { + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + fValue = CastToBool(vch); + if (opcode == OP_NOTIF) + fValue = !fValue; + popstack(stack); + } + vfExec.push_back(fValue); + } + break; + + case OP_ELSE: + { + if (vfExec.empty()) + return false; + vfExec.back() = !vfExec.back(); + } + break; + + case OP_ENDIF: + { + if (vfExec.empty()) + return false; + vfExec.pop_back(); + } + break; + + case OP_VERIFY: + { + // (true -- ) or + // (false -- false) and return + if (stack.size() < 1) + return false; + bool fValue = CastToBool(stacktop(-1)); + if (fValue) + popstack(stack); + else + return false; + } + break; + + case OP_RETURN: + { + return false; + } + break; + + + // + // Stack ops + // + case OP_TOALTSTACK: + { + if (stack.size() < 1) + return false; + altstack.push_back(stacktop(-1)); + popstack(stack); + } + break; + + case OP_FROMALTSTACK: + { + if (altstack.size() < 1) + return false; + stack.push_back(altstacktop(-1)); + popstack(altstack); + } + break; + + case OP_2DROP: + { + // (x1 x2 -- ) + if (stack.size() < 2) + return false; + popstack(stack); + popstack(stack); + } + break; + + case OP_2DUP: + { + // (x1 x2 -- x1 x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch1 = stacktop(-2); + valtype vch2 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_3DUP: + { + // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) + if (stack.size() < 3) + return false; + valtype vch1 = stacktop(-3); + valtype vch2 = stacktop(-2); + valtype vch3 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + stack.push_back(vch3); + } + break; + + case OP_2OVER: + { + // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) + if (stack.size() < 4) + return false; + valtype vch1 = stacktop(-4); + valtype vch2 = stacktop(-3); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2ROT: + { + // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) + if (stack.size() < 6) + return false; + valtype vch1 = stacktop(-6); + valtype vch2 = stacktop(-5); + stack.erase(stack.end()-6, stack.end()-4); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2SWAP: + { + // (x1 x2 x3 x4 -- x3 x4 x1 x2) + if (stack.size() < 4) + return false; + swap(stacktop(-4), stacktop(-2)); + swap(stacktop(-3), stacktop(-1)); + } + break; + + case OP_IFDUP: + { + // (x - 0 | x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + if (CastToBool(vch)) + stack.push_back(vch); + } + break; + + case OP_DEPTH: + { + // -- stacksize + CBigNum bn(stack.size()); + stack.push_back(bn.getvch()); + } + break; + + case OP_DROP: + { + // (x -- ) + if (stack.size() < 1) + return false; + popstack(stack); + } + break; + + case OP_DUP: + { + // (x -- x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + stack.push_back(vch); + } + break; + + case OP_NIP: + { + // (x1 x2 -- x2) + if (stack.size() < 2) + return false; + stack.erase(stack.end() - 2); + } + break; + + case OP_OVER: + { + // (x1 x2 -- x1 x2 x1) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-2); + stack.push_back(vch); + } + break; + + case OP_PICK: + case OP_ROLL: + { + // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) + // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) + if (stack.size() < 2) + return false; + int n = CastToBigNum(stacktop(-1)).getint(); + popstack(stack); + if (n < 0 || n >= (int)stack.size()) + return false; + valtype vch = stacktop(-n-1); + if (opcode == OP_ROLL) + stack.erase(stack.end()-n-1); + stack.push_back(vch); + } + break; + + case OP_ROT: + { + // (x1 x2 x3 -- x2 x3 x1) + // x2 x1 x3 after first swap + // x2 x3 x1 after second swap + if (stack.size() < 3) + return false; + swap(stacktop(-3), stacktop(-2)); + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_SWAP: + { + // (x1 x2 -- x2 x1) + if (stack.size() < 2) + return false; + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_TUCK: + { + // (x1 x2 -- x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-1); + stack.insert(stack.end()-2, vch); + } + break; + + + // + // Splice ops + // + case OP_CAT: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + vch1.insert(vch1.end(), vch2.begin(), vch2.end()); + popstack(stack); + if (stacktop(-1).size() > 520) + return false; + } + break; + + case OP_SUBSTR: + { + // (in begin size -- out) + if (stack.size() < 3) + return false; + valtype& vch = stacktop(-3); + int nBegin = CastToBigNum(stacktop(-2)).getint(); + int nEnd = nBegin + CastToBigNum(stacktop(-1)).getint(); + if (nBegin < 0 || nEnd < nBegin) + return false; + if (nBegin > (int)vch.size()) + nBegin = vch.size(); + if (nEnd > (int)vch.size()) + nEnd = vch.size(); + vch.erase(vch.begin() + nEnd, vch.end()); + vch.erase(vch.begin(), vch.begin() + nBegin); + popstack(stack); + popstack(stack); + } + break; + + case OP_LEFT: + case OP_RIGHT: + { + // (in size -- out) + if (stack.size() < 2) + return false; + valtype& vch = stacktop(-2); + int nSize = CastToBigNum(stacktop(-1)).getint(); + if (nSize < 0) + return false; + if (nSize > (int)vch.size()) + nSize = vch.size(); + if (opcode == OP_LEFT) + vch.erase(vch.begin() + nSize, vch.end()); + else + vch.erase(vch.begin(), vch.end() - nSize); + popstack(stack); + } + break; + + case OP_SIZE: + { + // (in -- in size) + if (stack.size() < 1) + return false; + CBigNum bn(stacktop(-1).size()); + stack.push_back(bn.getvch()); + } + break; + + + // + // Bitwise logic + // + case OP_INVERT: + { + // (in - out) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + for (unsigned int i = 0; i < vch.size(); i++) + vch[i] = ~vch[i]; + } + break; + + case OP_AND: + case OP_OR: + case OP_XOR: + { + // (x1 x2 - out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + MakeSameSize(vch1, vch2); + if (opcode == OP_AND) + { + for (unsigned int i = 0; i < vch1.size(); i++) + vch1[i] &= vch2[i]; + } + else if (opcode == OP_OR) + { + for (unsigned int i = 0; i < vch1.size(); i++) + vch1[i] |= vch2[i]; + } + else if (opcode == OP_XOR) + { + for (unsigned int i = 0; i < vch1.size(); i++) + vch1[i] ^= vch2[i]; + } + popstack(stack); + } + break; + + case OP_EQUAL: + case OP_EQUALVERIFY: + //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL + { + // (x1 x2 - bool) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + bool fEqual = (vch1 == vch2); + // OP_NOTEQUAL is disabled because it would be too easy to say + // something like n != 1 and have some wiseguy pass in 1 with extra + // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) + //if (opcode == OP_NOTEQUAL) + // fEqual = !fEqual; + popstack(stack); + popstack(stack); + stack.push_back(fEqual ? vchTrue : vchFalse); + if (opcode == OP_EQUALVERIFY) + { + if (fEqual) + popstack(stack); + else + return false; + } + } + break; + + + // + // Numeric + // + case OP_1ADD: + case OP_1SUB: + case OP_2MUL: + case OP_2DIV: + case OP_NEGATE: + case OP_ABS: + case OP_NOT: + case OP_0NOTEQUAL: + { + // (in -- out) + if (stack.size() < 1) + return false; + CBigNum bn = CastToBigNum(stacktop(-1)); + switch (opcode) + { + case OP_1ADD: bn += bnOne; break; + case OP_1SUB: bn -= bnOne; break; + case OP_2MUL: bn <<= 1; break; + case OP_2DIV: bn >>= 1; break; + case OP_NEGATE: bn = -bn; break; + case OP_ABS: if (bn < bnZero) bn = -bn; break; + case OP_NOT: bn = (bn == bnZero); break; + case OP_0NOTEQUAL: bn = (bn != bnZero); break; + default: assert(!"invalid opcode"); break; + } + popstack(stack); + stack.push_back(bn.getvch()); + } + break; + + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_MOD: + case OP_LSHIFT: + case OP_RSHIFT: + case OP_BOOLAND: + case OP_BOOLOR: + case OP_NUMEQUAL: + case OP_NUMEQUALVERIFY: + case OP_NUMNOTEQUAL: + case OP_LESSTHAN: + case OP_GREATERTHAN: + case OP_LESSTHANOREQUAL: + case OP_GREATERTHANOREQUAL: + case OP_MIN: + case OP_MAX: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + CBigNum bn1 = CastToBigNum(stacktop(-2)); + CBigNum bn2 = CastToBigNum(stacktop(-1)); + CBigNum bn; + switch (opcode) + { + case OP_ADD: + bn = bn1 + bn2; + break; + + case OP_SUB: + bn = bn1 - bn2; + break; + + case OP_MUL: + if (!BN_mul(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_DIV: + if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) + return false; + break; + + case OP_MOD: + if (!BN_mod(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_LSHIFT: + if (bn2 < bnZero || bn2 > CBigNum(2048)) + return false; + bn = bn1 << bn2.getulong(); + break; + + case OP_RSHIFT: + if (bn2 < bnZero || bn2 > CBigNum(2048)) + return false; + bn = bn1 >> bn2.getulong(); + break; + + case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; + case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; + case OP_NUMEQUAL: bn = (bn1 == bn2); break; + case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; + case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; + case OP_LESSTHAN: bn = (bn1 < bn2); break; + case OP_GREATERTHAN: bn = (bn1 > bn2); break; + case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; + case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; + case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; + case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; + default: assert(!"invalid opcode"); break; + } + popstack(stack); + popstack(stack); + stack.push_back(bn.getvch()); + + if (opcode == OP_NUMEQUALVERIFY) + { + if (CastToBool(stacktop(-1))) + popstack(stack); + else + return false; + } + } + break; + + case OP_WITHIN: + { + // (x min max -- out) + if (stack.size() < 3) + return false; + CBigNum bn1 = CastToBigNum(stacktop(-3)); + CBigNum bn2 = CastToBigNum(stacktop(-2)); + CBigNum bn3 = CastToBigNum(stacktop(-1)); + bool fValue = (bn2 <= bn1 && bn1 < bn3); + popstack(stack); + popstack(stack); + popstack(stack); + stack.push_back(fValue ? vchTrue : vchFalse); + } + break; + + + // + // Crypto + // + case OP_RIPEMD160: + case OP_SHA1: + case OP_SHA256: + case OP_HASH160: + case OP_HASH256: + { + // (in -- hash) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); + if (opcode == OP_RIPEMD160) + RIPEMD160(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA1) + SHA1(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA256) + SHA256(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_HASH160) + { + uint160 hash160 = Hash160(vch); + memcpy(&vchHash[0], &hash160, sizeof(hash160)); + } + else if (opcode == OP_HASH256) + { + uint256 hash = Hash(vch.begin(), vch.end()); + memcpy(&vchHash[0], &hash, sizeof(hash)); + } + popstack(stack); + stack.push_back(vchHash); + } + break; + + case OP_CODESEPARATOR: + { + // Hash starts after the code separator + pbegincodehash = pc; + } + break; + + case OP_CHECKSIG: + case OP_CHECKSIGVERIFY: + { + // (sig pubkey -- bool) + if (stack.size() < 2) + return false; + + valtype& vchSig = stacktop(-2); + valtype& vchPubKey = stacktop(-1); + + ////// debug print + //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); + //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signature, since there's no way for a signature to sign itself + scriptCode.FindAndDelete(CScript(vchSig)); + + bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); + + popstack(stack); + popstack(stack); + stack.push_back(fSuccess ? vchTrue : vchFalse); + if (opcode == OP_CHECKSIGVERIFY) + { + if (fSuccess) + popstack(stack); + else + return false; + } + } + break; + + case OP_CHECKMULTISIG: + case OP_CHECKMULTISIGVERIFY: + { + // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) + + int i = 1; + if ((int)stack.size() < i) + return false; + + int nKeysCount = CastToBigNum(stacktop(-i)).getint(); + if (nKeysCount < 0 || nKeysCount > 20) + return false; + nOpCount += nKeysCount; + if (nOpCount > 201) + return false; + int ikey = ++i; + i += nKeysCount; + if ((int)stack.size() < i) + return false; + + int nSigsCount = CastToBigNum(stacktop(-i)).getint(); + if (nSigsCount < 0 || nSigsCount > nKeysCount) + return false; + int isig = ++i; + i += nSigsCount; + if ((int)stack.size() < i) + return false; + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signatures, since there's no way for a signature to sign itself + for (int k = 0; k < nSigsCount; k++) + { + valtype& vchSig = stacktop(-isig-k); + scriptCode.FindAndDelete(CScript(vchSig)); + } + + bool fSuccess = true; + while (fSuccess && nSigsCount > 0) + { + valtype& vchSig = stacktop(-isig); + valtype& vchPubKey = stacktop(-ikey); + + // Check signature + if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)) + { + isig++; + nSigsCount--; + } + ikey++; + nKeysCount--; + + // If there are more signatures left than keys left, + // then too many signatures have failed + if (nSigsCount > nKeysCount) + fSuccess = false; + } + + while (i-- > 0) + popstack(stack); + stack.push_back(fSuccess ? vchTrue : vchFalse); + + if (opcode == OP_CHECKMULTISIGVERIFY) + { + if (fSuccess) + popstack(stack); + else + return false; + } + } + break; + + default: + return false; + } + + // Size limits + if (stack.size() + altstack.size() > 1000) + return false; + } + } + catch (...) + { + return false; + } + + + if (!vfExec.empty()) + return false; + + return true; +} + + + + + + + + + +uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + if (nIn >= txTo.vin.size()) + { + printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); + return 1; + } + CTransaction txTmp(txTo); + + // In case concatenating two scripts ends up with two codeseparators, + // or an extra one at the end, this prevents all those possible incompatibilities. + scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); + + // Blank out other inputs' signatures + for (unsigned int i = 0; i < txTmp.vin.size(); i++) + txTmp.vin[i].scriptSig = CScript(); + txTmp.vin[nIn].scriptSig = scriptCode; + + // Blank out some of the outputs + if ((nHashType & 0x1f) == SIGHASH_NONE) + { + // Wildcard payee + txTmp.vout.clear(); + + // Let the others update at will + for (unsigned int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + else if ((nHashType & 0x1f) == SIGHASH_SINGLE) + { + // Only lockin the txout payee at same index as txin + unsigned int nOut = nIn; + if (nOut >= txTmp.vout.size()) + { + printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); + return 1; + } + txTmp.vout.resize(nOut+1); + for (unsigned int i = 0; i < nOut; i++) + txTmp.vout[i].SetNull(); + + // Let the others update at will + for (unsigned int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + + // Blank out other inputs completely, not recommended for open transactions + if (nHashType & SIGHASH_ANYONECANPAY) + { + txTmp.vin[0] = txTmp.vin[nIn]; + txTmp.vin.resize(1); + } + + // Serialize and hash + CDataStream ss(SER_GETHASH, 0); + ss.reserve(10000); + ss << txTmp << nHashType; + return Hash(ss.begin(), ss.end()); +} + + +// Valid signature cache, to avoid doing expensive ECDSA signature checking +// twice for every transaction (once when accepted into memory pool, and +// again when accepted into the block chain) + +class CSignatureCache +{ +private: + // sigdata_type is (signature hash, signature, public key): + typedef boost::tuple, std::vector > sigdata_type; + std::set< sigdata_type> setValid; + CCriticalSection cs_sigcache; + +public: + bool + Get(uint256 hash, const std::vector& vchSig, const std::vector& pubKey) + { + LOCK(cs_sigcache); + + sigdata_type k(hash, vchSig, pubKey); + std::set::iterator mi = setValid.find(k); + if (mi != setValid.end()) + return true; + return false; + } + + void + Set(uint256 hash, const std::vector& vchSig, const std::vector& pubKey) + { + // DoS prevention: limit cache size to less than 10MB + // (~200 bytes per cache entry times 50,000 entries) + // Since there are a maximum of 20,000 signature operations per block + // 50,000 is a reasonable default. + int64 nMaxCacheSize = GetArg("-maxsigcachesize", 50000); + if (nMaxCacheSize <= 0) return; + + LOCK(cs_sigcache); + + while (static_cast(setValid.size()) > nMaxCacheSize) + { + // Evict a random entry. Random because that helps + // foil would-be DoS attackers who might try to pre-generate + // and re-use a set of valid signatures just-slightly-greater + // than our cache size. + uint256 randomHash = GetRandHash(); + std::vector unused; + std::set::iterator it = + setValid.lower_bound(sigdata_type(randomHash, unused, unused)); + if (it == setValid.end()) + it = setValid.begin(); + setValid.erase(*it); + } + + sigdata_type k(hash, vchSig, pubKey); + setValid.insert(k); + } +}; + +bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, + const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + static CSignatureCache signatureCache; + + // Hash type is one byte tacked on to the end of the signature + if (vchSig.empty()) + return false; + if (nHashType == 0) + nHashType = vchSig.back(); + else if (nHashType != vchSig.back()) + return false; + vchSig.pop_back(); + + uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType); + + if (signatureCache.Get(sighash, vchSig, vchPubKey)) + return true; + + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + + if (!key.Verify(sighash, vchSig)) + return false; + + signatureCache.Set(sighash, vchSig, vchPubKey); + return true; +} + + + + + + + + + +// +// Return public keys or hashes from scriptPubKey, for 'standard' transaction types. +// +bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector >& vSolutionsRet) +{ + // Templates + static map mTemplates; + if (mTemplates.empty()) + { + // Standard tx, sender provides pubkey, receiver adds signature + mTemplates.insert(make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG)); + + // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey + mTemplates.insert(make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG)); + + // Sender provides N pubkeys, receivers provides M signatures + mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG)); + } + + // Shortcut for pay-to-script-hash, which are more constrained than the other types: + // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL + if (scriptPubKey.IsPayToScriptHash()) + { + typeRet = TX_SCRIPTHASH; + vector hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22); + vSolutionsRet.push_back(hashBytes); + return true; + } + + // Scan templates + const CScript& script1 = scriptPubKey; + BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates) + { + const CScript& script2 = tplate.second; + vSolutionsRet.clear(); + + opcodetype opcode1, opcode2; + vector vch1, vch2; + + // Compare + CScript::const_iterator pc1 = script1.begin(); + CScript::const_iterator pc2 = script2.begin(); + loop + { + if (pc1 == script1.end() && pc2 == script2.end()) + { + // Found a match + typeRet = tplate.first; + if (typeRet == TX_MULTISIG) + { + // Additional checks for TX_MULTISIG: + unsigned char m = vSolutionsRet.front()[0]; + unsigned char n = vSolutionsRet.back()[0]; + if (m < 1 || n < 1 || m > n || vSolutionsRet.size()-2 != n) + return false; + } + return true; + } + if (!script1.GetOp(pc1, opcode1, vch1)) + break; + if (!script2.GetOp(pc2, opcode2, vch2)) + break; + + // Template matching opcodes: + if (opcode2 == OP_PUBKEYS) + { + while (vch1.size() >= 33 && vch1.size() <= 120) + { + vSolutionsRet.push_back(vch1); + if (!script1.GetOp(pc1, opcode1, vch1)) + break; + } + if (!script2.GetOp(pc2, opcode2, vch2)) + break; + // Normal situation is to fall through + // to other if/else statments + } + + if (opcode2 == OP_PUBKEY) + { + if (vch1.size() < 33 || vch1.size() > 120) + break; + vSolutionsRet.push_back(vch1); + } + else if (opcode2 == OP_PUBKEYHASH) + { + if (vch1.size() != sizeof(uint160)) + break; + vSolutionsRet.push_back(vch1); + } + else if (opcode2 == OP_SMALLINTEGER) + { // Single-byte small integer pushed onto vSolutions + if (opcode1 == OP_0 || + (opcode1 >= OP_1 && opcode1 <= OP_16)) + { + char n = (char)CScript::DecodeOP_N(opcode1); + vSolutionsRet.push_back(valtype(1, n)); + } + else + break; + } + else if (opcode1 != opcode2 || vch1 != vch2) + { + // Others must match exactly + break; + } + } + } + + vSolutionsRet.clear(); + typeRet = TX_NONSTANDARD; + return false; +} + + +bool Sign1(const CKeyID& address, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet) +{ + CKey key; + if (!keystore.GetKey(address, key)) + return false; + + vector vchSig; + if (!key.Sign(hash, vchSig)) + return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig; + + return true; +} + +bool SignN(const vector& multisigdata, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet) +{ + int nSigned = 0; + int nRequired = multisigdata.front()[0]; + for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++) + { + const valtype& pubkey = multisigdata[i]; + CKeyID keyID = CPubKey(pubkey).GetID(); + if (Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) + ++nSigned; + } + return nSigned==nRequired; +} + +// +// Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type. +// Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), +// unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. +// Returns false if scriptPubKey could not be completely satisified. +// +bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType, + CScript& scriptSigRet, txnouttype& whichTypeRet) +{ + scriptSigRet.clear(); + + vector vSolutions; + if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) + return false; + + CKeyID keyID; + switch (whichTypeRet) + { + case TX_NONSTANDARD: + return false; + case TX_PUBKEY: + keyID = CPubKey(vSolutions[0]).GetID(); + return Sign1(keyID, keystore, hash, nHashType, scriptSigRet); + case TX_PUBKEYHASH: + keyID = CKeyID(uint160(vSolutions[0])); + if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) + return false; + else + { + CPubKey vch; + keystore.GetPubKey(keyID, vch); + scriptSigRet << vch; + } + return true; + case TX_SCRIPTHASH: + return keystore.GetCScript(uint160(vSolutions[0]), scriptSigRet); + + case TX_MULTISIG: + scriptSigRet << OP_0; // workaround CHECKMULTISIG bug + return (SignN(vSolutions, keystore, hash, nHashType, scriptSigRet)); + } + return false; +} + +int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions) +{ + switch (t) + { + case TX_NONSTANDARD: + return -1; + case TX_PUBKEY: + return 1; + case TX_PUBKEYHASH: + return 2; + case TX_MULTISIG: + if (vSolutions.size() < 1 || vSolutions[0].size() < 1) + return -1; + return vSolutions[0][0] + 1; + case TX_SCRIPTHASH: + return 1; // doesn't include args needed by the script + } + return -1; +} + +bool IsStandard(const CScript& scriptPubKey) +{ + vector vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_MULTISIG) + { + unsigned char m = vSolutions.front()[0]; + unsigned char n = vSolutions.back()[0]; + // Support up to x-of-3 multisig txns as standard + if (n < 1 || n > 3) + return false; + if (m < 1 || m > n) + return false; + } + + return whichType != TX_NONSTANDARD; +} + + +unsigned int HaveKeys(const vector& pubkeys, const CKeyStore& keystore) +{ + unsigned int nResult = 0; + BOOST_FOREACH(const valtype& pubkey, pubkeys) + { + CKeyID keyID = CPubKey(pubkey).GetID(); + if (keystore.HaveKey(keyID)) + ++nResult; + } + return nResult; +} + + +class CKeyStoreIsMineVisitor : public boost::static_visitor +{ +private: + const CKeyStore *keystore; +public: + CKeyStoreIsMineVisitor(const CKeyStore *keystoreIn) : keystore(keystoreIn) { } + bool operator()(const CNoDestination &dest) const { return false; } + bool operator()(const CKeyID &keyID) const { return keystore->HaveKey(keyID); } + bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); } +}; + +bool IsMine(const CKeyStore &keystore, const CTxDestination &dest) +{ + return boost::apply_visitor(CKeyStoreIsMineVisitor(&keystore), dest); +} + +bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) +{ + vector vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + CKeyID keyID; + switch (whichType) + { + case TX_NONSTANDARD: + return false; + case TX_PUBKEY: + keyID = CPubKey(vSolutions[0]).GetID(); + return keystore.HaveKey(keyID); + case TX_PUBKEYHASH: + keyID = CKeyID(uint160(vSolutions[0])); + return keystore.HaveKey(keyID); + case TX_SCRIPTHASH: + { + CScript subscript; + if (!keystore.GetCScript(CScriptID(uint160(vSolutions[0])), subscript)) + return false; + return IsMine(keystore, subscript); + } + case TX_MULTISIG: + { + // Only consider transactions "mine" if we own ALL the + // keys involved. multi-signature transactions that are + // partially owned (somebody else has a key that can spend + // them) enable spend-out-from-under-you attacks, especially + // in shared-wallet situations. + vector keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); + return HaveKeys(keys, keystore) == keys.size(); + } + } + return false; +} + +bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) +{ + vector vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_PUBKEY) + { + addressRet = CPubKey(vSolutions[0]).GetID(); + return true; + } + else if (whichType == TX_PUBKEYHASH) + { + addressRet = CKeyID(uint160(vSolutions[0])); + return true; + } + else if (whichType == TX_SCRIPTHASH) + { + addressRet = CScriptID(uint160(vSolutions[0])); + return true; + } + // Multisig txns have more than one address... + return false; +} + +bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vector& addressRet, int& nRequiredRet) +{ + addressRet.clear(); + typeRet = TX_NONSTANDARD; + vector vSolutions; + if (!Solver(scriptPubKey, typeRet, vSolutions)) + return false; + + if (typeRet == TX_MULTISIG) + { + nRequiredRet = vSolutions.front()[0]; + for (unsigned int i = 1; i < vSolutions.size()-1; i++) + { + CTxDestination address = CPubKey(vSolutions[i]).GetID(); + addressRet.push_back(address); + } + } + else + { + nRequiredRet = 1; + CTxDestination address; + if (!ExtractDestination(scriptPubKey, address)) + return false; + addressRet.push_back(address); + } + + return true; +} + +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType) +{ + vector > stack, stackCopy; + if (!EvalScript(stack, scriptSig, txTo, nIn, nHashType)) + return false; + if (fValidatePayToScriptHash) + stackCopy = stack; + if (!EvalScript(stack, scriptPubKey, txTo, nIn, nHashType)) + return false; + if (stack.empty()) + return false; + + if (CastToBool(stack.back()) == false) + return false; + + // Additional validation for spend-to-script-hash transactions: + if (fValidatePayToScriptHash && scriptPubKey.IsPayToScriptHash()) + { + if (!scriptSig.IsPushOnly()) // scriptSig must be literals-only + return false; // or validation fails + + const valtype& pubKeySerialized = stackCopy.back(); + CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); + popstack(stackCopy); + + if (!EvalScript(stackCopy, pubKey2, txTo, nIn, nHashType)) + return false; + if (stackCopy.empty()) + return false; + return CastToBool(stackCopy.back()); + } + + return true; +} + + +bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType) +{ + assert(nIn < txTo.vin.size()); + CTxIn& txin = txTo.vin[nIn]; + + // Leave out the signature from the hash, since a signature can't sign itself. + // The checksig op will also drop the signatures from its hash. + uint256 hash = SignatureHash(fromPubKey, txTo, nIn, nHashType); + + txnouttype whichType; + if (!Solver(keystore, fromPubKey, hash, nHashType, txin.scriptSig, whichType)) + return false; + + if (whichType == TX_SCRIPTHASH) + { + // Solver returns the subscript that need to be evaluated; + // the final scriptSig is the signatures from that + // and then the serialized subscript: + CScript subscript = txin.scriptSig; + + // Recompute txn hash using subscript in place of scriptPubKey: + uint256 hash2 = SignatureHash(subscript, txTo, nIn, nHashType); + + txnouttype subType; + bool fSolved = + Solver(keystore, subscript, hash2, nHashType, txin.scriptSig, subType) && subType != TX_SCRIPTHASH; + // Append serialized subscript whether or not it is completely signed: + txin.scriptSig << static_cast(subscript); + if (!fSolved) return false; + } + + // Test solution + return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, true, 0); +} + +bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType) +{ + assert(nIn < txTo.vin.size()); + CTxIn& txin = txTo.vin[nIn]; + assert(txin.prevout.n < txFrom.vout.size()); + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, nHashType); +} + +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType) +{ + assert(nIn < txTo.vin.size()); + const CTxIn& txin = txTo.vin[nIn]; + if (txin.prevout.n >= txFrom.vout.size()) + return false; + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + if (txin.prevout.hash != txFrom.GetHash()) + return false; + + return VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, fValidatePayToScriptHash, nHashType); +} + +static CScript PushAll(const vector& values) +{ + CScript result; + BOOST_FOREACH(const valtype& v, values) + result << v; + return result; +} + +static CScript CombineMultisig(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, + const vector& vSolutions, + vector& sigs1, vector& sigs2) +{ + // Combine all the signatures we've got: + set allsigs; + BOOST_FOREACH(const valtype& v, sigs1) + { + if (!v.empty()) + allsigs.insert(v); + } + BOOST_FOREACH(const valtype& v, sigs2) + { + if (!v.empty()) + allsigs.insert(v); + } + + // Build a map of pubkey -> signature by matching sigs to pubkeys: + assert(vSolutions.size() > 1); + unsigned int nSigsRequired = vSolutions.front()[0]; + unsigned int nPubKeys = vSolutions.size()-2; + map sigs; + BOOST_FOREACH(const valtype& sig, allsigs) + { + for (unsigned int i = 0; i < nPubKeys; i++) + { + const valtype& pubkey = vSolutions[i+1]; + if (sigs.count(pubkey)) + continue; // Already got a sig for this pubkey + + if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0)) + { + sigs[pubkey] = sig; + break; + } + } + } + // Now build a merged CScript: + unsigned int nSigsHave = 0; + CScript result; result << OP_0; // pop-one-too-many workaround + for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++) + { + if (sigs.count(vSolutions[i+1])) + { + result << sigs[vSolutions[i+1]]; + ++nSigsHave; + } + } + // Fill any missing with OP_0: + for (unsigned int i = nSigsHave; i < nSigsRequired; i++) + result << OP_0; + + return result; +} + +static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, + const txnouttype txType, const vector& vSolutions, + vector& sigs1, vector& sigs2) +{ + switch (txType) + { + case TX_NONSTANDARD: + // Don't know anything about this, assume bigger one is correct: + if (sigs1.size() >= sigs2.size()) + return PushAll(sigs1); + return PushAll(sigs2); + case TX_PUBKEY: + case TX_PUBKEYHASH: + // Signatures are bigger than placeholders or empty scripts: + if (sigs1.empty() || sigs1[0].empty()) + return PushAll(sigs2); + return PushAll(sigs1); + case TX_SCRIPTHASH: + if (sigs1.empty() || sigs1.back().empty()) + return PushAll(sigs2); + else if (sigs2.empty() || sigs2.back().empty()) + return PushAll(sigs1); + else + { + // Recurse to combine: + valtype spk = sigs1.back(); + CScript pubKey2(spk.begin(), spk.end()); + + txnouttype txType2; + vector > vSolutions2; + Solver(pubKey2, txType2, vSolutions2); + sigs1.pop_back(); + sigs2.pop_back(); + CScript result = CombineSignatures(pubKey2, txTo, nIn, txType2, vSolutions2, sigs1, sigs2); + result << spk; + return result; + } + case TX_MULTISIG: + return CombineMultisig(scriptPubKey, txTo, nIn, vSolutions, sigs1, sigs2); + } + + return CScript(); +} + +CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, + const CScript& scriptSig1, const CScript& scriptSig2) +{ + txnouttype txType; + vector > vSolutions; + Solver(scriptPubKey, txType, vSolutions); + + vector stack1; + EvalScript(stack1, scriptSig1, CTransaction(), 0, 0); + vector stack2; + EvalScript(stack2, scriptSig2, CTransaction(), 0, 0); + + return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2); +} + +unsigned int CScript::GetSigOpCount(bool fAccurate) const +{ + unsigned int n = 0; + const_iterator pc = begin(); + opcodetype lastOpcode = OP_INVALIDOPCODE; + while (pc < end()) + { + opcodetype opcode; + if (!GetOp(pc, opcode)) + break; + if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY) + n++; + else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY) + { + if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16) + n += DecodeOP_N(lastOpcode); + else + n += 20; + } + lastOpcode = opcode; + } + return n; +} + +unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const +{ + if (!IsPayToScriptHash()) + return GetSigOpCount(true); + + // This is a pay-to-script-hash scriptPubKey; + // get the last item that the scriptSig + // pushes onto the stack: + const_iterator pc = scriptSig.begin(); + vector data; + while (pc < scriptSig.end()) + { + opcodetype opcode; + if (!scriptSig.GetOp(pc, opcode, data)) + return 0; + if (opcode > OP_16) + return 0; + } + + /// ... and return it's opcount: + CScript subscript(data.begin(), data.end()); + return subscript.GetSigOpCount(true); +} + +bool CScript::IsPayToScriptHash() const +{ + // Extra-fast test for pay-to-script-hash CScripts: + return (this->size() == 23 && + this->at(0) == OP_HASH160 && + this->at(1) == 0x14 && + this->at(22) == OP_EQUAL); +} + +class CScriptVisitor : public boost::static_visitor +{ +private: + CScript *script; +public: + CScriptVisitor(CScript *scriptin) { script = scriptin; } + + bool operator()(const CNoDestination &dest) const { + script->clear(); + return false; + } + + bool operator()(const CKeyID &keyID) const { + script->clear(); + *script << OP_DUP << OP_HASH160 << keyID << OP_EQUALVERIFY << OP_CHECKSIG; + return true; + } + + bool operator()(const CScriptID &scriptID) const { + script->clear(); + *script << OP_HASH160 << scriptID << OP_EQUAL; + return true; + } +}; + +void CScript::SetDestination(const CTxDestination& dest) +{ + boost::apply_visitor(CScriptVisitor(this), dest); +} + +void CScript::SetMultisig(int nRequired, const std::vector& keys) +{ + this->clear(); + + *this << EncodeOP_N(nRequired); + BOOST_FOREACH(const CKey& key, keys) + *this << key.GetPubKey(); + *this << EncodeOP_N(keys.size()) << OP_CHECKMULTISIG; +} diff --git a/src/script.h b/src/script.h new file mode 100644 index 0000000..9e0d69a --- /dev/null +++ b/src/script.h @@ -0,0 +1,606 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef H_BITCOIN_SCRIPT +#define H_BITCOIN_SCRIPT + +#include +#include + +#include +#include + +#include "keystore.h" +#include "bignum.h" + +class CTransaction; + +/** Signature hash types/flags */ +enum +{ + SIGHASH_ALL = 1, + SIGHASH_NONE = 2, + SIGHASH_SINGLE = 3, + SIGHASH_ANYONECANPAY = 0x80, +}; + + +enum txnouttype +{ + TX_NONSTANDARD, + // 'standard' transaction types: + TX_PUBKEY, + TX_PUBKEYHASH, + TX_SCRIPTHASH, + TX_MULTISIG, +}; + +class CNoDestination { +public: + friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; } + friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } +}; + +/** A txout script template with a specific destination. It is either: + * * CNoDestination: no destination set + * * CKeyID: TX_PUBKEYHASH destination + * * CScriptID: TX_SCRIPTHASH destination + * A CTxDestination is the internal data type encoded in a CBitcoinAddress + */ +typedef boost::variant CTxDestination; + +const char* GetTxnOutputType(txnouttype t); + +/** Script opcodes */ +enum opcodetype +{ + // push value + OP_0 = 0x00, + OP_FALSE = OP_0, + OP_PUSHDATA1 = 0x4c, + OP_PUSHDATA2 = 0x4d, + OP_PUSHDATA4 = 0x4e, + OP_1NEGATE = 0x4f, + OP_RESERVED = 0x50, + OP_1 = 0x51, + OP_TRUE=OP_1, + OP_2 = 0x52, + OP_3 = 0x53, + OP_4 = 0x54, + OP_5 = 0x55, + OP_6 = 0x56, + OP_7 = 0x57, + OP_8 = 0x58, + OP_9 = 0x59, + OP_10 = 0x5a, + OP_11 = 0x5b, + OP_12 = 0x5c, + OP_13 = 0x5d, + OP_14 = 0x5e, + OP_15 = 0x5f, + OP_16 = 0x60, + + // control + OP_NOP = 0x61, + OP_VER = 0x62, + OP_IF = 0x63, + OP_NOTIF = 0x64, + OP_VERIF = 0x65, + OP_VERNOTIF = 0x66, + OP_ELSE = 0x67, + OP_ENDIF = 0x68, + OP_VERIFY = 0x69, + OP_RETURN = 0x6a, + + // stack ops + OP_TOALTSTACK = 0x6b, + OP_FROMALTSTACK = 0x6c, + OP_2DROP = 0x6d, + OP_2DUP = 0x6e, + OP_3DUP = 0x6f, + OP_2OVER = 0x70, + OP_2ROT = 0x71, + OP_2SWAP = 0x72, + OP_IFDUP = 0x73, + OP_DEPTH = 0x74, + OP_DROP = 0x75, + OP_DUP = 0x76, + OP_NIP = 0x77, + OP_OVER = 0x78, + OP_PICK = 0x79, + OP_ROLL = 0x7a, + OP_ROT = 0x7b, + OP_SWAP = 0x7c, + OP_TUCK = 0x7d, + + // splice ops + OP_CAT = 0x7e, + OP_SUBSTR = 0x7f, + OP_LEFT = 0x80, + OP_RIGHT = 0x81, + OP_SIZE = 0x82, + + // bit logic + OP_INVERT = 0x83, + OP_AND = 0x84, + OP_OR = 0x85, + OP_XOR = 0x86, + OP_EQUAL = 0x87, + OP_EQUALVERIFY = 0x88, + OP_RESERVED1 = 0x89, + OP_RESERVED2 = 0x8a, + + // numeric + OP_1ADD = 0x8b, + OP_1SUB = 0x8c, + OP_2MUL = 0x8d, + OP_2DIV = 0x8e, + OP_NEGATE = 0x8f, + OP_ABS = 0x90, + OP_NOT = 0x91, + OP_0NOTEQUAL = 0x92, + + OP_ADD = 0x93, + OP_SUB = 0x94, + OP_MUL = 0x95, + OP_DIV = 0x96, + OP_MOD = 0x97, + OP_LSHIFT = 0x98, + OP_RSHIFT = 0x99, + + OP_BOOLAND = 0x9a, + OP_BOOLOR = 0x9b, + OP_NUMEQUAL = 0x9c, + OP_NUMEQUALVERIFY = 0x9d, + OP_NUMNOTEQUAL = 0x9e, + OP_LESSTHAN = 0x9f, + OP_GREATERTHAN = 0xa0, + OP_LESSTHANOREQUAL = 0xa1, + OP_GREATERTHANOREQUAL = 0xa2, + OP_MIN = 0xa3, + OP_MAX = 0xa4, + + OP_WITHIN = 0xa5, + + // crypto + OP_RIPEMD160 = 0xa6, + OP_SHA1 = 0xa7, + OP_SHA256 = 0xa8, + OP_HASH160 = 0xa9, + OP_HASH256 = 0xaa, + OP_CODESEPARATOR = 0xab, + OP_CHECKSIG = 0xac, + OP_CHECKSIGVERIFY = 0xad, + OP_CHECKMULTISIG = 0xae, + OP_CHECKMULTISIGVERIFY = 0xaf, + + // expansion + OP_NOP1 = 0xb0, + OP_NOP2 = 0xb1, + OP_NOP3 = 0xb2, + OP_NOP4 = 0xb3, + OP_NOP5 = 0xb4, + OP_NOP6 = 0xb5, + OP_NOP7 = 0xb6, + OP_NOP8 = 0xb7, + OP_NOP9 = 0xb8, + OP_NOP10 = 0xb9, + + + + // template matching params + OP_SMALLINTEGER = 0xfa, + OP_PUBKEYS = 0xfb, + OP_PUBKEYHASH = 0xfd, + OP_PUBKEY = 0xfe, + + OP_INVALIDOPCODE = 0xff, +}; + +const char* GetOpName(opcodetype opcode); + + + +inline std::string ValueString(const std::vector& vch) +{ + if (vch.size() <= 4) + return strprintf("%d", CBigNum(vch).getint()); + else + return HexStr(vch); +} + +inline std::string StackString(const std::vector >& vStack) +{ + std::string str; + BOOST_FOREACH(const std::vector& vch, vStack) + { + if (!str.empty()) + str += " "; + str += ValueString(vch); + } + return str; +} + + + + + + + + +/** Serialized script, used inside transaction inputs and outputs */ +class CScript : public std::vector +{ +protected: + CScript& push_int64(int64 n) + { + if (n == -1 || (n >= 1 && n <= 16)) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return *this; + } + + CScript& push_uint64(uint64 n) + { + if (n >= 1 && n <= 16) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return *this; + } + +public: + CScript() { } + CScript(const CScript& b) : std::vector(b.begin(), b.end()) { } + CScript(const_iterator pbegin, const_iterator pend) : std::vector(pbegin, pend) { } +#ifndef _MSC_VER + CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector(pbegin, pend) { } +#endif + + CScript& operator+=(const CScript& b) + { + insert(end(), b.begin(), b.end()); + return *this; + } + + friend CScript operator+(const CScript& a, const CScript& b) + { + CScript ret = a; + ret += b; + return ret; + } + + + //explicit CScript(char b) is not portable. Use 'signed char' or 'unsigned char'. + explicit CScript(signed char b) { operator<<(b); } + explicit CScript(short b) { operator<<(b); } + explicit CScript(int b) { operator<<(b); } + explicit CScript(long b) { operator<<(b); } + explicit CScript(int64 b) { operator<<(b); } + explicit CScript(unsigned char b) { operator<<(b); } + explicit CScript(unsigned int b) { operator<<(b); } + explicit CScript(unsigned short b) { operator<<(b); } + explicit CScript(unsigned long b) { operator<<(b); } + explicit CScript(uint64 b) { operator<<(b); } + + explicit CScript(opcodetype b) { operator<<(b); } + explicit CScript(const uint256& b) { operator<<(b); } + explicit CScript(const CBigNum& b) { operator<<(b); } + explicit CScript(const std::vector& b) { operator<<(b); } + + + //CScript& operator<<(char b) is not portable. Use 'signed char' or 'unsigned char'. + CScript& operator<<(signed char b) { return push_int64(b); } + CScript& operator<<(short b) { return push_int64(b); } + CScript& operator<<(int b) { return push_int64(b); } + CScript& operator<<(long b) { return push_int64(b); } + CScript& operator<<(int64 b) { return push_int64(b); } + CScript& operator<<(unsigned char b) { return push_uint64(b); } + CScript& operator<<(unsigned int b) { return push_uint64(b); } + CScript& operator<<(unsigned short b) { return push_uint64(b); } + CScript& operator<<(unsigned long b) { return push_uint64(b); } + CScript& operator<<(uint64 b) { return push_uint64(b); } + + CScript& operator<<(opcodetype opcode) + { + if (opcode < 0 || opcode > 0xff) + throw std::runtime_error("CScript::operator<<() : invalid opcode"); + insert(end(), (unsigned char)opcode); + return *this; + } + + CScript& operator<<(const uint160& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return *this; + } + + CScript& operator<<(const uint256& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return *this; + } + + CScript& operator<<(const CPubKey& key) + { + std::vector vchKey = key.Raw(); + return (*this) << vchKey; + } + + CScript& operator<<(const CBigNum& b) + { + *this << b.getvch(); + return *this; + } + + CScript& operator<<(const std::vector& b) + { + if (b.size() < OP_PUSHDATA1) + { + insert(end(), (unsigned char)b.size()); + } + else if (b.size() <= 0xff) + { + insert(end(), OP_PUSHDATA1); + insert(end(), (unsigned char)b.size()); + } + else if (b.size() <= 0xffff) + { + insert(end(), OP_PUSHDATA2); + unsigned short nSize = b.size(); + insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + } + else + { + insert(end(), OP_PUSHDATA4); + unsigned int nSize = b.size(); + insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + } + insert(end(), b.begin(), b.end()); + return *this; + } + + CScript& operator<<(const CScript& b) + { + // I'm not sure if this should push the script or concatenate scripts. + // If there's ever a use for pushing a script onto a script, delete this member fn + assert(!"warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate"); + return *this; + } + + + bool GetOp(iterator& pc, opcodetype& opcodeRet, std::vector& vchRet) + { + // Wrapper so it can be called with either iterator or const_iterator + const_iterator pc2 = pc; + bool fRet = GetOp2(pc2, opcodeRet, &vchRet); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(iterator& pc, opcodetype& opcodeRet) + { + const_iterator pc2 = pc; + bool fRet = GetOp2(pc2, opcodeRet, NULL); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet, std::vector& vchRet) const + { + return GetOp2(pc, opcodeRet, &vchRet); + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const + { + return GetOp2(pc, opcodeRet, NULL); + } + + bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, std::vector* pvchRet) const + { + opcodeRet = OP_INVALIDOPCODE; + if (pvchRet) + pvchRet->clear(); + if (pc >= end()) + return false; + + // Read instruction + if (end() - pc < 1) + return false; + unsigned int opcode = *pc++; + + // Immediate operand + if (opcode <= OP_PUSHDATA4) + { + unsigned int nSize; + if (opcode < OP_PUSHDATA1) + { + nSize = opcode; + } + else if (opcode == OP_PUSHDATA1) + { + if (end() - pc < 1) + return false; + nSize = *pc++; + } + else if (opcode == OP_PUSHDATA2) + { + if (end() - pc < 2) + return false; + nSize = 0; + memcpy(&nSize, &pc[0], 2); + pc += 2; + } + else if (opcode == OP_PUSHDATA4) + { + if (end() - pc < 4) + return false; + memcpy(&nSize, &pc[0], 4); + pc += 4; + } + if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize) + return false; + if (pvchRet) + pvchRet->assign(pc, pc + nSize); + pc += nSize; + } + + opcodeRet = (opcodetype)opcode; + return true; + } + + // Encode/decode small integers: + static int DecodeOP_N(opcodetype opcode) + { + if (opcode == OP_0) + return 0; + assert(opcode >= OP_1 && opcode <= OP_16); + return (int)opcode - (int)(OP_1 - 1); + } + static opcodetype EncodeOP_N(int n) + { + assert(n >= 0 && n <= 16); + if (n == 0) + return OP_0; + return (opcodetype)(OP_1+n-1); + } + + int FindAndDelete(const CScript& b) + { + int nFound = 0; + if (b.empty()) + return nFound; + iterator pc = begin(); + opcodetype opcode; + do + { + while (end() - pc >= (long)b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) + { + erase(pc, pc + b.size()); + ++nFound; + } + } + while (GetOp(pc, opcode)); + return nFound; + } + int Find(opcodetype op) const + { + int nFound = 0; + opcodetype opcode; + for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);) + if (opcode == op) + ++nFound; + return nFound; + } + + // Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs + // as 20 sigops. With pay-to-script-hash, that changed: + // CHECKMULTISIGs serialized in scriptSigs are + // counted more accurately, assuming they are of the form + // ... OP_N CHECKMULTISIG ... + unsigned int GetSigOpCount(bool fAccurate) const; + + // Accurately count sigOps, including sigOps in + // pay-to-script-hash transactions: + unsigned int GetSigOpCount(const CScript& scriptSig) const; + + bool IsPayToScriptHash() const; + + // Called by CTransaction::IsStandard + bool IsPushOnly() const + { + const_iterator pc = begin(); + while (pc < end()) + { + opcodetype opcode; + if (!GetOp(pc, opcode)) + return false; + if (opcode > OP_16) + return false; + } + return true; + } + + + void SetDestination(const CTxDestination& address); + void SetMultisig(int nRequired, const std::vector& keys); + + + void PrintHex() const + { + printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str()); + } + + std::string ToString() const + { + std::string str; + opcodetype opcode; + std::vector vch; + const_iterator pc = begin(); + while (pc < end()) + { + if (!str.empty()) + str += " "; + if (!GetOp(pc, opcode, vch)) + { + str += "[error]"; + return str; + } + if (0 <= opcode && opcode <= OP_PUSHDATA4) + str += ValueString(vch); + else + str += GetOpName(opcode); + } + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } + + CScriptID GetID() const + { + return CScriptID(Hash160(*this)); + } +}; + + + + + +bool EvalScript(std::vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType); +bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet); +int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions); +bool IsStandard(const CScript& scriptPubKey); +bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); +bool IsMine(const CKeyStore& keystore, const CTxDestination &dest); +bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); +bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector& addressRet, int& nRequiredRet); +bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); +bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType); +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType); + +// Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders, +// combine them intelligently and return the result. +CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); + +#endif diff --git a/src/scrypt.c b/src/scrypt.c new file mode 100644 index 0000000..e507b44 --- /dev/null +++ b/src/scrypt.c @@ -0,0 +1,300 @@ +/* + * Copyright 2009 Colin Percival, 2011 ArtForz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ + +#include "scrypt.h" +#include +#include +#include +#include + +static inline uint32_t be32dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); +} + +static inline void be32enc(void *pp, uint32_t x) +{ + uint8_t *p = (uint8_t *)pp; + p[3] = x & 0xff; + p[2] = (x >> 8) & 0xff; + p[1] = (x >> 16) & 0xff; + p[0] = (x >> 24) & 0xff; +} + +static inline uint32_t le32dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + + ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); +} + +static inline void le32enc(void *pp, uint32_t x) +{ + uint8_t *p = (uint8_t *)pp; + p[0] = x & 0xff; + p[1] = (x >> 8) & 0xff; + p[2] = (x >> 16) & 0xff; + p[3] = (x >> 24) & 0xff; +} + + +typedef struct HMAC_SHA256Context { + SHA256_CTX ictx; + SHA256_CTX octx; +} HMAC_SHA256_CTX; + +/* Initialize an HMAC-SHA256 operation with the given key. */ +static void +HMAC_SHA256_Init(HMAC_SHA256_CTX *ctx, const void *_K, size_t Klen) +{ + unsigned char pad[64]; + unsigned char khash[32]; + const unsigned char *K = _K; + size_t i; + + /* If Klen > 64, the key is really SHA256(K). */ + if (Klen > 64) { + SHA256_Init(&ctx->ictx); + SHA256_Update(&ctx->ictx, K, Klen); + SHA256_Final(khash, &ctx->ictx); + K = khash; + Klen = 32; + } + + /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ + SHA256_Init(&ctx->ictx); + memset(pad, 0x36, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + SHA256_Update(&ctx->ictx, pad, 64); + + /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ + SHA256_Init(&ctx->octx); + memset(pad, 0x5c, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + SHA256_Update(&ctx->octx, pad, 64); + + /* Clean the stack. */ + memset(khash, 0, 32); +} + +/* Add bytes to the HMAC-SHA256 operation. */ +static void +HMAC_SHA256_Update(HMAC_SHA256_CTX *ctx, const void *in, size_t len) +{ + /* Feed data to the inner SHA256 operation. */ + SHA256_Update(&ctx->ictx, in, len); +} + +/* Finish an HMAC-SHA256 operation. */ +static void +HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX *ctx) +{ + unsigned char ihash[32]; + + /* Finish the inner SHA256 operation. */ + SHA256_Final(ihash, &ctx->ictx); + + /* Feed the inner hash to the outer SHA256 operation. */ + SHA256_Update(&ctx->octx, ihash, 32); + + /* Finish the outer SHA256 operation. */ + SHA256_Final(digest, &ctx->octx); + + /* Clean the stack. */ + memset(ihash, 0, 32); +} + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +static void +PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt, + size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen) +{ + HMAC_SHA256_CTX PShctx, hctx; + size_t i; + uint8_t ivec[4]; + uint8_t U[32]; + uint8_t T[32]; + uint64_t j; + int k; + size_t clen; + + /* Compute HMAC state after processing P and S. */ + HMAC_SHA256_Init(&PShctx, passwd, passwdlen); + HMAC_SHA256_Update(&PShctx, salt, saltlen); + + /* Iterate through the blocks. */ + for (i = 0; i * 32 < dkLen; i++) { + /* Generate INT(i + 1). */ + be32enc(ivec, (uint32_t)(i + 1)); + + /* Compute U_1 = PRF(P, S || INT(i)). */ + memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX)); + HMAC_SHA256_Update(&hctx, ivec, 4); + HMAC_SHA256_Final(U, &hctx); + + /* T_i = U_1 ... */ + memcpy(T, U, 32); + + for (j = 2; j <= c; j++) { + /* Compute U_j. */ + HMAC_SHA256_Init(&hctx, passwd, passwdlen); + HMAC_SHA256_Update(&hctx, U, 32); + HMAC_SHA256_Final(U, &hctx); + + /* ... xor U_j ... */ + for (k = 0; k < 32; k++) + T[k] ^= U[k]; + } + + /* Copy as many bytes as necessary into buf. */ + clen = dkLen - i * 32; + if (clen > 32) + clen = 32; + memcpy(&buf[i * 32], T, clen); + } + + /* Clean PShctx, since we never called _Final on it. */ + memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX)); +} + + +#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) + +static inline void xor_salsa8(uint32_t B[16], const uint32_t Bx[16]) +{ + uint32_t x00,x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15; + int i; + + x00 = (B[ 0] ^= Bx[ 0]); + x01 = (B[ 1] ^= Bx[ 1]); + x02 = (B[ 2] ^= Bx[ 2]); + x03 = (B[ 3] ^= Bx[ 3]); + x04 = (B[ 4] ^= Bx[ 4]); + x05 = (B[ 5] ^= Bx[ 5]); + x06 = (B[ 6] ^= Bx[ 6]); + x07 = (B[ 7] ^= Bx[ 7]); + x08 = (B[ 8] ^= Bx[ 8]); + x09 = (B[ 9] ^= Bx[ 9]); + x10 = (B[10] ^= Bx[10]); + x11 = (B[11] ^= Bx[11]); + x12 = (B[12] ^= Bx[12]); + x13 = (B[13] ^= Bx[13]); + x14 = (B[14] ^= Bx[14]); + x15 = (B[15] ^= Bx[15]); + for (i = 0; i < 8; i += 2) { + /* Operate on columns. */ + x04 ^= ROTL(x00 + x12, 7); x09 ^= ROTL(x05 + x01, 7); + x14 ^= ROTL(x10 + x06, 7); x03 ^= ROTL(x15 + x11, 7); + + x08 ^= ROTL(x04 + x00, 9); x13 ^= ROTL(x09 + x05, 9); + x02 ^= ROTL(x14 + x10, 9); x07 ^= ROTL(x03 + x15, 9); + + x12 ^= ROTL(x08 + x04, 13); x01 ^= ROTL(x13 + x09, 13); + x06 ^= ROTL(x02 + x14, 13); x11 ^= ROTL(x07 + x03, 13); + + x00 ^= ROTL(x12 + x08, 18); x05 ^= ROTL(x01 + x13, 18); + x10 ^= ROTL(x06 + x02, 18); x15 ^= ROTL(x11 + x07, 18); + + /* Operate on rows. */ + x01 ^= ROTL(x00 + x03, 7); x06 ^= ROTL(x05 + x04, 7); + x11 ^= ROTL(x10 + x09, 7); x12 ^= ROTL(x15 + x14, 7); + + x02 ^= ROTL(x01 + x00, 9); x07 ^= ROTL(x06 + x05, 9); + x08 ^= ROTL(x11 + x10, 9); x13 ^= ROTL(x12 + x15, 9); + + x03 ^= ROTL(x02 + x01, 13); x04 ^= ROTL(x07 + x06, 13); + x09 ^= ROTL(x08 + x11, 13); x14 ^= ROTL(x13 + x12, 13); + + x00 ^= ROTL(x03 + x02, 18); x05 ^= ROTL(x04 + x07, 18); + x10 ^= ROTL(x09 + x08, 18); x15 ^= ROTL(x14 + x13, 18); + } + B[ 0] += x00; + B[ 1] += x01; + B[ 2] += x02; + B[ 3] += x03; + B[ 4] += x04; + B[ 5] += x05; + B[ 6] += x06; + B[ 7] += x07; + B[ 8] += x08; + B[ 9] += x09; + B[10] += x10; + B[11] += x11; + B[12] += x12; + B[13] += x13; + B[14] += x14; + B[15] += x15; +} + +void scrypt_1024_1_1_256_sp(const char *input, char *output, char *scratchpad) +{ + uint8_t B[128]; + uint32_t X[32]; + uint32_t *V; + uint32_t i, j, k; + + V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + + PBKDF2_SHA256((const uint8_t *)input, 80, (const uint8_t *)input, 80, 1, B, 128); + + for (k = 0; k < 32; k++) + X[k] = le32dec(&B[4 * k]); + + for (i = 0; i < 1024; i++) { + memcpy(&V[i * 32], X, 128); + xor_salsa8(&X[0], &X[16]); + xor_salsa8(&X[16], &X[0]); + } + for (i = 0; i < 1024; i++) { + j = 32 * (X[16] & 1023); + for (k = 0; k < 32; k++) + X[k] ^= V[j + k]; + xor_salsa8(&X[0], &X[16]); + xor_salsa8(&X[16], &X[0]); + } + + for (k = 0; k < 32; k++) + le32enc(&B[4 * k], X[k]); + + PBKDF2_SHA256((const uint8_t *)input, 80, B, 128, 1, (uint8_t *)output, 32); +} + +void scrypt_1024_1_1_256(const char *input, char *output) +{ + char scratchpad[SCRYPT_SCRATCHPAD_SIZE]; + scrypt_1024_1_1_256_sp(input, output, scratchpad); +} diff --git a/src/scrypt.h b/src/scrypt.h new file mode 100644 index 0000000..3a08617 --- /dev/null +++ b/src/scrypt.h @@ -0,0 +1,17 @@ +#ifndef SCRYPT_H +#define SCRYPT_H + +#ifdef __cplusplus +extern "C" { +#endif + +const int SCRYPT_SCRATCHPAD_SIZE = 131072 + 63; + +void scrypt_1024_1_1_256_sp(const char *input, char *output, char *scratchpad); +void scrypt_1024_1_1_256(const char *input, char *output); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/serialize.h b/src/serialize.h new file mode 100644 index 0000000..9cf1de4 --- /dev/null +++ b/src/serialize.h @@ -0,0 +1,1190 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_SERIALIZE_H +#define BITCOIN_SERIALIZE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "allocators.h" +#include "version.h" + +typedef long long int64; +typedef unsigned long long uint64; + +class CScript; +class CDataStream; +class CAutoFile; +static const unsigned int MAX_SIZE = 0x02000000; + +// Used to bypass the rule against non-const reference to temporary +// where it makes sense with wrappers such as CFlatData or CTxDB +template +inline T& REF(const T& val) +{ + return const_cast(val); +} + +///////////////////////////////////////////////////////////////// +// +// Templates for serializing to anything that looks like a stream, +// i.e. anything that supports .read(char*, int) and .write(char*, int) +// + +enum +{ + // primary actions + SER_NETWORK = (1 << 0), + SER_DISK = (1 << 1), + SER_GETHASH = (1 << 2), + + // modifiers + SER_SKIPSIG = (1 << 16), + SER_BLOCKHEADERONLY = (1 << 17), +}; + +#define IMPLEMENT_SERIALIZE(statements) \ + unsigned int GetSerializeSize(int nType, int nVersion) const \ + { \ + CSerActionGetSerializeSize ser_action; \ + const bool fGetSize = true; \ + const bool fWrite = false; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + ser_streamplaceholder s; \ + assert(fGetSize||fWrite||fRead); /* suppress warning */ \ + s.nType = nType; \ + s.nVersion = nVersion; \ + {statements} \ + return nSerSize; \ + } \ + template \ + void Serialize(Stream& s, int nType, int nVersion) const \ + { \ + CSerActionSerialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = true; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + assert(fGetSize||fWrite||fRead); /* suppress warning */ \ + {statements} \ + } \ + template \ + void Unserialize(Stream& s, int nType, int nVersion) \ + { \ + CSerActionUnserialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = false; \ + const bool fRead = true; \ + unsigned int nSerSize = 0; \ + assert(fGetSize||fWrite||fRead); /* suppress warning */ \ + {statements} \ + } + +#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) + + + + + + +// +// Basic types +// +#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) +#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj)) + +inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(int64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(uint64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); } + +template inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, int64 a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, uint64 a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); } + +template inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, int64& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, uint64& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); } + +inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); } +template inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); } +template inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; } + + + + + + +// +// Compact size +// size < 253 -- 1 byte +// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) +// size <= UINT_MAX -- 5 bytes (254 + 4 bytes) +// size > UINT_MAX -- 9 bytes (255 + 8 bytes) +// +inline unsigned int GetSizeOfCompactSize(uint64 nSize) +{ + if (nSize < 253) return sizeof(unsigned char); + else if (nSize <= std::numeric_limits::max()) return sizeof(unsigned char) + sizeof(unsigned short); + else if (nSize <= std::numeric_limits::max()) return sizeof(unsigned char) + sizeof(unsigned int); + else return sizeof(unsigned char) + sizeof(uint64); +} + +template +void WriteCompactSize(Stream& os, uint64 nSize) +{ + if (nSize < 253) + { + unsigned char chSize = nSize; + WRITEDATA(os, chSize); + } + else if (nSize <= std::numeric_limits::max()) + { + unsigned char chSize = 253; + unsigned short xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else if (nSize <= std::numeric_limits::max()) + { + unsigned char chSize = 254; + unsigned int xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else + { + unsigned char chSize = 255; + uint64 xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + return; +} + +template +uint64 ReadCompactSize(Stream& is) +{ + unsigned char chSize; + READDATA(is, chSize); + uint64 nSizeRet = 0; + if (chSize < 253) + { + nSizeRet = chSize; + } + else if (chSize == 253) + { + unsigned short xSize; + READDATA(is, xSize); + nSizeRet = xSize; + } + else if (chSize == 254) + { + unsigned int xSize; + READDATA(is, xSize); + nSizeRet = xSize; + } + else + { + uint64 xSize; + READDATA(is, xSize); + nSizeRet = xSize; + } + if (nSizeRet > (uint64)MAX_SIZE) + throw std::ios_base::failure("ReadCompactSize() : size too large"); + return nSizeRet; +} + + + +#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) + +/** Wrapper for serializing arrays and POD. + * There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it. + */ +class CFlatData +{ +protected: + char* pbegin; + char* pend; +public: + CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { } + char* begin() { return pbegin; } + const char* begin() const { return pbegin; } + char* end() { return pend; } + const char* end() const { return pend; } + + unsigned int GetSerializeSize(int, int=0) const + { + return pend - pbegin; + } + + template + void Serialize(Stream& s, int, int=0) const + { + s.write(pbegin, pend - pbegin); + } + + template + void Unserialize(Stream& s, int, int=0) + { + s.read(pbegin, pend - pbegin); + } +}; + +// +// Forward declarations +// + +// string +template unsigned int GetSerializeSize(const std::basic_string& str, int, int=0); +template void Serialize(Stream& os, const std::basic_string& str, int, int=0); +template void Unserialize(Stream& is, std::basic_string& str, int, int=0); + +// vector +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&); +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion); + +// others derived from vector +extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion); +template void Serialize(Stream& os, const CScript& v, int nType, int nVersion); +template void Unserialize(Stream& is, CScript& v, int nType, int nVersion); + +// pair +template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion); +template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion); +template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion); + +// 3 tuple +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); + +// 4 tuple +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); + +// map +template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::map& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::map& m, int nType, int nVersion); + +// set +template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::set& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::set& m, int nType, int nVersion); + + + + + +// +// If none of the specialized versions above matched, default to calling member function. +// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error. +// The compiler will only cast int to long if none of the other templates matched. +// Thanks to Boost serialization for this idea. +// +template +inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion) +{ + return a.GetSerializeSize((int)nType, nVersion); +} + +template +inline void Serialize(Stream& os, const T& a, long nType, int nVersion) +{ + a.Serialize(os, (int)nType, nVersion); +} + +template +inline void Unserialize(Stream& is, T& a, long nType, int nVersion) +{ + a.Unserialize(is, (int)nType, nVersion); +} + + + + + +// +// string +// +template +unsigned int GetSerializeSize(const std::basic_string& str, int, int) +{ + return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]); +} + +template +void Serialize(Stream& os, const std::basic_string& str, int, int) +{ + WriteCompactSize(os, str.size()); + if (!str.empty()) + os.write((char*)&str[0], str.size() * sizeof(str[0])); +} + +template +void Unserialize(Stream& is, std::basic_string& str, int, int) +{ + unsigned int nSize = ReadCompactSize(is); + str.resize(nSize); + if (nSize != 0) + is.read((char*)&str[0], nSize * sizeof(str[0])); +} + + + +// +// vector +// +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); +} + +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + unsigned int nSize = GetSizeOfCompactSize(v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + nSize += GetSerializeSize((*vi), nType, nVersion); + return nSize; +} + +template +inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion) +{ + return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + WriteCompactSize(os, v.size()); + if (!v.empty()) + os.write((char*)&v[0], v.size() * sizeof(T)); +} + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + WriteCompactSize(os, v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + ::Serialize(os, (*vi), nType, nVersion); +} + +template +inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion) +{ + Serialize_impl(os, v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + // Limit size per read so bogus size value won't cause out of memory + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + while (i < nSize) + { + unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); + v.resize(i + blk); + is.read((char*)&v[i], blk * sizeof(T)); + i += blk; + } +} + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + unsigned int nMid = 0; + while (nMid < nSize) + { + nMid += 5000000 / sizeof(T); + if (nMid > nSize) + nMid = nSize; + v.resize(nMid); + for (; i < nMid; i++) + Unserialize(is, v[i], nType, nVersion); + } +} + +template +inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion) +{ + Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental()); +} + + + +// +// others derived from vector +// +inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion) +{ + return GetSerializeSize((const std::vector&)v, nType, nVersion); +} + +template +void Serialize(Stream& os, const CScript& v, int nType, int nVersion) +{ + Serialize(os, (const std::vector&)v, nType, nVersion); +} + +template +void Unserialize(Stream& is, CScript& v, int nType, int nVersion) +{ + Unserialize(is, (std::vector&)v, nType, nVersion); +} + + + +// +// pair +// +template +unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion) +{ + return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion); +} + +template +void Serialize(Stream& os, const std::pair& item, int nType, int nVersion) +{ + Serialize(os, item.first, nType, nVersion); + Serialize(os, item.second, nType, nVersion); +} + +template +void Unserialize(Stream& is, std::pair& item, int nType, int nVersion) +{ + Unserialize(is, item.first, nType, nVersion); + Unserialize(is, item.second, nType, nVersion); +} + + + +// +// 3 tuple +// +template +unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion) +{ + unsigned int nSize = 0; + nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion) +{ + Serialize(os, boost::get<0>(item), nType, nVersion); + Serialize(os, boost::get<1>(item), nType, nVersion); + Serialize(os, boost::get<2>(item), nType, nVersion); +} + +template +void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion) +{ + Unserialize(is, boost::get<0>(item), nType, nVersion); + Unserialize(is, boost::get<1>(item), nType, nVersion); + Unserialize(is, boost::get<2>(item), nType, nVersion); +} + + + +// +// 4 tuple +// +template +unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion) +{ + unsigned int nSize = 0; + nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); + nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion) +{ + Serialize(os, boost::get<0>(item), nType, nVersion); + Serialize(os, boost::get<1>(item), nType, nVersion); + Serialize(os, boost::get<2>(item), nType, nVersion); + Serialize(os, boost::get<3>(item), nType, nVersion); +} + +template +void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion) +{ + Unserialize(is, boost::get<0>(item), nType, nVersion); + Unserialize(is, boost::get<1>(item), nType, nVersion); + Unserialize(is, boost::get<2>(item), nType, nVersion); + Unserialize(is, boost::get<3>(item), nType, nVersion); +} + + + +// +// map +// +template +unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + nSize += GetSerializeSize((*mi), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::map& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + Serialize(os, (*mi), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::map& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::map::iterator mi = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + std::pair item; + Unserialize(is, item, nType, nVersion); + mi = m.insert(mi, item); + } +} + + + +// +// set +// +template +unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + nSize += GetSerializeSize((*it), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::set& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + Serialize(os, (*it), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::set& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::set::iterator it = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + K key; + Unserialize(is, key, nType, nVersion); + it = m.insert(it, key); + } +} + + + +// +// Support for IMPLEMENT_SERIALIZE and READWRITE macro +// +class CSerActionGetSerializeSize { }; +class CSerActionSerialize { }; +class CSerActionUnserialize { }; + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action) +{ + return ::GetSerializeSize(obj, nType, nVersion); +} + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action) +{ + ::Serialize(s, obj, nType, nVersion); + return 0; +} + +template +inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action) +{ + ::Unserialize(s, obj, nType, nVersion); + return 0; +} + +struct ser_streamplaceholder +{ + int nType; + int nVersion; +}; + + + + + + + + + + + + +/** Double ended buffer combining vector and stream-like interfaces. + * + * >> and << read and write unformatted data using the above serialization templates. + * Fills with data in linear time; some stringstream implementations take N^2 time. + */ +class CDataStream +{ +protected: + typedef std::vector > vector_type; + vector_type vch; + unsigned int nReadPos; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + typedef vector_type::allocator_type allocator_type; + typedef vector_type::size_type size_type; + typedef vector_type::difference_type difference_type; + typedef vector_type::reference reference; + typedef vector_type::const_reference const_reference; + typedef vector_type::value_type value_type; + typedef vector_type::iterator iterator; + typedef vector_type::const_iterator const_iterator; + typedef vector_type::reverse_iterator reverse_iterator; + + explicit CDataStream(int nTypeIn, int nVersionIn) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } +#endif + + CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + { + Init(nTypeIn, nVersionIn); + } + + void Init(int nTypeIn, int nVersionIn) + { + nReadPos = 0; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = std::ios::badbit | std::ios::failbit; + } + + CDataStream& operator+=(const CDataStream& b) + { + vch.insert(vch.end(), b.begin(), b.end()); + return *this; + } + + friend CDataStream operator+(const CDataStream& a, const CDataStream& b) + { + CDataStream ret = a; + ret += b; + return (ret); + } + + std::string str() const + { + return (std::string(begin(), end())); + } + + + // + // Vector subset + // + const_iterator begin() const { return vch.begin() + nReadPos; } + iterator begin() { return vch.begin() + nReadPos; } + const_iterator end() const { return vch.end(); } + iterator end() { return vch.end(); } + size_type size() const { return vch.size() - nReadPos; } + bool empty() const { return vch.size() == nReadPos; } + void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } + void reserve(size_type n) { vch.reserve(n + nReadPos); } + const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } + reference operator[](size_type pos) { return vch[pos + nReadPos]; } + void clear() { vch.clear(); nReadPos = 0; } + iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); } + + void insert(iterator it, const_iterator first, const_iterator last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + + void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + void insert(iterator it, const char* first, const char* last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } +#endif + + iterator erase(iterator it) + { + if (it == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (++nReadPos >= vch.size()) + { + // whenever we reach the end, we take the opportunity to clear the buffer + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + return vch.begin() + nReadPos; + } + else + return vch.erase(it); + } + + iterator erase(iterator first, iterator last) + { + if (first == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (last == vch.end()) + { + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + else + { + nReadPos = (last - vch.begin()); + return last; + } + } + else + return vch.erase(first, last); + } + + inline void Compact() + { + vch.erase(vch.begin(), vch.begin() + nReadPos); + nReadPos = 0; + } + + bool Rewind(size_type n) + { + // Rewind by n characters if the buffer hasn't been compacted yet + if (n > nReadPos) + return false; + nReadPos -= n; + return true; + } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool eof() const { return size() == 0; } + bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } + bool good() const { return !eof() && (state == 0); } + void clear(short n) { state = n; } // name conflict with vector clear() + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; } + CDataStream* rdbuf() { return this; } + int in_avail() { return size(); } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CDataStream& read(char* pch, int nSize) + { + // Read from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(std::ios::failbit, "CDataStream::read() : end of data"); + memset(pch, 0, nSize); + nSize = vch.size() - nReadPos; + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = 0; + vch.clear(); + return (*this); + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& ignore(int nSize) + { + // Ignore from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(std::ios::failbit, "CDataStream::ignore() : end of data"); + nSize = vch.size() - nReadPos; + } + nReadPos = 0; + vch.clear(); + return (*this); + } + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& write(const char* pch, int nSize) + { + // Write to the end of the buffer + assert(nSize >= 0); + vch.insert(vch.end(), pch, pch + nSize); + return (*this); + } + + template + void Serialize(Stream& s, int nType, int nVersion) const + { + // Special case: stream << stream concatenates like stream += stream + if (!vch.empty()) + s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CDataStream& operator<<(const T& obj) + { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CDataStream& operator>>(T& obj) + { + // Unserialize from this stream + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; + +#ifdef TESTCDATASTREAM +// VC6sp6 +// CDataStream: +// n=1000 0 seconds +// n=2000 0 seconds +// n=4000 0 seconds +// n=8000 0 seconds +// n=16000 0 seconds +// n=32000 0 seconds +// n=64000 1 seconds +// n=128000 1 seconds +// n=256000 2 seconds +// n=512000 4 seconds +// n=1024000 8 seconds +// n=2048000 16 seconds +// n=4096000 32 seconds +// stringstream: +// n=1000 1 seconds +// n=2000 1 seconds +// n=4000 13 seconds +// n=8000 87 seconds +// n=16000 400 seconds +// n=32000 1660 seconds +// n=64000 6749 seconds +// n=128000 27241 seconds +// n=256000 109804 seconds +#include +int main(int argc, char *argv[]) +{ + vector vch(0xcc, 250); + printf("CDataStream:\n"); + for (int n = 1000; n <= 4500000; n *= 2) + { + CDataStream ss; + time_t nStart = time(NULL); + for (int i = 0; i < n; i++) + ss.write((char*)&vch[0], vch.size()); + printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); + } + printf("stringstream:\n"); + for (int n = 1000; n <= 4500000; n *= 2) + { + stringstream ss; + time_t nStart = time(NULL); + for (int i = 0; i < n; i++) + ss.write((char*)&vch[0], vch.size()); + printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); + } +} +#endif + + + + + + + + + + +/** RAII wrapper for FILE*. + * + * Will automatically close the file when it goes out of scope if not null. + * If you're returning the file pointer, return file.release(). + * If you need to close the file early, use file.fclose() instead of fclose(file). + */ +class CAutoFile +{ +protected: + FILE* file; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) + { + file = filenew; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = std::ios::badbit | std::ios::failbit; + } + + ~CAutoFile() + { + fclose(); + } + + void fclose() + { + if (file != NULL && file != stdin && file != stdout && file != stderr) + ::fclose(file); + file = NULL; + } + + FILE* release() { FILE* ret = file; file = NULL; return ret; } + operator FILE*() { return file; } + FILE* operator->() { return file; } + FILE& operator*() { return *file; } + FILE** operator&() { return &file; } + FILE* operator=(FILE* pnew) { return file = pnew; } + bool operator!() { return (file == NULL); } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } + bool good() const { return state == 0; } + void clear(short n = 0) { state = n; } + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CAutoFile& read(char* pch, size_t nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); + if (fread(pch, 1, nSize, file) != nSize) + setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); + return (*this); + } + + CAutoFile& write(const char* pch, size_t nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); + if (fwrite(pch, 1, nSize, file) != nSize) + setstate(std::ios::failbit, "CAutoFile::write : write failed"); + return (*this); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CAutoFile& operator<<(const T& obj) + { + // Serialize to this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CAutoFile& operator>>(T& obj) + { + // Unserialize from this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; + +#endif diff --git a/src/strlcpy.h b/src/strlcpy.h new file mode 100644 index 0000000..2cc786e --- /dev/null +++ b/src/strlcpy.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef BITCOIN_STRLCPY_H +#define BITCOIN_STRLCPY_H + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +inline size_t strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) + { + while (--n != 0) + { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) + { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +inline size_t strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') + { + if (n != 1) + { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} +#endif diff --git a/src/sync.cpp b/src/sync.cpp new file mode 100644 index 0000000..3702ec2 --- /dev/null +++ b/src/sync.cpp @@ -0,0 +1,130 @@ +// Copyright (c) 2011-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "sync.h" +#include "util.h" + +#include + +#ifdef DEBUG_LOCKCONTENTION +void PrintLockContention(const char* pszName, const char* pszFile, int nLine) +{ + printf("LOCKCONTENTION: %s\n", pszName); + printf("Locker: %s:%d\n", pszFile, nLine); +} +#endif /* DEBUG_LOCKCONTENTION */ + +#ifdef DEBUG_LOCKORDER +// +// Early deadlock detection. +// Problem being solved: +// Thread 1 locks A, then B, then C +// Thread 2 locks D, then C, then A +// --> may result in deadlock between the two threads, depending on when they run. +// Solution implemented here: +// Keep track of pairs of locks: (A before B), (A before C), etc. +// Complain if any thread tries to lock in a different order. +// + +struct CLockLocation +{ + CLockLocation(const char* pszName, const char* pszFile, int nLine) + { + mutexName = pszName; + sourceFile = pszFile; + sourceLine = nLine; + } + + std::string ToString() const + { + return mutexName+" "+sourceFile+":"+itostr(sourceLine); + } + +private: + std::string mutexName; + std::string sourceFile; + int sourceLine; +}; + +typedef std::vector< std::pair > LockStack; + +static boost::mutex dd_mutex; +static std::map, LockStack> lockorders; +static boost::thread_specific_ptr lockstack; + + +static void potential_deadlock_detected(const std::pair& mismatch, const LockStack& s1, const LockStack& s2) +{ + printf("POTENTIAL DEADLOCK DETECTED\n"); + printf("Previous lock order was:\n"); + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2) + { + if (i.first == mismatch.first) printf(" (1)"); + if (i.first == mismatch.second) printf(" (2)"); + printf(" %s\n", i.second.ToString().c_str()); + } + printf("Current lock order is:\n"); + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1) + { + if (i.first == mismatch.first) printf(" (1)"); + if (i.first == mismatch.second) printf(" (2)"); + printf(" %s\n", i.second.ToString().c_str()); + } +} + +static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) +{ + if (lockstack.get() == NULL) + lockstack.reset(new LockStack); + + if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str()); + dd_mutex.lock(); + + (*lockstack).push_back(std::make_pair(c, locklocation)); + + if (!fTry) { + BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack)) { + if (i.first == c) break; + + std::pair p1 = std::make_pair(i.first, c); + if (lockorders.count(p1)) + continue; + lockorders[p1] = (*lockstack); + + std::pair p2 = std::make_pair(c, i.first); + if (lockorders.count(p2)) + { + potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]); + break; + } + } + } + dd_mutex.unlock(); +} + +static void pop_lock() +{ + if (fDebug) + { + const CLockLocation& locklocation = (*lockstack).rbegin()->second; + printf("Unlocked: %s\n", locklocation.ToString().c_str()); + } + dd_mutex.lock(); + (*lockstack).pop_back(); + dd_mutex.unlock(); +} + +void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry) +{ + push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry); +} + +void LeaveCritical() +{ + pop_lock(); +} + +#endif /* DEBUG_LOCKORDER */ diff --git a/src/sync.h b/src/sync.h new file mode 100644 index 0000000..680ce19 --- /dev/null +++ b/src/sync.h @@ -0,0 +1,214 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_SYNC_H +#define BITCOIN_SYNC_H + +#include +#include +#include +#include + + + + +/** Wrapped boost mutex: supports recursive locking, but no waiting */ +typedef boost::recursive_mutex CCriticalSection; + +/** Wrapped boost mutex: supports waiting but not recursive locking */ +typedef boost::mutex CWaitableCriticalSection; + +#ifdef DEBUG_LOCKORDER +void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false); +void LeaveCritical(); +#else +void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {} +void static inline LeaveCritical() {} +#endif + +#ifdef DEBUG_LOCKCONTENTION +void PrintLockContention(const char* pszName, const char* pszFile, int nLine); +#endif + +/** Wrapper around boost::interprocess::scoped_lock */ +template +class CMutexLock +{ +private: + boost::unique_lock lock; +public: + + void Enter(const char* pszName, const char* pszFile, int nLine) + { + if (!lock.owns_lock()) + { + EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex())); +#ifdef DEBUG_LOCKCONTENTION + if (!lock.try_lock()) + { + PrintLockContention(pszName, pszFile, nLine); +#endif + lock.lock(); +#ifdef DEBUG_LOCKCONTENTION + } +#endif + } + } + + void Leave() + { + if (lock.owns_lock()) + { + lock.unlock(); + LeaveCritical(); + } + } + + bool TryEnter(const char* pszName, const char* pszFile, int nLine) + { + if (!lock.owns_lock()) + { + EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true); + lock.try_lock(); + if (!lock.owns_lock()) + LeaveCritical(); + } + return lock.owns_lock(); + } + + CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) : lock(mutexIn, boost::defer_lock) + { + if (fTry) + TryEnter(pszName, pszFile, nLine); + else + Enter(pszName, pszFile, nLine); + } + + ~CMutexLock() + { + if (lock.owns_lock()) + LeaveCritical(); + } + + operator bool() + { + return lock.owns_lock(); + } + + boost::unique_lock &GetLock() + { + return lock; + } +}; + +typedef CMutexLock CCriticalBlock; + +#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__) +#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__) +#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true) + +#define ENTER_CRITICAL_SECTION(cs) \ + { \ + EnterCritical(#cs, __FILE__, __LINE__, (void*)(&cs)); \ + (cs).lock(); \ + } + +#define LEAVE_CRITICAL_SECTION(cs) \ + { \ + (cs).unlock(); \ + LeaveCritical(); \ + } + +class CSemaphore +{ +private: + boost::condition_variable condition; + boost::mutex mutex; + int value; + +public: + CSemaphore(int init) : value(init) {} + + void wait() { + boost::unique_lock lock(mutex); + while (value < 1) { + condition.wait(lock); + } + value--; + } + + bool try_wait() { + boost::unique_lock lock(mutex); + if (value < 1) + return false; + value--; + return true; + } + + void post() { + { + boost::unique_lock lock(mutex); + value++; + } + condition.notify_one(); + } +}; + +/** RAII-style semaphore lock */ +class CSemaphoreGrant +{ +private: + CSemaphore *sem; + bool fHaveGrant; + +public: + void Acquire() { + if (fHaveGrant) + return; + sem->wait(); + fHaveGrant = true; + } + + void Release() { + if (!fHaveGrant) + return; + sem->post(); + fHaveGrant = false; + } + + bool TryAcquire() { + if (!fHaveGrant && sem->try_wait()) + fHaveGrant = true; + return fHaveGrant; + } + + void MoveTo(CSemaphoreGrant &grant) { + grant.Release(); + grant.sem = sem; + grant.fHaveGrant = fHaveGrant; + sem = NULL; + fHaveGrant = false; + } + + CSemaphoreGrant() : sem(NULL), fHaveGrant(false) {} + + CSemaphoreGrant(CSemaphore &sema, bool fTry = false) : sem(&sema), fHaveGrant(false) { + if (fTry) + TryAcquire(); + else + Acquire(); + } + + ~CSemaphoreGrant() { + Release(); + } + + operator bool() { + return fHaveGrant; + } +}; +#endif + diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp new file mode 100644 index 0000000..36a9873 --- /dev/null +++ b/src/test/Checkpoints_tests.cpp @@ -0,0 +1,34 @@ +// +// Unit tests for block-chain checkpoints +// +#include // for 'map_list_of()' +#include +#include + +#include "../checkpoints.h" +#include "../util.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(Checkpoints_tests) + +BOOST_AUTO_TEST_CASE(sanity) +{ + uint256 p1500 = uint256("0x841a2965955dd288cfa707a755d05a54e45f8bd476835ec9af4402a2b59a2967"); + uint256 p120000 = uint256("0xbd9d26924f05f6daa7f0155f32828ec89e8e29cee9e7121b026a7a3552ac6131"); + BOOST_CHECK(Checkpoints::CheckBlock(1500, p1500)); + BOOST_CHECK(Checkpoints::CheckBlock(120000, p120000)); + + + // Wrong hashes at checkpoints should fail: + BOOST_CHECK(!Checkpoints::CheckBlock(1500, p120000)); + BOOST_CHECK(!Checkpoints::CheckBlock(120000, p1500)); + + // ... but any hash not at a checkpoint should succeed: + BOOST_CHECK(Checkpoints::CheckBlock(1500+1, p120000)); + BOOST_CHECK(Checkpoints::CheckBlock(120000+1, p1500)); + + BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 120000); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp new file mode 100644 index 0000000..4a185b3 --- /dev/null +++ b/src/test/DoS_tests.cpp @@ -0,0 +1,314 @@ +// +// Unit tests for denial-of-service detection/prevention code +// +#include + +#include // for 'map_list_of()' +#include +#include +#include + +#include "main.h" +#include "wallet.h" +#include "net.h" +#include "util.h" + +#include + +// Tests this internal-to-main.cpp method: +extern bool AddOrphanTx(const CDataStream& vMsg); +extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans); +extern std::map mapOrphanTransactions; +extern std::map > mapOrphanTransactionsByPrev; + +CService ip(uint32_t i) +{ + struct in_addr s; + s.s_addr = i; + return CService(CNetAddr(s), GetDefaultPort()); +} + +BOOST_AUTO_TEST_SUITE(DoS_tests) + +BOOST_AUTO_TEST_CASE(DoS_banning) +{ + CNode::ClearBanned(); + CAddress addr1(ip(0xa0b0c001)); + CNode dummyNode1(INVALID_SOCKET, addr1, "", true); + dummyNode1.Misbehaving(100); // Should get banned + BOOST_CHECK(CNode::IsBanned(addr1)); + BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different ip, not banned + + CAddress addr2(ip(0xa0b0c002)); + CNode dummyNode2(INVALID_SOCKET, addr2, "", true); + dummyNode2.Misbehaving(50); + BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet... + BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be + dummyNode2.Misbehaving(50); + BOOST_CHECK(CNode::IsBanned(addr2)); +} + +BOOST_AUTO_TEST_CASE(DoS_banscore) +{ + CNode::ClearBanned(); + mapArgs["-banscore"] = "111"; // because 11 is my favorite number + CAddress addr1(ip(0xa0b0c001)); + CNode dummyNode1(INVALID_SOCKET, addr1, "", true); + dummyNode1.Misbehaving(100); + BOOST_CHECK(!CNode::IsBanned(addr1)); + dummyNode1.Misbehaving(10); + BOOST_CHECK(!CNode::IsBanned(addr1)); + dummyNode1.Misbehaving(1); + BOOST_CHECK(CNode::IsBanned(addr1)); + mapArgs.erase("-banscore"); +} + +BOOST_AUTO_TEST_CASE(DoS_bantime) +{ + CNode::ClearBanned(); + int64 nStartTime = GetTime(); + SetMockTime(nStartTime); // Overrides future calls to GetTime() + + CAddress addr(ip(0xa0b0c001)); + CNode dummyNode(INVALID_SOCKET, addr, "", true); + + dummyNode.Misbehaving(100); + BOOST_CHECK(CNode::IsBanned(addr)); + + SetMockTime(nStartTime+60*60); + BOOST_CHECK(CNode::IsBanned(addr)); + + SetMockTime(nStartTime+60*60*24+1); + BOOST_CHECK(!CNode::IsBanned(addr)); +} + +static bool CheckNBits(unsigned int nbits1, int64 time1, unsigned int nbits2, int64 time2)\ +{ + if (time1 > time2) + return CheckNBits(nbits2, time2, nbits1, time1); + int64 deltaTime = time2-time1; + + CBigNum required; + required.SetCompact(ComputeMinWork(nbits1, deltaTime)); + CBigNum have; + have.SetCompact(nbits2); + return (have <= required); +} + +BOOST_AUTO_TEST_CASE(DoS_checknbits) +{ + using namespace boost::assign; // for 'map_list_of()' + + // Timestamps,nBits from the bitcoin blockchain. + // These are the block-chain checkpoint blocks + typedef std::map BlockData; + BlockData chainData = + map_list_of(1239852051,486604799)(1262749024,486594666) + (1279305360,469854461)(1280200847,469830746)(1281678674,469809688) + (1296207707,453179945)(1302624061,453036989)(1309640330,437004818) + (1313172719,436789733); + + // Make sure CheckNBits considers every combination of block-chain-lock-in-points + // "sane": + BOOST_FOREACH(const BlockData::value_type& i, chainData) + { + BOOST_FOREACH(const BlockData::value_type& j, chainData) + { + BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first)); + } + } + + // Test a couple of insane combinations: + BlockData::value_type firstcheck = *(chainData.begin()); + BlockData::value_type lastcheck = *(chainData.rbegin()); + + // First checkpoint difficulty at or a while after the last checkpoint time should fail when + // compared to last checkpoint + BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*10, lastcheck.second, lastcheck.first)); + BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*60*24*14, lastcheck.second, lastcheck.first)); + + // ... but OK if enough time passed for difficulty to adjust downward: + BOOST_CHECK(CheckNBits(firstcheck.second, lastcheck.first+60*60*24*365*4, lastcheck.second, lastcheck.first)); + +} + +CTransaction RandomOrphan() +{ + std::map::iterator it; + it = mapOrphanTransactions.lower_bound(GetRandHash()); + if (it == mapOrphanTransactions.end()) + it = mapOrphanTransactions.begin(); + const CDataStream* pvMsg = it->second; + CTransaction tx; + CDataStream(*pvMsg) >> tx; + return tx; +} + +BOOST_AUTO_TEST_CASE(DoS_mapOrphans) +{ + CKey key; + key.MakeNewKey(true); + CBasicKeyStore keystore; + keystore.AddKey(key); + + // 50 orphan transactions: + for (int i = 0; i < 50; i++) + { + CTransaction tx; + tx.vin.resize(1); + tx.vin[0].prevout.n = 0; + tx.vin[0].prevout.hash = GetRandHash(); + tx.vin[0].scriptSig << OP_1; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + + CDataStream ds(SER_DISK, CLIENT_VERSION); + ds << tx; + AddOrphanTx(ds); + } + + // ... and 50 that depend on other orphans: + for (int i = 0; i < 50; i++) + { + CTransaction txPrev = RandomOrphan(); + + CTransaction tx; + tx.vin.resize(1); + tx.vin[0].prevout.n = 0; + tx.vin[0].prevout.hash = txPrev.GetHash(); + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + SignSignature(keystore, txPrev, tx, 0); + + CDataStream ds(SER_DISK, CLIENT_VERSION); + ds << tx; + AddOrphanTx(ds); + } + + // This really-big orphan should be ignored: + for (int i = 0; i < 10; i++) + { + CTransaction txPrev = RandomOrphan(); + + CTransaction tx; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + tx.vin.resize(500); + for (unsigned int j = 0; j < tx.vin.size(); j++) + { + tx.vin[j].prevout.n = j; + tx.vin[j].prevout.hash = txPrev.GetHash(); + } + SignSignature(keystore, txPrev, tx, 0); + // Re-use same signature for other inputs + // (they don't have to be valid for this test) + for (unsigned int j = 1; j < tx.vin.size(); j++) + tx.vin[j].scriptSig = tx.vin[0].scriptSig; + + CDataStream ds(SER_DISK, CLIENT_VERSION); + ds << tx; + BOOST_CHECK(!AddOrphanTx(ds)); + } + + // Test LimitOrphanTxSize() function: + LimitOrphanTxSize(40); + BOOST_CHECK(mapOrphanTransactions.size() <= 40); + LimitOrphanTxSize(10); + BOOST_CHECK(mapOrphanTransactions.size() <= 10); + LimitOrphanTxSize(0); + BOOST_CHECK(mapOrphanTransactions.empty()); + BOOST_CHECK(mapOrphanTransactionsByPrev.empty()); +} + +BOOST_AUTO_TEST_CASE(DoS_checkSig) +{ + // Test signature caching code (see key.cpp Verify() methods) + + CKey key; + key.MakeNewKey(true); + CBasicKeyStore keystore; + keystore.AddKey(key); + + // 100 orphan transactions: + static const int NPREV=100; + CTransaction orphans[NPREV]; + for (int i = 0; i < NPREV; i++) + { + CTransaction& tx = orphans[i]; + tx.vin.resize(1); + tx.vin[0].prevout.n = 0; + tx.vin[0].prevout.hash = GetRandHash(); + tx.vin[0].scriptSig << OP_1; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + + CDataStream ds(SER_DISK, CLIENT_VERSION); + ds << tx; + AddOrphanTx(ds); + } + + // Create a transaction that depends on orphans: + CTransaction tx; + tx.vout.resize(1); + tx.vout[0].nValue = 1*CENT; + tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + tx.vin.resize(NPREV); + for (unsigned int j = 0; j < tx.vin.size(); j++) + { + tx.vin[j].prevout.n = 0; + tx.vin[j].prevout.hash = orphans[j].GetHash(); + } + // Creating signatures primes the cache: + boost::posix_time::ptime mst1 = boost::posix_time::microsec_clock::local_time(); + for (unsigned int j = 0; j < tx.vin.size(); j++) + BOOST_CHECK(SignSignature(keystore, orphans[j], tx, j)); + boost::posix_time::ptime mst2 = boost::posix_time::microsec_clock::local_time(); + boost::posix_time::time_duration msdiff = mst2 - mst1; + long nOneValidate = msdiff.total_milliseconds(); + if (fDebug) printf("DoS_Checksig sign: %ld\n", nOneValidate); + + // ... now validating repeatedly should be quick: + // 2.8GHz machine, -g build: Sign takes ~760ms, + // uncached Verify takes ~250ms, cached Verify takes ~50ms + // (for 100 single-signature inputs) + mst1 = boost::posix_time::microsec_clock::local_time(); + for (unsigned int i = 0; i < 5; i++) + for (unsigned int j = 0; j < tx.vin.size(); j++) + BOOST_CHECK(VerifySignature(orphans[j], tx, j, true, SIGHASH_ALL)); + mst2 = boost::posix_time::microsec_clock::local_time(); + msdiff = mst2 - mst1; + long nManyValidate = msdiff.total_milliseconds(); + if (fDebug) printf("DoS_Checksig five: %ld\n", nManyValidate); + + BOOST_CHECK_MESSAGE(nManyValidate < nOneValidate, "Signature cache timing failed"); + + // Empty a signature, validation should fail: + CScript save = tx.vin[0].scriptSig; + tx.vin[0].scriptSig = CScript(); + BOOST_CHECK(!VerifySignature(orphans[0], tx, 0, true, SIGHASH_ALL)); + tx.vin[0].scriptSig = save; + + // Swap signatures, validation should fail: + std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig); + BOOST_CHECK(!VerifySignature(orphans[0], tx, 0, true, SIGHASH_ALL)); + BOOST_CHECK(!VerifySignature(orphans[1], tx, 1, true, SIGHASH_ALL)); + std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig); + + // Exercise -maxsigcachesize code: + mapArgs["-maxsigcachesize"] = "10"; + // Generate a new, different signature for vin[0] to trigger cache clear: + CScript oldSig = tx.vin[0].scriptSig; + BOOST_CHECK(SignSignature(keystore, orphans[0], tx, 0)); + BOOST_CHECK(tx.vin[0].scriptSig != oldSig); + for (unsigned int j = 0; j < tx.vin.size(); j++) + BOOST_CHECK(VerifySignature(orphans[j], tx, j, true, SIGHASH_ALL)); + mapArgs.erase("-maxsigcachesize"); + + LimitOrphanTxSize(0); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/README b/src/test/README new file mode 100644 index 0000000..77f7faa --- /dev/null +++ b/src/test/README @@ -0,0 +1,21 @@ +The sources in this directory are unit test cases. Boost includes a +unit testing framework, and since bitcoin already uses boost, it makes +sense to simply use this framework rather than require developers to +configure some other framework (we want as few impediments to creating +unit tests as possible). + +The build system is setup to compile an executable called "test_bitcoin" +that runs all of the unit tests. The main source file is called +test_bitcoin.cpp, which simply includes other files that contain the +actual unit tests (outside of a couple required preprocessor +directives). The pattern is to create one test file for each class or +source file for which you want to create unit tests. The file naming +convention is "_tests.cpp" and such files should wrap +their tests in a test suite called "_tests". For an +examples of this pattern, examine uint160_tests.cpp and +uint256_tests.cpp. + +For further reading, I found the following website to be helpful in +explaining how the boost unit test framework works: + +http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/ diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp new file mode 100644 index 0000000..fdf3285 --- /dev/null +++ b/src/test/base32_tests.cpp @@ -0,0 +1,20 @@ +#include + +#include "util.h" + +BOOST_AUTO_TEST_SUITE(base32_tests) + +BOOST_AUTO_TEST_CASE(base32_testvectors) +{ + static const std::string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"}; + static const std::string vstrOut[] = {"","my======","mzxq====","mzxw6===","mzxw6yq=","mzxw6ytb","mzxw6ytboi======"}; + for (unsigned int i=0; i + +#include "base58.h" + +BOOST_AUTO_TEST_SUITE(base58_tests) + +// TODO: +// EncodeBase58Check +// DecodeBase58Check +// CBase58Data +// bool SetString(const char* psz) + // bool SetString(const std::string& str) + // std::string ToString() const + // int CompareTo(const CBase58Data& b58) const + // bool operator==(const CBase58Data& b58) const + // bool operator<=(const CBase58Data& b58) const + // bool operator>=(const CBase58Data& b58) const + // bool operator< (const CBase58Data& b58) const + // bool operator> (const CBase58Data& b58) const + +// CBitcoinAddress + // bool SetHash160(const uint160& hash160) + // bool SetPubKey(const std::vector& vchPubKey) + // bool IsValid() const + // CBitcoinAddress() + // CBitcoinAddress(uint160 hash160In) + // CBitcoinAddress(const std::vector& vchPubKey) + // CBitcoinAddress(const std::string& strAddress) + // CBitcoinAddress(const char* pszAddress) + // uint160 GetHash160() const + +#define U(x) (reinterpret_cast(x)) +static struct { + const unsigned char *data; + int size; +} vstrIn[] = { +{U(""), 0}, +{U("\x61"), 1}, +{U("\x62\x62\x62"), 3}, +{U("\x63\x63\x63"), 3}, +{U("\x73\x69\x6d\x70\x6c\x79\x20\x61\x20\x6c\x6f\x6e\x67\x20\x73\x74\x72\x69\x6e\x67"), 20}, +{U("\x00\xeb\x15\x23\x1d\xfc\xeb\x60\x92\x58\x86\xb6\x7d\x06\x52\x99\x92\x59\x15\xae\xb1\x72\xc0\x66\x47"), 25}, +{U("\x51\x6b\x6f\xcd\x0f"), 5}, +{U("\xbf\x4f\x89\x00\x1e\x67\x02\x74\xdd"), 9}, +{U("\x57\x2e\x47\x94"), 4}, +{U("\xec\xac\x89\xca\xd9\x39\x23\xc0\x23\x21"), 10}, +{U("\x10\xc8\x51\x1e"), 4}, +{U("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), 10}, +}; + +const char *vstrOut[] = { +"", +"2g", +"a3gV", +"aPEr", +"2cFupjhnEsSn59qHXstmK2ffpLv2", +"1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L", +"ABnLTmg", +"3SEo3LWLoPntC", +"3EFU7m", +"EJDM8drfXA6uyA", +"Rt5zm", +"1111111111" +}; + +BOOST_AUTO_TEST_CASE(base58_EncodeBase58) +{ + for (unsigned int i=0; i result; + for (unsigned int i=0; i expected(vstrIn[i].data, vstrIn[i].data + vstrIn[i].size); + BOOST_CHECK(DecodeBase58(vstrOut[i], result)); + BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); + } + BOOST_CHECK(!DecodeBase58("invalid", result)); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp new file mode 100644 index 0000000..c5a053e --- /dev/null +++ b/src/test/base64_tests.cpp @@ -0,0 +1,22 @@ +#include + +#include "main.h" +#include "wallet.h" +#include "util.h" + +BOOST_AUTO_TEST_SUITE(base64_tests) + +BOOST_AUTO_TEST_CASE(base64_testvectors) +{ + static const std::string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"}; + static const std::string vstrOut[] = {"","Zg==","Zm8=","Zm9v","Zm9vYg==","Zm9vYmE=","Zm9vYmFy"}; + for (unsigned int i=0; i +#include + +#include "bignum.h" +#include "util.h" + +BOOST_AUTO_TEST_SUITE(bignum_tests) + +// Unfortunately there's no standard way of preventing a function from being +// inlined, so we define a macro for it. +// +// You should use it like this: +// NOINLINE void function() {...} +#if defined(__GNUC__) +// This also works and will be defined for any compiler implementing gcc +// extensions, such as clang and icc. +#define NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define NOINLINE __declspec(noinline) +#else +// We give out a warning because it impacts the correctness of one bignum test. +#warning You should define NOINLINE for your compiler. +#define NOINLINE +#endif + +// For the following test case, it is useful to use additional tools. +// +// The simplest one to use is the compiler flag -ftrapv, which detects integer +// overflows and similar errors. However, due to optimizations and compilers +// taking advantage of undefined behavior sometimes it may not actually detect +// anything. +// +// You can also use compiler-based stack protection to possibly detect possible +// stack buffer overruns. +// +// For more accurate diagnostics, you can use an undefined arithmetic operation +// detector such as the clang-based tool: +// +// "IOC: An Integer Overflow Checker for C/C++" +// +// Available at: http://embed.cs.utah.edu/ioc/ +// +// It might also be useful to use Google's AddressSanitizer to detect +// stack buffer overruns, which valgrind can't currently detect. + +// Let's force this code not to be inlined, in order to actually +// test a generic version of the function. This increases the chance +// that -ftrapv will detect overflows. +NOINLINE void mysetint64(CBigNum& num, int64 n) +{ + num.setint64(n); +} + +// For each number, we do 2 tests: one with inline code, then we reset the +// value to 0, then the second one with a non-inlined function. +BOOST_AUTO_TEST_CASE(bignum_setint64) +{ + int64 n; + + { + n = 0; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "0"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "0"); + } + { + n = 1; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "1"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "1"); + } + { + n = -1; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "-1"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "-1"); + } + { + n = 5; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "5"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "5"); + } + { + n = -5; + CBigNum num(n); + BOOST_CHECK(num.ToString() == "-5"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "-5"); + } + { + n = std::numeric_limits::min(); + CBigNum num(n); + BOOST_CHECK(num.ToString() == "-9223372036854775808"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "-9223372036854775808"); + } + { + n = std::numeric_limits::max(); + CBigNum num(n); + BOOST_CHECK(num.ToString() == "9223372036854775807"); + num.setulong(0); + BOOST_CHECK(num.ToString() == "0"); + mysetint64(num, n); + BOOST_CHECK(num.ToString() == "9223372036854775807"); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json new file mode 100644 index 0000000..0c2d711 --- /dev/null +++ b/src/test/data/script_invalid.json @@ -0,0 +1,161 @@ +[ +["", ""], +["", "NOP"], +["NOP", ""], +["NOP","NOP"], + +["0x4c01","0x01 NOP", "PUSHDATA1 with not enough bytes"], +["0x4d0200ff","0x01 NOP", "PUSHDATA2 with not enough bytes"], +["0x4e03000000ffff","0x01 NOP", "PUSHDATA4 with not enough bytes"], + +["1", "IF 0x50 ENDIF 1", "0x50 is reserved"], +["0x52", "0x5f ADD 0x60 EQUAL", "0x51 through 0x60 push 1 through 16 onto stack"], +["0","NOP"], +["1", "IF VER ELSE 1 ENDIF", "VER non-functional"], +["0", "IF VERIF ELSE 1 ENDIF", "VERIF illegal everywhere"], +["0", "IF VERNOTIF ELSE 1 ENDIF", "VERNOT illegal everywhere"], + +["1 IF", "1 ENDIF", "IF/ENDIF can't span scriptSig/scriptPubKey"], +["1 IF 0 ENDIF", "1 ENDIF"], +["1 ELSE 0 ENDIF", "1"], +["0 NOTIF", "123"], + +["0", "DUP IF ENDIF"], +["0", "IF 1 ENDIF"], +["0", "DUP IF ELSE ENDIF"], +["0", "IF 1 ELSE ENDIF"], +["0", "NOTIF ELSE 1 ENDIF"], + +["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF"], +["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF"], +["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], + +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF"], +["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF"], +["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], + +["1", "RETURN"], +["1", "DUP IF RETURN ENDIF"], + +["0", "VERIFY 1"], +["1", "VERIFY"], +["1", "VERIFY 0"], + +["1 TOALTSTACK", "FROMALTSTACK 1", "alt stack not shared between sig/pubkey"], + +["IFDUP", "DEPTH 0 EQUAL"], +["DROP", "DEPTH 0 EQUAL"], +["DUP", "DEPTH 0 EQUAL"], +["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL"], +["NOP", "NIP"], +["NOP", "1 NIP"], +["NOP", "1 0 NIP"], +["NOP", "OVER 1"], +["1", "OVER"], +["0 1", "OVER DEPTH 3 EQUALVERIFY"], +["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL"], +["NOP", "0 PICK"], +["1", "-1 PICK"], +["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL"], +["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL"], +["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL"], +["NOP", "0 ROLL"], +["1", "-1 ROLL"], +["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL"], +["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL"], +["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL"], +["NOP", "ROT 1"], +["NOP", "1 ROT 1"], +["NOP", "1 2 ROT 1"], +["NOP", "0 1 2 ROT"], +["NOP", "SWAP 1"], +["1", "SWAP 1"], +["0 1", "SWAP 1 EQUALVERIFY"], +["NOP", "TUCK 1"], +["1", "TUCK 1"], +["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP"], +["NOP", "2DUP 1"], +["1", "2DUP 1"], +["NOP", "3DUP 1"], +["1", "3DUP 1"], +["1 2", "3DUP 1"], +["NOP", "2OVER 1"], +["1", "2 3 2OVER 1"], +["NOP", "2SWAP 1"], +["1", "2 3 2SWAP 1"], + +["'a' 'b'", "CAT", "CAT disabled"], +["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "CAT disabled"], +["'abc' 1 1", "SUBSTR", "SUBSTR disabled"], +["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "SUBSTR disabled"], +["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "LEFT disabled"], +["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "RIGHT disabled"], + +["NOP", "SIZE 1"], + +["'abc'", "IF INVERT ELSE 1 ENDIF", "INVERT disabled"], +["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "AND disabled"], +["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "OR disabled"], +["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "XOR disabled"], +["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "2MUL disabled"], +["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "2DIV disabled"], +["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "MUL disabled"], +["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "DIV disabled"], +["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "MOD disabled"], +["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "LSHIFT disabled"], +["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "RSHIFT disabled"], + +["0 1","EQUAL"], +["1 1 ADD", "0 EQUAL"], +["11 1 ADD 12 SUB", "11 EQUAL"], + +["2147483648 0 ADD", "NOP", "arithmetic operands must be in range [-2^31...2^31] "], +["-2147483648 0 ADD", "NOP", "arithmetic operands must be in range [-2^31...2^31] "], +["2147483647 DUP ADD", "4294967294 NUMEQUAL", "NUMEQUAL must be in numeric range"], +["'abcdef' NOT", "0 EQUAL", "NOT is an arithmetic operand"], + +["2 DUP MUL", "4 EQUAL", "disabled"], +["2 DUP DIV", "1 EQUAL", "disabled"], +["2 2MUL", "4 EQUAL", "disabled"], +["2 2DIV", "1 EQUAL", "disabled"], +["7 3 MOD", "1 EQUAL", "disabled"], +["2 2 LSHIFT", "8 EQUAL", "disabled"], +["2 1 RSHIFT", "1 EQUAL", "disabled"], + +["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL"], +["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL"], + +["0x50","1", "opcode 0x50 is reserved"], +["1", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid"], +["1", "IF 0xc0 ELSE 1 ENDIF"], +["1", "IF 0xd1 ELSE 1 ENDIF"], +["1", "IF 0xee ELSE 1 ENDIF"], +["1", "IF 0xfd ELSE 1 ENDIF"], +["1", "IF 0xff ELSE 1 ENDIF"], + +["NOP", "RIPEMD160"], +["NOP", "SHA1"], +["NOP", "SHA256"], +["NOP", "HASH160"], +["NOP", "HASH256"], + +["NOP", +"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", +">520 byte push"], +["1", +"0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +">201 opcodes executed. 0x61 is NOP"], +["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 2 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +">1,000 stack size (0x6f is 3DUP)"], +["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 TOALTSTACK 2 TOALTSTACK 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +">1,000 stack+altstack size"], +["NOP", +"0 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +"10,001-byte scriptPubKey"], + +["NOP1","NOP10"] +] diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json new file mode 100644 index 0000000..6ef4d46 --- /dev/null +++ b/src/test/data/script_valid.json @@ -0,0 +1,204 @@ +[ +["0x01 0x0b", "11 EQUAL", "push 1 byte"], +["0x02 0x417a", "'Az' EQUAL"], +["0x4b 0x417a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a", + "'Azzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' EQUAL", "push 75 bytes"], + +["0x4c 0x01 0x07","7 EQUAL", "0x4c is OP_PUSHDATA1"], +["0x4d 0x0100 0x08","8 EQUAL", "0x4d is OP_PUSHDATA2"], +["0x4e 0x01000000 0x09","9 EQUAL", "0x4e is OP_PUSHDATA4"], + +["0x4c 0x00","0 EQUAL"], +["0x4d 0x0000","0 EQUAL"], +["0x4e 0x00000000","0 EQUAL"], +["0x4f 1000 ADD","999 EQUAL"], +["0", "IF 0x50 ENDIF 1", "0x50 is reserved (ok if not executed)"], +["0x51", "0x5f ADD 0x60 EQUAL", "0x51 through 0x60 push 1 through 16 onto stack"], +["1","NOP"], +["0", "IF VER ELSE 1 ENDIF", "VER non-functional (ok if not executed)"], +["0", "IF RESERVED1 RESERVED2 ELSE 1 ENDIF", "RESERVED ok in un-executed IF"], + +["1", "DUP IF ENDIF"], +["1", "IF 1 ENDIF"], +["1", "DUP IF ELSE ENDIF"], +["1", "IF 1 ELSE ENDIF"], +["0", "IF ELSE 1 ENDIF"], + +["1 1", "IF IF 1 ELSE 0 ENDIF ENDIF"], +["1 0", "IF IF 1 ELSE 0 ENDIF ENDIF"], +["1 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], + +["1 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF"], +["1 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF"], +["1 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], + +["1 1", "VERIFY"], + +["10 0 11 TOALTSTACK DROP FROMALTSTACK", "ADD 21 EQUAL"], +["'gavin_was_here' TOALTSTACK 11 FROMALTSTACK", "'gavin_was_here' EQUALVERIFY 11 EQUAL"], + +["0 IFDUP", "DEPTH 1 EQUALVERIFY 0 EQUAL"], +["1 IFDUP", "DEPTH 2 EQUALVERIFY 1 EQUALVERIFY 1 EQUAL"], +["0 DROP", "DEPTH 0 EQUAL"], +["0", "DUP 1 ADD 1 EQUALVERIFY 0 EQUAL"], +["0 1", "NIP"], +["1 0", "OVER DEPTH 3 EQUALVERIFY"], +["22 21 20", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL"], +["22 21 20", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL"], +["22 21 20", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL"], +["22 21 20", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL"], +["22 21 20", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL"], +["22 21 20", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL"], +["22 21 20", "ROT 22 EQUAL"], +["22 21 20", "ROT ROT 21 EQUAL"], +["22 21 20", "ROT ROT ROT 20 EQUAL"], +["1 0", "SWAP 1 EQUALVERIFY 0 EQUAL"], +["0 1", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP"], +["13 14", "2DUP ROT EQUALVERIFY EQUAL"], +["-1 0 1 2", "3DUP DEPTH 7 EQUALVERIFY ADD ADD 3 EQUALVERIFY 2DROP 0 EQUALVERIFY"], +["1 2 3 5", "2OVER ADD ADD 8 EQUALVERIFY ADD ADD 6 EQUAL"], +["1 3 5 7", "2SWAP ADD 4 EQUALVERIFY ADD 12 EQUAL"], +["0", "SIZE 0 EQUAL"], +["1", "SIZE 1 EQUAL"], +["127", "SIZE 1 EQUAL"], +["128", "SIZE 2 EQUAL"], +["32767", "SIZE 2 EQUAL"], +["32768", "SIZE 3 EQUAL"], +["8388607", "SIZE 3 EQUAL"], +["8388608", "SIZE 4 EQUAL"], +["2147483647", "SIZE 4 EQUAL"], +["2147483648", "SIZE 5 EQUAL"], +["-1", "SIZE 1 EQUAL"], +["-127", "SIZE 1 EQUAL"], +["-128", "SIZE 2 EQUAL"], +["-32767", "SIZE 2 EQUAL"], +["-32768", "SIZE 3 EQUAL"], +["-8388607", "SIZE 3 EQUAL"], +["-8388608", "SIZE 4 EQUAL"], +["-2147483647", "SIZE 4 EQUAL"], +["-2147483648", "SIZE 5 EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "SIZE 26 EQUAL"], + + +["2 -2 ADD", "0 EQUAL"], +["2147483647 -2147483647 ADD", "0 EQUAL"], +["-1 -1 ADD", "-2 EQUAL"], + +["0 0","EQUAL"], +["1 1 ADD", "2 EQUAL"], +["1 1ADD", "2 EQUAL"], +["111 1SUB", "110 EQUAL"], +["111 1 ADD 12 SUB", "100 EQUAL"], +["0 ABS", "0 EQUAL"], +["16 ABS", "16 EQUAL"], +["-16 ABS", "-16 NEGATE EQUAL"], +["0 NOT", "NOP"], +["1 NOT", "0 EQUAL"], +["11 NOT", "0 EQUAL"], +["0 0NOTEQUAL", "0 EQUAL"], +["1 0NOTEQUAL", "1 EQUAL"], +["111 0NOTEQUAL", "1 EQUAL"], +["-111 0NOTEQUAL", "1 EQUAL"], +["1 1 BOOLAND", "NOP"], +["1 0 BOOLAND", "NOT"], +["0 1 BOOLAND", "NOT"], +["0 0 BOOLAND", "NOT"], +["16 17 BOOLAND", "NOP"], +["1 1 BOOLOR", "NOP"], +["1 0 BOOLOR", "NOP"], +["0 1 BOOLOR", "NOP"], +["0 0 BOOLOR", "NOT"], +["16 17 BOOLOR", "NOP"], +["11 10 1 ADD", "NUMEQUAL"], +["11 10 1 ADD", "NUMEQUALVERIFY 1"], +["11 10 1 ADD", "NUMNOTEQUAL NOT"], +["111 10 1 ADD", "NUMNOTEQUAL"], +["11 10", "LESSTHAN NOT"], +["4 4", "LESSTHAN NOT"], +["10 11", "LESSTHAN"], +["-11 11", "LESSTHAN"], +["-11 -10", "LESSTHAN"], +["11 10", "GREATERTHAN"], +["4 4", "GREATERTHAN NOT"], +["10 11", "GREATERTHAN NOT"], +["-11 11", "GREATERTHAN NOT"], +["-11 -10", "GREATERTHAN NOT"], +["11 10", "LESSTHANOREQUAL NOT"], +["4 4", "LESSTHANOREQUAL"], +["10 11", "LESSTHANOREQUAL"], +["-11 11", "LESSTHANOREQUAL"], +["-11 -10", "LESSTHANOREQUAL"], +["11 10", "GREATERTHANOREQUAL"], +["4 4", "GREATERTHANOREQUAL"], +["10 11", "GREATERTHANOREQUAL NOT"], +["-11 11", "GREATERTHANOREQUAL NOT"], +["-11 -10", "GREATERTHANOREQUAL NOT"], +["1 0 MIN", "0 NUMEQUAL"], +["0 1 MIN", "0 NUMEQUAL"], +["-1 0 MIN", "-1 NUMEQUAL"], +["0 -2147483647 MIN", "-2147483647 NUMEQUAL"], +["2147483647 0 MAX", "2147483647 NUMEQUAL"], +["0 100 MAX", "100 NUMEQUAL"], +["-100 0 MAX", "0 NUMEQUAL"], +["0 -2147483647 MAX", "0 NUMEQUAL"], +["0 0 1", "WITHIN"], +["1 0 1", "WITHIN NOT"], +["0 -2147483647 2147483647", "WITHIN"], +["-1 -100 100", "WITHIN"], +["11 -100 100", "WITHIN"], +["-2147483647 -100 100", "WITHIN NOT"], +["2147483647 -100 100", "WITHIN NOT"], + +["2147483647 2147483647 SUB", "0 EQUAL"], +["2147483647 DUP ADD", "4294967294 EQUAL", ">32 bit EQUAL is valid"], +["2147483647 NEGATE DUP ADD", "-4294967294 EQUAL"], + +["''", "RIPEMD160 0x14 0x9c1185a5c5e9fc54612808977ee8f548b2258d31 EQUAL"], +["'a'", "RIPEMD160 0x14 0x0bdc9d2d256b3ee9daae347be6f4dc835a467ffe EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "RIPEMD160 0x14 0xf71c27109c692c1b56bbdceb5b9d2865b3708dbc EQUAL"], +["''", "SHA1 0x14 0xda39a3ee5e6b4b0d3255bfef95601890afd80709 EQUAL"], +["'a'", "SHA1 0x14 0x86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "SHA1 0x14 0x32d10c7b8cf96570ca04ce37f2a19d84240d3a89 EQUAL"], +["''", "SHA256 0x20 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 EQUAL"], +["'a'", "SHA256 0x20 0xca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "SHA256 0x20 0x71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73 EQUAL"], +["''", "DUP HASH160 SWAP SHA256 RIPEMD160 EQUAL"], +["''", "DUP HASH256 SWAP SHA256 SHA256 EQUAL"], +["''", "NOP HASH160 0x14 0xb472a266d0bd89c13706a4132ccfb16f7c3b9fcb EQUAL"], +["'a'", "HASH160 NOP 0x14 0x994355199e516ff76c4fa4aab39337b9d84cf12b EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "HASH160 0x4c 0x14 0xc286a1af0947f58d1ad787385b1c2c4a976f9e71 EQUAL"], +["''", "HASH256 0x20 0x5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456 EQUAL"], +["'a'", "HASH256 0x20 0xbf5d3affb73efd2ec6c36ad3112dd933efed63c4e1cbffcfa88e2759c144f2d8 EQUAL"], +["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL"], + + +["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL"], +["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL"], + +["0", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid if executed"], +["0", "IF 0xc0 ELSE 1 ENDIF"], +["0", "IF 0xd1 ELSE 1 ENDIF"], +["0", "IF 0xee ELSE 1 ENDIF"], +["0", "IF 0xfd ELSE 1 ENDIF"], +["0", "IF 0xff ELSE 1 ENDIF"], + +["NOP", +"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'", +"520 byte push"], +["1", +"0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +"201 opcodes executed. 0x61 is NOP"], +["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1,000 stack size (0x6f is 3DUP)"], +["1 TOALTSTACK 2 TOALTSTACK 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1 2 3 4 5 6 7 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"1,000 stack size (altstack cleared between scriptSig/scriptPubKey)"], +["'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f", +"'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", +"Max-size (10,000-byte), max-push(520 bytes), max-opcodes(201), max stack size(1,000 items). 0x6f is 3DUP, 0x61 is NOP"], + +["NOP","1"] +] diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp new file mode 100644 index 0000000..78953d2 --- /dev/null +++ b/src/test/getarg_tests.cpp @@ -0,0 +1,167 @@ +#include +#include +#include + +#include "util.h" + +BOOST_AUTO_TEST_SUITE(getarg_tests) + +static void +ResetArgs(const std::string& strArg) +{ + std::vector vecArg; + boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on); + + // Insert dummy executable name: + vecArg.insert(vecArg.begin(), "testbitcoin"); + + // Convert to char*: + std::vector vecChar; + BOOST_FOREACH(std::string& s, vecArg) + vecChar.push_back(s.c_str()); + + ParseParameters(vecChar.size(), &vecChar[0]); +} + +BOOST_AUTO_TEST_CASE(boolarg) +{ + ResetArgs("-foo"); + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + BOOST_CHECK(!GetBoolArg("-fo")); + BOOST_CHECK(!GetBoolArg("-fo", false)); + BOOST_CHECK(GetBoolArg("-fo", true)); + + BOOST_CHECK(!GetBoolArg("-fooo")); + BOOST_CHECK(!GetBoolArg("-fooo", false)); + BOOST_CHECK(GetBoolArg("-fooo", true)); + + ResetArgs("-foo=0"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + + ResetArgs("-foo=1"); + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + // New 0.6 feature: auto-map -nosomething to !-something: + ResetArgs("-nofoo"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + + ResetArgs("-nofoo=1"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + + ResetArgs("-foo -nofoo"); // -foo should win + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + ResetArgs("-foo=1 -nofoo=1"); // -foo should win + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + ResetArgs("-foo=0 -nofoo=0"); // -foo should win + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + + // New 0.6 feature: treat -- same as -: + ResetArgs("--foo=1"); + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + + ResetArgs("--nofoo=1"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); + +} + +BOOST_AUTO_TEST_CASE(stringarg) +{ + ResetArgs(""); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), "eleven"); + + ResetArgs("-foo -bar"); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), ""); + + ResetArgs("-foo="); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), ""); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), ""); + + ResetArgs("-foo=11"); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), "11"); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), "11"); + + ResetArgs("-foo=eleven"); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), "eleven"); + BOOST_CHECK_EQUAL(GetArg("-foo", "eleven"), "eleven"); + +} + +BOOST_AUTO_TEST_CASE(intarg) +{ + ResetArgs(""); + BOOST_CHECK_EQUAL(GetArg("-foo", 11), 11); + BOOST_CHECK_EQUAL(GetArg("-foo", 0), 0); + + ResetArgs("-foo -bar"); + BOOST_CHECK_EQUAL(GetArg("-foo", 11), 0); + BOOST_CHECK_EQUAL(GetArg("-bar", 11), 0); + + ResetArgs("-foo=11 -bar=12"); + BOOST_CHECK_EQUAL(GetArg("-foo", 0), 11); + BOOST_CHECK_EQUAL(GetArg("-bar", 11), 12); + + ResetArgs("-foo=NaN -bar=NotANumber"); + BOOST_CHECK_EQUAL(GetArg("-foo", 1), 0); + BOOST_CHECK_EQUAL(GetArg("-bar", 11), 0); +} + +BOOST_AUTO_TEST_CASE(doubledash) +{ + ResetArgs("--foo"); + BOOST_CHECK_EQUAL(GetBoolArg("-foo"), true); + + ResetArgs("--foo=verbose --bar=1"); + BOOST_CHECK_EQUAL(GetArg("-foo", ""), "verbose"); + BOOST_CHECK_EQUAL(GetArg("-bar", 0), 1); +} + +BOOST_AUTO_TEST_CASE(boolargno) +{ + ResetArgs("-nofoo"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!GetBoolArg("-foo", false)); + + ResetArgs("-nofoo=1"); + BOOST_CHECK(!GetBoolArg("-foo")); + BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!GetBoolArg("-foo", false)); + + ResetArgs("-nofoo=0"); + BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", true)); + BOOST_CHECK(GetBoolArg("-foo", false)); + + ResetArgs("-foo --nofoo"); + BOOST_CHECK(GetBoolArg("-foo")); + + ResetArgs("-nofoo -foo"); // foo always wins: + BOOST_CHECK(GetBoolArg("-foo")); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp new file mode 100644 index 0000000..a6e8a10 --- /dev/null +++ b/src/test/key_tests.cpp @@ -0,0 +1,147 @@ +#include + +#include +#include + +#include "key.h" +#include "base58.h" +#include "uint256.h" +#include "util.h" + +using namespace std; + +static const string strSecret1 ("6uu5bsZLA2Lm6yCxgwxDxHyZmhYeqBMLQT83Fyq738YhYucQPQf"); +static const string strSecret2 ("6vZDRwYgTNidWzmKs9x8QzQGeWCqbdUtNRpEKZMaP67ZSn8XMjb"); +static const string strSecret1C ("T6UsJv9hYpvDfM5noKYkB3vfeHxhyegkeWJ4y7qKeQJuyXMK11XX"); +static const string strSecret2C ("T9PBs5kq9QrkBPxeGNWKitMi4XuFVr25jaXTnuopLVZxCUAJbixA"); +static const CBitcoinAddress addr1 ("LWaFezDtucfCA4xcVEfs3R3xfgGWjSwcZr"); +static const CBitcoinAddress addr2 ("LXwHM6mRd432EzLJYwuKQMPhTzrgr7ur9K"); +static const CBitcoinAddress addr1C("LZWK8h7C166niP6GmpUmiGrvn4oxPqQgFV"); +static const CBitcoinAddress addr2C("Lgb6tdqmdW3n5E12johSuEAqRMt4kAr7yu"); + + +static const string strAddressBad("LRjyUS2uuieEPkhZNdQz8hE5YycxVEqSXA"); + + +#ifdef KEY_TESTS_DUMPINFO +void dumpKeyInfo(uint256 privkey) +{ + CSecret secret; + secret.resize(32); + memcpy(&secret[0], &privkey, 32); + vector sec; + sec.resize(32); + memcpy(&sec[0], &secret[0], 32); + printf(" * secret (hex): %s\n", HexStr(sec).c_str()); + + for (int nCompressed=0; nCompressed<2; nCompressed++) + { + bool fCompressed = nCompressed == 1; + printf(" * %s:\n", fCompressed ? "compressed" : "uncompressed"); + CBitcoinSecret bsecret; + bsecret.SetSecret(secret, fCompressed); + printf(" * secret (base58): %s\n", bsecret.ToString().c_str()); + CKey key; + key.SetSecret(secret, fCompressed); + vector vchPubKey = key.GetPubKey(); + printf(" * pubkey (hex): %s\n", HexStr(vchPubKey).c_str()); + printf(" * address (base58): %s\n", CBitcoinAddress(vchPubKey).ToString().c_str()); + } +} +#endif + + +BOOST_AUTO_TEST_SUITE(key_tests) + +BOOST_AUTO_TEST_CASE(key_test1) +{ + CBitcoinSecret bsecret1, bsecret2, bsecret1C, bsecret2C, baddress1; + BOOST_CHECK( bsecret1.SetString (strSecret1)); + BOOST_CHECK( bsecret2.SetString (strSecret2)); + BOOST_CHECK( bsecret1C.SetString(strSecret1C)); + BOOST_CHECK( bsecret2C.SetString(strSecret2C)); + BOOST_CHECK(!baddress1.SetString(strAddressBad)); + + bool fCompressed; + CSecret secret1 = bsecret1.GetSecret (fCompressed); + BOOST_CHECK(fCompressed == false); + CSecret secret2 = bsecret2.GetSecret (fCompressed); + BOOST_CHECK(fCompressed == false); + CSecret secret1C = bsecret1C.GetSecret(fCompressed); + BOOST_CHECK(fCompressed == true); + CSecret secret2C = bsecret2C.GetSecret(fCompressed); + BOOST_CHECK(fCompressed == true); + + BOOST_CHECK(secret1 == secret1C); + BOOST_CHECK(secret2 == secret2C); + + CKey key1, key2, key1C, key2C; + key1.SetSecret(secret1, false); + key2.SetSecret(secret2, false); + key1C.SetSecret(secret1, true); + key2C.SetSecret(secret2, true); + + BOOST_CHECK(addr1.Get() == CTxDestination(key1.GetPubKey().GetID())); + BOOST_CHECK(addr2.Get() == CTxDestination(key2.GetPubKey().GetID())); + BOOST_CHECK(addr1C.Get() == CTxDestination(key1C.GetPubKey().GetID())); + BOOST_CHECK(addr2C.Get() == CTxDestination(key2C.GetPubKey().GetID())); + + for (int n=0; n<16; n++) + { + string strMsg = strprintf("Very secret message %i: 11", n); + uint256 hashMsg = Hash(strMsg.begin(), strMsg.end()); + + // normal signatures + + vector sign1, sign2, sign1C, sign2C; + + BOOST_CHECK(key1.Sign (hashMsg, sign1)); + BOOST_CHECK(key2.Sign (hashMsg, sign2)); + BOOST_CHECK(key1C.Sign(hashMsg, sign1C)); + BOOST_CHECK(key2C.Sign(hashMsg, sign2C)); + + BOOST_CHECK( key1.Verify(hashMsg, sign1)); + BOOST_CHECK(!key1.Verify(hashMsg, sign2)); + BOOST_CHECK( key1.Verify(hashMsg, sign1C)); + BOOST_CHECK(!key1.Verify(hashMsg, sign2C)); + + BOOST_CHECK(!key2.Verify(hashMsg, sign1)); + BOOST_CHECK( key2.Verify(hashMsg, sign2)); + BOOST_CHECK(!key2.Verify(hashMsg, sign1C)); + BOOST_CHECK( key2.Verify(hashMsg, sign2C)); + + BOOST_CHECK( key1C.Verify(hashMsg, sign1)); + BOOST_CHECK(!key1C.Verify(hashMsg, sign2)); + BOOST_CHECK( key1C.Verify(hashMsg, sign1C)); + BOOST_CHECK(!key1C.Verify(hashMsg, sign2C)); + + BOOST_CHECK(!key2C.Verify(hashMsg, sign1)); + BOOST_CHECK( key2C.Verify(hashMsg, sign2)); + BOOST_CHECK(!key2C.Verify(hashMsg, sign1C)); + BOOST_CHECK( key2C.Verify(hashMsg, sign2C)); + + // compact signatures (with key recovery) + + vector csign1, csign2, csign1C, csign2C; + + BOOST_CHECK(key1.SignCompact (hashMsg, csign1)); + BOOST_CHECK(key2.SignCompact (hashMsg, csign2)); + BOOST_CHECK(key1C.SignCompact(hashMsg, csign1C)); + BOOST_CHECK(key2C.SignCompact(hashMsg, csign2C)); + + CKey rkey1, rkey2, rkey1C, rkey2C; + + BOOST_CHECK(rkey1.SetCompactSignature (hashMsg, csign1)); + BOOST_CHECK(rkey2.SetCompactSignature (hashMsg, csign2)); + BOOST_CHECK(rkey1C.SetCompactSignature(hashMsg, csign1C)); + BOOST_CHECK(rkey2C.SetCompactSignature(hashMsg, csign2C)); + + + BOOST_CHECK(rkey1.GetPubKey() == key1.GetPubKey()); + BOOST_CHECK(rkey2.GetPubKey() == key2.GetPubKey()); + BOOST_CHECK(rkey1C.GetPubKey() == key1C.GetPubKey()); + BOOST_CHECK(rkey2C.GetPubKey() == key2C.GetPubKey()); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp new file mode 100644 index 0000000..5712b4a --- /dev/null +++ b/src/test/miner_tests.cpp @@ -0,0 +1,36 @@ +#include + +#include "uint256.h" +#include "util.h" + +extern void SHA256Transform(void* pstate, void* pinput, const void* pinit); + +BOOST_AUTO_TEST_SUITE(miner_tests) + +BOOST_AUTO_TEST_CASE(sha256transform_equality) +{ + unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + + + // unsigned char pstate[32]; + unsigned char pinput[64]; + + int i; + + for (i = 0; i < 32; i++) { + pinput[i] = i; + pinput[i+32] = 0; + } + + uint256 hash; + + SHA256Transform(&hash, pinput, pSHA256InitState); + + BOOST_TEST_MESSAGE(hash.GetHex()); + + uint256 hash_reference("0x2df5e1c65ef9f8cde240d23cae2ec036d31a15ec64bc68f64be242b1da6631f3"); + + BOOST_CHECK(hash == hash_reference); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp new file mode 100644 index 0000000..64a6678 --- /dev/null +++ b/src/test/mruset_tests.cpp @@ -0,0 +1,90 @@ +#include + +using namespace std; + +#include "mruset.h" +#include "util.h" + +#define NUM_TESTS 16 +#define MAX_SIZE 100 + +class mrutester +{ +private: + mruset mru; + std::set set; + +public: + mrutester() { mru.max_size(MAX_SIZE); } + int size() const { return set.size(); } + + void insert(int n) + { + mru.insert(n); + set.insert(n); + BOOST_CHECK(mru == set); + } +}; + +BOOST_AUTO_TEST_SUITE(mruset_tests) + +// Test that an mruset behaves like a set, as long as no more than MAX_SIZE elements are in it +BOOST_AUTO_TEST_CASE(mruset_like_set) +{ + + for (int nTest=0; nTest mru(MAX_SIZE); + for (int nAction=0; nAction<3*MAX_SIZE; nAction++) + { + int n = GetRandInt(2 * MAX_SIZE); + mru.insert(n); + BOOST_CHECK(mru.size() <= MAX_SIZE); + } + } +} + +// 16-bit permutation function +int static permute(int n) +{ + // hexadecimals of pi; verified to be linearly independent + static const int table[16] = {0x243F, 0x6A88, 0x85A3, 0x08D3, 0x1319, 0x8A2E, 0x0370, 0x7344, + 0xA409, 0x3822, 0x299F, 0x31D0, 0x082E, 0xFA98, 0xEC4E, 0x6C89}; + + int ret = 0; + for (int bit=0; bit<16; bit++) + if (n & (1< mru(MAX_SIZE); + for (int n=0; n<10*MAX_SIZE; n++) + { + mru.insert(permute(n)); + + set tester; + for (int m=max(0,n-MAX_SIZE+1); m<=n; m++) + tester.insert(permute(m)); + + BOOST_CHECK(mru == tester); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp new file mode 100644 index 0000000..6bc5e3b --- /dev/null +++ b/src/test/multisig_tests.cpp @@ -0,0 +1,296 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "keystore.h" +#include "main.h" +#include "script.h" +#include "wallet.h" + +using namespace std; +using namespace boost::assign; + +typedef vector valtype; + +extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType); + +BOOST_AUTO_TEST_SUITE(multisig_tests) + +CScript +sign_multisig(CScript scriptPubKey, vector keys, CTransaction transaction, int whichIn) +{ + uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL); + + CScript result; + result << OP_0; // CHECKMULTISIG bug workaround + BOOST_FOREACH(CKey key, keys) + { + vector vchSig; + BOOST_CHECK(key.Sign(hash, vchSig)); + vchSig.push_back((unsigned char)SIGHASH_ALL); + result << vchSig; + } + return result; +} + +BOOST_AUTO_TEST_CASE(multisig_verify) +{ + CKey key[4]; + for (int i = 0; i < 4; i++) + key[i].MakeNewKey(true); + + CScript a_and_b; + a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CScript a_or_b; + a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CScript escrow; + escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + + CTransaction txFrom; // Funding transaction + txFrom.vout.resize(3); + txFrom.vout[0].scriptPubKey = a_and_b; + txFrom.vout[1].scriptPubKey = a_or_b; + txFrom.vout[2].scriptPubKey = escrow; + + CTransaction txTo[3]; // Spending transaction + for (int i = 0; i < 3; i++) + { + txTo[i].vin.resize(1); + txTo[i].vout.resize(1); + txTo[i].vin[0].prevout.n = i; + txTo[i].vin[0].prevout.hash = txFrom.GetHash(); + txTo[i].vout[0].nValue = 1; + } + + vector keys; + CScript s; + + // Test a AND b: + keys.clear(); + keys += key[0],key[1]; // magic operator+= from boost.assign + s = sign_multisig(a_and_b, keys, txTo[0], 0); + BOOST_CHECK(VerifyScript(s, a_and_b, txTo[0], 0, true, 0)); + + for (int i = 0; i < 4; i++) + { + keys.clear(); + keys += key[i]; + s = sign_multisig(a_and_b, keys, txTo[0], 0); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, true, 0), strprintf("a&b 1: %d", i)); + + keys.clear(); + keys += key[1],key[i]; + s = sign_multisig(a_and_b, keys, txTo[0], 0); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, true, 0), strprintf("a&b 2: %d", i)); + } + + // Test a OR b: + for (int i = 0; i < 4; i++) + { + keys.clear(); + keys += key[i]; + s = sign_multisig(a_or_b, keys, txTo[1], 0); + if (i == 0 || i == 1) + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, txTo[1], 0, true, 0), strprintf("a|b: %d", i)); + else + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, txTo[1], 0, true, 0), strprintf("a|b: %d", i)); + } + s.clear(); + s << OP_0 << OP_0; + BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, true, 0)); + s.clear(); + s << OP_0 << OP_1; + BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, true, 0)); + + + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + { + keys.clear(); + keys += key[i],key[j]; + s = sign_multisig(escrow, keys, txTo[2], 0); + if (i < j && i < 3 && j < 3) + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, txTo[2], 0, true, 0), strprintf("escrow 1: %d %d", i, j)); + else + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, txTo[2], 0, true, 0), strprintf("escrow 2: %d %d", i, j)); + } +} + +BOOST_AUTO_TEST_CASE(multisig_IsStandard) +{ + CKey key[4]; + for (int i = 0; i < 4; i++) + key[i].MakeNewKey(true); + + CScript a_and_b; + a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK(::IsStandard(a_and_b)); + + CScript a_or_b; + a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK(::IsStandard(a_or_b)); + + CScript escrow; + escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + BOOST_CHECK(::IsStandard(escrow)); + + CScript one_of_four; + one_of_four << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << key[3].GetPubKey() << OP_4 << OP_CHECKMULTISIG; + BOOST_CHECK(!::IsStandard(one_of_four)); + + CScript malformed[6]; + malformed[0] << OP_3 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + malformed[1] << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + malformed[2] << OP_0 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + malformed[3] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_0 << OP_CHECKMULTISIG; + malformed[4] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_CHECKMULTISIG; + malformed[5] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey(); + + for (int i = 0; i < 6; i++) + BOOST_CHECK(!::IsStandard(malformed[i])); +} + +BOOST_AUTO_TEST_CASE(multisig_Solver1) +{ + // Tests Solver() that returns lists of keys that are + // required to satisfy a ScriptPubKey + // + // Also tests IsMine() and ExtractAddress() + // + // Note: ExtractAddress for the multisignature transactions + // always returns false for this release, even if you have + // one key that would satisfy an (a|b) or 2-of-3 keys needed + // to spend an escrow transaction. + // + CBasicKeyStore keystore, emptykeystore, partialkeystore; + CKey key[3]; + CTxDestination keyaddr[3]; + for (int i = 0; i < 3; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + keyaddr[i] = key[i].GetPubKey().GetID(); + } + partialkeystore.AddKey(key[0]); + + { + vector solutions; + txnouttype whichType; + CScript s; + s << key[0].GetPubKey() << OP_CHECKSIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK(solutions.size() == 1); + CTxDestination addr; + BOOST_CHECK(ExtractDestination(s, addr)); + BOOST_CHECK(addr == keyaddr[0]); + BOOST_CHECK(IsMine(keystore, s)); + BOOST_CHECK(!IsMine(emptykeystore, s)); + } + { + vector solutions; + txnouttype whichType; + CScript s; + s << OP_DUP << OP_HASH160 << key[0].GetPubKey().GetID() << OP_EQUALVERIFY << OP_CHECKSIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK(solutions.size() == 1); + CTxDestination addr; + BOOST_CHECK(ExtractDestination(s, addr)); + BOOST_CHECK(addr == keyaddr[0]); + BOOST_CHECK(IsMine(keystore, s)); + BOOST_CHECK(!IsMine(emptykeystore, s)); + } + { + vector solutions; + txnouttype whichType; + CScript s; + s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(solutions.size(), 4); + CTxDestination addr; + BOOST_CHECK(!ExtractDestination(s, addr)); + BOOST_CHECK(IsMine(keystore, s)); + BOOST_CHECK(!IsMine(emptykeystore, s)); + BOOST_CHECK(!IsMine(partialkeystore, s)); + } + { + vector solutions; + txnouttype whichType; + CScript s; + s << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK_EQUAL(solutions.size(), 4); + vector addrs; + int nRequired; + BOOST_CHECK(ExtractDestinations(s, whichType, addrs, nRequired)); + BOOST_CHECK(addrs[0] == keyaddr[0]); + BOOST_CHECK(addrs[1] == keyaddr[1]); + BOOST_CHECK(nRequired == 1); + BOOST_CHECK(IsMine(keystore, s)); + BOOST_CHECK(!IsMine(emptykeystore, s)); + BOOST_CHECK(!IsMine(partialkeystore, s)); + } + { + vector solutions; + txnouttype whichType; + CScript s; + s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + BOOST_CHECK(Solver(s, whichType, solutions)); + BOOST_CHECK(solutions.size() == 5); + } +} + +BOOST_AUTO_TEST_CASE(multisig_Sign) +{ + // Test SignSignature() (and therefore the version of Solver() that signs transactions) + CBasicKeyStore keystore; + CKey key[4]; + for (int i = 0; i < 4; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + } + + CScript a_and_b; + a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CScript a_or_b; + a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CScript escrow; + escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + + CTransaction txFrom; // Funding transaction + txFrom.vout.resize(3); + txFrom.vout[0].scriptPubKey = a_and_b; + txFrom.vout[1].scriptPubKey = a_or_b; + txFrom.vout[2].scriptPubKey = escrow; + + CTransaction txTo[3]; // Spending transaction + for (int i = 0; i < 3; i++) + { + txTo[i].vin.resize(1); + txTo[i].vout.resize(1); + txTo[i].vin[0].prevout.n = i; + txTo[i].vin[0].prevout.hash = txFrom.GetHash(); + txTo[i].vout[0].nValue = 1; + } + + for (int i = 0; i < 3; i++) + { + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + } +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp new file mode 100644 index 0000000..502369c --- /dev/null +++ b/src/test/netbase_tests.cpp @@ -0,0 +1,102 @@ +#include + +#include +#include + +#include "netbase.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(netbase_tests) + +BOOST_AUTO_TEST_CASE(netbase_networks) +{ + BOOST_CHECK(CNetAddr("127.0.0.1").GetNetwork() == NET_UNROUTABLE); + BOOST_CHECK(CNetAddr("::1").GetNetwork() == NET_UNROUTABLE); + BOOST_CHECK(CNetAddr("8.8.8.8").GetNetwork() == NET_IPV4); + BOOST_CHECK(CNetAddr("2001::8888").GetNetwork() == NET_IPV6); + BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_TOR); +} + +BOOST_AUTO_TEST_CASE(netbase_properties) +{ + BOOST_CHECK(CNetAddr("127.0.0.1").IsIPv4()); + BOOST_CHECK(CNetAddr("::FFFF:192.168.1.1").IsIPv4()); + BOOST_CHECK(CNetAddr("::1").IsIPv6()); + BOOST_CHECK(CNetAddr("10.0.0.1").IsRFC1918()); + BOOST_CHECK(CNetAddr("192.168.1.1").IsRFC1918()); + BOOST_CHECK(CNetAddr("172.31.255.255").IsRFC1918()); + BOOST_CHECK(CNetAddr("2001:0DB8::").IsRFC3849()); + BOOST_CHECK(CNetAddr("169.254.1.1").IsRFC3927()); + BOOST_CHECK(CNetAddr("2002::1").IsRFC3964()); + BOOST_CHECK(CNetAddr("FC00::").IsRFC4193()); + BOOST_CHECK(CNetAddr("2001::2").IsRFC4380()); + BOOST_CHECK(CNetAddr("2001:10::").IsRFC4843()); + BOOST_CHECK(CNetAddr("FE80::").IsRFC4862()); + BOOST_CHECK(CNetAddr("64:FF9B::").IsRFC6052()); + BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor()); + BOOST_CHECK(CNetAddr("127.0.0.1").IsLocal()); + BOOST_CHECK(CNetAddr("::1").IsLocal()); + BOOST_CHECK(CNetAddr("8.8.8.8").IsRoutable()); + BOOST_CHECK(CNetAddr("2001::1").IsRoutable()); + BOOST_CHECK(CNetAddr("127.0.0.1").IsValid()); +} + +bool static TestSplitHost(string test, string host, int port) +{ + string hostOut; + int portOut = -1; + SplitHostPort(test, portOut, hostOut); + return hostOut == host && port == portOut; +} + +BOOST_AUTO_TEST_CASE(netbase_splithost) +{ + BOOST_CHECK(TestSplitHost("www.casinocoin.org", "www.casinocoin.org", -1)); + BOOST_CHECK(TestSplitHost("[www.casinocoin.org]", "www.casinocoin.org", -1)); + BOOST_CHECK(TestSplitHost("www.casinocoin.org:80", "www.casinocoin.org", 80)); + BOOST_CHECK(TestSplitHost("[www.casinocoin.org]:80", "www.casinocoin.org", 80)); + BOOST_CHECK(TestSplitHost("127.0.0.1", "127.0.0.1", -1)); + BOOST_CHECK(TestSplitHost("127.0.0.1:8333", "127.0.0.1", 8333)); + BOOST_CHECK(TestSplitHost("[127.0.0.1]", "127.0.0.1", -1)); + BOOST_CHECK(TestSplitHost("[127.0.0.1]:8333", "127.0.0.1", 8333)); + BOOST_CHECK(TestSplitHost("::ffff:127.0.0.1", "::ffff:127.0.0.1", -1)); + BOOST_CHECK(TestSplitHost("[::ffff:127.0.0.1]:8333", "::ffff:127.0.0.1", 8333)); + BOOST_CHECK(TestSplitHost("[::]:8333", "::", 8333)); + BOOST_CHECK(TestSplitHost("::8333", "::8333", -1)); + BOOST_CHECK(TestSplitHost(":8333", "", 8333)); + BOOST_CHECK(TestSplitHost("[]:8333", "", 8333)); + BOOST_CHECK(TestSplitHost("", "", -1)); +} + +bool static TestParse(string src, string canon) +{ + CService addr; + if (!LookupNumeric(src.c_str(), addr, 65535)) + return canon == ""; + return canon == addr.ToString(); +} + +BOOST_AUTO_TEST_CASE(netbase_lookupnumeric) +{ + BOOST_CHECK(TestParse("127.0.0.1", "127.0.0.1:65535")); + BOOST_CHECK(TestParse("127.0.0.1:8333", "127.0.0.1:8333")); + BOOST_CHECK(TestParse("::ffff:127.0.0.1", "127.0.0.1:65535")); + BOOST_CHECK(TestParse("::", "[::]:65535")); + BOOST_CHECK(TestParse("[::]:8333", "[::]:8333")); + BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535")); + BOOST_CHECK(TestParse(":::", "")); +} + +BOOST_AUTO_TEST_CASE(onioncat_test) +{ + // values from http://www.cypherpunk.at/onioncat/wiki/OnionCat + CNetAddr addr1("5wyqrzbvrdsumnok.onion"); + CNetAddr addr2("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca"); + BOOST_CHECK(addr1 == addr2); + BOOST_CHECK(addr1.IsTor()); + BOOST_CHECK(addr1.ToStringIP() == "5wyqrzbvrdsumnok.onion"); + BOOST_CHECK(addr1.IsRoutable()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp new file mode 100644 index 0000000..e6c00e3 --- /dev/null +++ b/src/test/rpc_tests.cpp @@ -0,0 +1,69 @@ +#include +#include + +#include "base58.h" +#include "util.h" +#include "bitcoinrpc.h" + +using namespace std; +using namespace json_spirit; + +BOOST_AUTO_TEST_SUITE(rpc_tests) + +static Array +createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) +{ + Array result; + result.push_back(nRequired); + Array addresses; + if (address1) addresses.push_back(address1); + if (address2) addresses.push_back(address1); + result.push_back(addresses); + return result; +} + +// This can be removed this when addmultisigaddress is enabled on main net: +struct TestNetFixture +{ + TestNetFixture() { fTestNet = true; } + ~TestNetFixture() { fTestNet = false; } +}; + +BOOST_FIXTURE_TEST_CASE(rpc_addmultisig, TestNetFixture) +{ + rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor; + + // old, 65-byte-long: + const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8"; + // new, compressed: + const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; + + Value v; + CBitcoinAddress address; + BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); + address.SetString(v.get_str()); + BOOST_CHECK(address.IsValid() && address.IsScript()); + + BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false)); + address.SetString(v.get_str()); + BOOST_CHECK(address.IsValid() && address.IsScript()); + + BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false)); + address.SetString(v.get_str()); + BOOST_CHECK(address.IsValid() && address.IsScript()); + + BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error); + BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error); + BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error); + + BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error); + BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error); + + string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing + BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error); + + string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing + BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp new file mode 100644 index 0000000..f7bf5df --- /dev/null +++ b/src/test/script_P2SH_tests.cpp @@ -0,0 +1,330 @@ +#include +#include +#include +#include +#include +#include + +#include "../main.h" +#include "../script.h" +#include "../wallet.h" + +using namespace std; + +// Test routines internal to script.cpp: +extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType); + +// Helpers: +static std::vector +Serialize(const CScript& s) +{ + std::vector sSerialized(s); + return sSerialized; +} + +static bool +Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict) +{ + // Create dummy to/from transactions: + CTransaction txFrom; + txFrom.vout.resize(1); + txFrom.vout[0].scriptPubKey = scriptPubKey; + + CTransaction txTo; + txTo.vin.resize(1); + txTo.vout.resize(1); + txTo.vin[0].prevout.n = 0; + txTo.vin[0].prevout.hash = txFrom.GetHash(); + txTo.vin[0].scriptSig = scriptSig; + txTo.vout[0].nValue = 1; + + return VerifyScript(scriptSig, scriptPubKey, txTo, 0, fStrict, 0); +} + + +BOOST_AUTO_TEST_SUITE(script_P2SH_tests) + +BOOST_AUTO_TEST_CASE(sign) +{ + // Pay-to-script-hash looks like this: + // scriptSig: + // scriptPubKey: HASH160 EQUAL + + // Test SignSignature() (and therefore the version of Solver() that signs transactions) + CBasicKeyStore keystore; + CKey key[4]; + for (int i = 0; i < 4; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + } + + // 8 Scripts: checking all combinations of + // different keys, straight/P2SH, pubkey/pubkeyhash + CScript standardScripts[4]; + standardScripts[0] << key[0].GetPubKey() << OP_CHECKSIG; + standardScripts[1].SetDestination(key[1].GetPubKey().GetID()); + standardScripts[2] << key[1].GetPubKey() << OP_CHECKSIG; + standardScripts[3].SetDestination(key[2].GetPubKey().GetID()); + CScript evalScripts[4]; + for (int i = 0; i < 4; i++) + { + keystore.AddCScript(standardScripts[i]); + evalScripts[i].SetDestination(standardScripts[i].GetID()); + } + + CTransaction txFrom; // Funding transaction: + txFrom.vout.resize(8); + for (int i = 0; i < 4; i++) + { + txFrom.vout[i].scriptPubKey = evalScripts[i]; + txFrom.vout[i+4].scriptPubKey = standardScripts[i]; + } + BOOST_CHECK(txFrom.IsStandard()); + + CTransaction txTo[8]; // Spending transactions + for (int i = 0; i < 8; i++) + { + txTo[i].vin.resize(1); + txTo[i].vout.resize(1); + txTo[i].vin[0].prevout.n = i; + txTo[i].vin[0].prevout.hash = txFrom.GetHash(); + txTo[i].vout[0].nValue = 1; + BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); + } + for (int i = 0; i < 8; i++) + { + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + } + // All of the above should be OK, and the txTos have valid signatures + // Check to make sure signature verification fails if we use the wrong ScriptSig: + for (int i = 0; i < 8; i++) + for (int j = 0; j < 8; j++) + { + CScript sigSave = txTo[i].vin[0].scriptSig; + txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; + bool sigOK = VerifySignature(txFrom, txTo[i], 0, true, 0); + if (i == j) + BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); + else + BOOST_CHECK_MESSAGE(!sigOK, strprintf("VerifySignature %d %d", i, j)); + txTo[i].vin[0].scriptSig = sigSave; + } +} + +BOOST_AUTO_TEST_CASE(norecurse) +{ + // Make sure only the outer pay-to-script-hash does the + // extra-validation thing: + CScript invalidAsScript; + invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE; + + CScript p2sh; + p2sh.SetDestination(invalidAsScript.GetID()); + + CScript scriptSig; + scriptSig << Serialize(invalidAsScript); + + // Should not verify, because it will try to execute OP_INVALIDOPCODE + BOOST_CHECK(!Verify(scriptSig, p2sh, true)); + + // Try to recurse, and verification should succeed because + // the inner HASH160 <> EQUAL should only check the hash: + CScript p2sh2; + p2sh2.SetDestination(p2sh.GetID()); + CScript scriptSig2; + scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh); + + BOOST_CHECK(Verify(scriptSig2, p2sh2, true)); +} + +BOOST_AUTO_TEST_CASE(set) +{ + // Test the CScript::Set* methods + CBasicKeyStore keystore; + CKey key[4]; + std::vector keys; + for (int i = 0; i < 4; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + keys.push_back(key[i]); + } + + CScript inner[4]; + inner[0].SetDestination(key[0].GetPubKey().GetID()); + inner[1].SetMultisig(2, std::vector(keys.begin(), keys.begin()+2)); + inner[2].SetMultisig(1, std::vector(keys.begin(), keys.begin()+2)); + inner[3].SetMultisig(2, std::vector(keys.begin(), keys.begin()+3)); + + CScript outer[4]; + for (int i = 0; i < 4; i++) + { + outer[i].SetDestination(inner[i].GetID()); + keystore.AddCScript(inner[i]); + } + + CTransaction txFrom; // Funding transaction: + txFrom.vout.resize(4); + for (int i = 0; i < 4; i++) + { + txFrom.vout[i].scriptPubKey = outer[i]; + } + BOOST_CHECK(txFrom.IsStandard()); + + CTransaction txTo[4]; // Spending transactions + for (int i = 0; i < 4; i++) + { + txTo[i].vin.resize(1); + txTo[i].vout.resize(1); + txTo[i].vin[0].prevout.n = i; + txTo[i].vin[0].prevout.hash = txFrom.GetHash(); + txTo[i].vout[0].nValue = 1; + txTo[i].vout[0].scriptPubKey = inner[i]; + BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); + } + for (int i = 0; i < 4; i++) + { + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + BOOST_CHECK_MESSAGE(txTo[i].IsStandard(), strprintf("txTo[%d].IsStandard", i)); + } +} + +BOOST_AUTO_TEST_CASE(is) +{ + // Test CScript::IsPayToScriptHash() + uint160 dummy; + CScript p2sh; + p2sh << OP_HASH160 << dummy << OP_EQUAL; + BOOST_CHECK(p2sh.IsPayToScriptHash()); + + // Not considered pay-to-script-hash if using one of the OP_PUSHDATA opcodes: + static const unsigned char direct[] = { OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL }; + BOOST_CHECK(CScript(direct, direct+sizeof(direct)).IsPayToScriptHash()); + static const unsigned char pushdata1[] = { OP_HASH160, OP_PUSHDATA1, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL }; + BOOST_CHECK(!CScript(pushdata1, pushdata1+sizeof(pushdata1)).IsPayToScriptHash()); + static const unsigned char pushdata2[] = { OP_HASH160, OP_PUSHDATA2, 20,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL }; + BOOST_CHECK(!CScript(pushdata2, pushdata2+sizeof(pushdata2)).IsPayToScriptHash()); + static const unsigned char pushdata4[] = { OP_HASH160, OP_PUSHDATA4, 20,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL }; + BOOST_CHECK(!CScript(pushdata4, pushdata4+sizeof(pushdata4)).IsPayToScriptHash()); + + CScript not_p2sh; + BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); + + not_p2sh.clear(); not_p2sh << OP_HASH160 << dummy << dummy << OP_EQUAL; + BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); + + not_p2sh.clear(); not_p2sh << OP_NOP << dummy << OP_EQUAL; + BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); + + not_p2sh.clear(); not_p2sh << OP_HASH160 << dummy << OP_CHECKSIG; + BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); +} + +BOOST_AUTO_TEST_CASE(switchover) +{ + // Test switchover code + CScript notValid; + notValid << OP_11 << OP_12 << OP_EQUALVERIFY; + CScript scriptSig; + scriptSig << Serialize(notValid); + + CScript fund; + fund.SetDestination(notValid.GetID()); + + + // Validation should succeed under old rules (hash is correct): + BOOST_CHECK(Verify(scriptSig, fund, false)); + // Fail under new: + BOOST_CHECK(!Verify(scriptSig, fund, true)); +} + +BOOST_AUTO_TEST_CASE(AreInputsStandard) +{ + std::map > mapInputs; + CBasicKeyStore keystore; + CKey key[3]; + vector keys; + for (int i = 0; i < 3; i++) + { + key[i].MakeNewKey(true); + keystore.AddKey(key[i]); + keys.push_back(key[i]); + } + + CTransaction txFrom; + txFrom.vout.resize(6); + + // First three are standard: + CScript pay1; pay1.SetDestination(key[0].GetPubKey().GetID()); + keystore.AddCScript(pay1); + CScript payScriptHash1; payScriptHash1.SetDestination(pay1.GetID()); + CScript pay1of3; pay1of3.SetMultisig(1, keys); + + txFrom.vout[0].scriptPubKey = payScriptHash1; + txFrom.vout[1].scriptPubKey = pay1; + txFrom.vout[2].scriptPubKey = pay1of3; + + // Last three non-standard: + CScript empty; + keystore.AddCScript(empty); + txFrom.vout[3].scriptPubKey = empty; + // Can't use SetPayToScriptHash, it checks for the empty Script. So: + txFrom.vout[4].scriptPubKey << OP_HASH160 << Hash160(empty) << OP_EQUAL; + CScript oneOfEleven; + oneOfEleven << OP_1; + for (int i = 0; i < 11; i++) + oneOfEleven << key[0].GetPubKey(); + oneOfEleven << OP_11 << OP_CHECKMULTISIG; + txFrom.vout[5].scriptPubKey.SetDestination(oneOfEleven.GetID()); + + mapInputs[txFrom.GetHash()] = make_pair(CTxIndex(), txFrom); + + CTransaction txTo; + txTo.vout.resize(1); + txTo.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID()); + + txTo.vin.resize(3); + txTo.vin[0].prevout.n = 0; + txTo.vin[0].prevout.hash = txFrom.GetHash(); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0)); + txTo.vin[1].prevout.n = 1; + txTo.vin[1].prevout.hash = txFrom.GetHash(); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1)); + txTo.vin[2].prevout.n = 2; + txTo.vin[2].prevout.hash = txFrom.GetHash(); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2)); + + BOOST_CHECK(txTo.AreInputsStandard(mapInputs)); + BOOST_CHECK_EQUAL(txTo.GetP2SHSigOpCount(mapInputs), 1); + + // Make sure adding crap to the scriptSigs makes them non-standard: + for (int i = 0; i < 3; i++) + { + CScript t = txTo.vin[i].scriptSig; + txTo.vin[i].scriptSig = (CScript() << 11) + t; + BOOST_CHECK(!txTo.AreInputsStandard(mapInputs)); + txTo.vin[i].scriptSig = t; + } + + CTransaction txToNonStd; + txToNonStd.vout.resize(1); + txToNonStd.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID()); + txToNonStd.vin.resize(2); + txToNonStd.vin[0].prevout.n = 4; + txToNonStd.vin[0].prevout.hash = txFrom.GetHash(); + txToNonStd.vin[0].scriptSig << Serialize(empty); + txToNonStd.vin[1].prevout.n = 5; + txToNonStd.vin[1].prevout.hash = txFrom.GetHash(); + txToNonStd.vin[1].scriptSig << OP_0 << Serialize(oneOfEleven); + + BOOST_CHECK(!txToNonStd.AreInputsStandard(mapInputs)); + BOOST_CHECK_EQUAL(txToNonStd.GetP2SHSigOpCount(mapInputs), 11); + + txToNonStd.vin[0].scriptSig.clear(); + BOOST_CHECK(!txToNonStd.AreInputsStandard(mapInputs)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp new file mode 100644 index 0000000..61d9a64 --- /dev/null +++ b/src/test/script_tests.cpp @@ -0,0 +1,445 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" + +#include "main.h" +#include "wallet.h" + +using namespace std; +using namespace json_spirit; +using namespace boost::algorithm; + +extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, + bool fValidatePayToScriptHash, int nHashType); + +CScript +ParseScript(string s) +{ + CScript result; + + static map mapOpNames; + + if (mapOpNames.size() == 0) + { + for (int op = OP_NOP; op <= OP_NOP10; op++) + { + const char* name = GetOpName((opcodetype)op); + if (strcmp(name, "OP_UNKNOWN") == 0) + continue; + string strName(name); + mapOpNames[strName] = (opcodetype)op; + // Convenience: OP_ADD and just ADD are both recognized: + replace_first(strName, "OP_", ""); + mapOpNames[strName] = (opcodetype)op; + } + } + + vector words; + split(words, s, is_any_of(" \t\n"), token_compress_on); + + BOOST_FOREACH(string w, words) + { + if (all(w, is_digit()) || + (starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit()))) + { + // Number + int64 n = atoi64(w); + result << n; + } + else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end()))) + { + // Raw hex data, inserted NOT pushed onto stack: + std::vector raw = ParseHex(string(w.begin()+2, w.end())); + result.insert(result.end(), raw.begin(), raw.end()); + } + else if (w.size() >= 2 && starts_with(w, "'") && ends_with(w, "'")) + { + // Single-quoted string, pushed as data. NOTE: this is poor-man's + // parsing, spaces/tabs/newlines in single-quoted strings won't work. + std::vector value(w.begin()+1, w.end()-1); + result << value; + } + else if (mapOpNames.count(w)) + { + // opcode, e.g. OP_ADD or OP_1: + result << mapOpNames[w]; + } + else + { + BOOST_ERROR("Parse error: " << s); + return CScript(); + } + } + + return result; +} + +Array +read_json(const std::string& filename) +{ + namespace fs = boost::filesystem; + fs::path testFile = fs::current_path() / "test" / "data" / filename; + +#ifdef TEST_DATA_DIR + if (!fs::exists(testFile)) + { + testFile = fs::path(BOOST_PP_STRINGIZE(TEST_DATA_DIR)) / filename; + } +#endif + + ifstream ifs(testFile.string().c_str(), ifstream::in); + Value v; + if (!read_stream(ifs, v)) + { + if (ifs.fail()) + BOOST_ERROR("Cound not find/open " << filename); + else + BOOST_ERROR("JSON syntax error in " << filename); + return Array(); + } + if (v.type() != array_type) + { + BOOST_ERROR(filename << " does not contain a json array"); + return Array(); + } + + return v.get_array(); +} + +BOOST_AUTO_TEST_SUITE(script_tests) + +BOOST_AUTO_TEST_CASE(script_valid) +{ + // Read tests from test/data/script_valid.json + // Format is an array of arrays + // Inner arrays are [ "scriptSig", "scriptPubKey" ] + // ... where scriptSig and scriptPubKey are stringified + // scripts. + Array tests = read_json("script_valid.json"); + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + string strTest = write_string(tv, false); + if (test.size() < 2) // Allow size > 2; extra stuff ignored (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + string scriptSigString = test[0].get_str(); + CScript scriptSig = ParseScript(scriptSigString); + string scriptPubKeyString = test[1].get_str(); + CScript scriptPubKey = ParseScript(scriptPubKeyString); + + CTransaction tx; + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, tx, 0, true, SIGHASH_NONE), strTest); + } +} + +BOOST_AUTO_TEST_CASE(script_invalid) +{ + // Scripts that should evaluate as invalid + Array tests = read_json("script_invalid.json"); + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + string strTest = write_string(tv, false); + if (test.size() < 2) // Allow size > 2; extra stuff ignored (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + string scriptSigString = test[0].get_str(); + CScript scriptSig = ParseScript(scriptSigString); + string scriptPubKeyString = test[1].get_str(); + CScript scriptPubKey = ParseScript(scriptPubKeyString); + + CTransaction tx; + BOOST_CHECK_MESSAGE(!VerifyScript(scriptSig, scriptPubKey, tx, 0, true, SIGHASH_NONE), strTest); + } +} + +BOOST_AUTO_TEST_CASE(script_PushData) +{ + // Check that PUSHDATA1, PUSHDATA2, and PUSHDATA4 create the same value on + // the stack as the 1-75 opcodes do. + static const unsigned char direct[] = { 1, 0x5a }; + static const unsigned char pushdata1[] = { OP_PUSHDATA1, 1, 0x5a }; + static const unsigned char pushdata2[] = { OP_PUSHDATA2, 1, 0, 0x5a }; + static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a }; + + vector > directStack; + BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), CTransaction(), 0, 0)); + + vector > pushdata1Stack; + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), CTransaction(), 0, 0)); + BOOST_CHECK(pushdata1Stack == directStack); + + vector > pushdata2Stack; + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), CTransaction(), 0, 0)); + BOOST_CHECK(pushdata2Stack == directStack); + + vector > pushdata4Stack; + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), CTransaction(), 0, 0)); + BOOST_CHECK(pushdata4Stack == directStack); +} + +CScript +sign_multisig(CScript scriptPubKey, std::vector keys, CTransaction transaction) +{ + uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL); + + CScript result; + // + // NOTE: CHECKMULTISIG has an unfortunate bug; it requires + // one extra item on the stack, before the signatures. + // Putting OP_0 on the stack is the workaround; + // fixing the bug would mean splitting the blockchain (old + // clients would not accept new CHECKMULTISIG transactions, + // and vice-versa) + // + result << OP_0; + BOOST_FOREACH(CKey key, keys) + { + vector vchSig; + BOOST_CHECK(key.Sign(hash, vchSig)); + vchSig.push_back((unsigned char)SIGHASH_ALL); + result << vchSig; + } + return result; +} +CScript +sign_multisig(CScript scriptPubKey, CKey key, CTransaction transaction) +{ + std::vector keys; + keys.push_back(key); + return sign_multisig(scriptPubKey, keys, transaction); +} + +BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) +{ + CKey key1, key2, key3; + key1.MakeNewKey(true); + key2.MakeNewKey(false); + key3.MakeNewKey(true); + + CScript scriptPubKey12; + scriptPubKey12 << OP_1 << key1.GetPubKey() << key2.GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CTransaction txFrom12; + txFrom12.vout.resize(1); + txFrom12.vout[0].scriptPubKey = scriptPubKey12; + + CTransaction txTo12; + txTo12.vin.resize(1); + txTo12.vout.resize(1); + txTo12.vin[0].prevout.n = 0; + txTo12.vin[0].prevout.hash = txFrom12.GetHash(); + txTo12.vout[0].nValue = 1; + + CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, true, 0)); + txTo12.vout[0].nValue = 2; + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, true, 0)); + + CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, true, 0)); + + CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, true, 0)); +} + +BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) +{ + CKey key1, key2, key3, key4; + key1.MakeNewKey(true); + key2.MakeNewKey(false); + key3.MakeNewKey(true); + key4.MakeNewKey(false); + + CScript scriptPubKey23; + scriptPubKey23 << OP_2 << key1.GetPubKey() << key2.GetPubKey() << key3.GetPubKey() << OP_3 << OP_CHECKMULTISIG; + + CTransaction txFrom23; + txFrom23.vout.resize(1); + txFrom23.vout[0].scriptPubKey = scriptPubKey23; + + CTransaction txTo23; + txTo23.vin.resize(1); + txTo23.vout.resize(1); + txTo23.vin[0].prevout.n = 0; + txTo23.vin[0].prevout.hash = txFrom23.GetHash(); + txTo23.vout[0].nValue = 1; + + std::vector keys; + keys.push_back(key1); keys.push_back(key2); + CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key1); keys.push_back(key3); + CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key2); keys.push_back(key3); + CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key2); keys.push_back(key2); // Can't re-use sig + CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order + CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order + CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys + CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); + keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys + CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, true, 0)); + + keys.clear(); // Must have signatures + CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, true, 0)); +} + +BOOST_AUTO_TEST_CASE(script_combineSigs) +{ + // Test the CombineSignatures function + CBasicKeyStore keystore; + vector keys; + for (int i = 0; i < 3; i++) + { + CKey key; + key.MakeNewKey(i%2 == 1); + keys.push_back(key); + keystore.AddKey(key); + } + + CTransaction txFrom; + txFrom.vout.resize(1); + txFrom.vout[0].scriptPubKey.SetDestination(keys[0].GetPubKey().GetID()); + CScript& scriptPubKey = txFrom.vout[0].scriptPubKey; + CTransaction txTo; + txTo.vin.resize(1); + txTo.vout.resize(1); + txTo.vin[0].prevout.n = 0; + txTo.vin[0].prevout.hash = txFrom.GetHash(); + CScript& scriptSig = txTo.vin[0].scriptSig; + txTo.vout[0].nValue = 1; + + CScript empty; + CScript combined = CombineSignatures(scriptPubKey, txTo, 0, empty, empty); + BOOST_CHECK(combined.empty()); + + // Single signature case: + SignSignature(keystore, txFrom, txTo, 0); // changes scriptSig + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); + BOOST_CHECK(combined == scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); + BOOST_CHECK(combined == scriptSig); + CScript scriptSigCopy = scriptSig; + // Signing again will give a different, valid signature: + SignSignature(keystore, txFrom, txTo, 0); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); + BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); + + // P2SH, single-signature case: + CScript pkSingle; pkSingle << keys[0].GetPubKey() << OP_CHECKSIG; + keystore.AddCScript(pkSingle); + scriptPubKey.SetDestination(pkSingle.GetID()); + SignSignature(keystore, txFrom, txTo, 0); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); + BOOST_CHECK(combined == scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); + BOOST_CHECK(combined == scriptSig); + scriptSigCopy = scriptSig; + SignSignature(keystore, txFrom, txTo, 0); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); + BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); + // dummy scriptSigCopy with placeholder, should always choose non-placeholder: + scriptSigCopy = CScript() << OP_0 << static_cast >(pkSingle); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); + BOOST_CHECK(combined == scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy); + BOOST_CHECK(combined == scriptSig); + + // Hardest case: Multisig 2-of-3 + scriptPubKey.SetMultisig(2, keys); + keystore.AddCScript(scriptPubKey); + SignSignature(keystore, txFrom, txTo, 0); + combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); + BOOST_CHECK(combined == scriptSig); + combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); + BOOST_CHECK(combined == scriptSig); + + // A couple of partially-signed versions: + vector sig1; + uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL); + BOOST_CHECK(keys[0].Sign(hash1, sig1)); + sig1.push_back(SIGHASH_ALL); + vector sig2; + uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE); + BOOST_CHECK(keys[1].Sign(hash2, sig2)); + sig2.push_back(SIGHASH_NONE); + vector sig3; + uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE); + BOOST_CHECK(keys[2].Sign(hash3, sig3)); + sig3.push_back(SIGHASH_SINGLE); + + // Not fussy about order (or even existence) of placeholders or signatures: + CScript partial1a = CScript() << OP_0 << sig1 << OP_0; + CScript partial1b = CScript() << OP_0 << OP_0 << sig1; + CScript partial2a = CScript() << OP_0 << sig2; + CScript partial2b = CScript() << sig2 << OP_0; + CScript partial3a = CScript() << sig3; + CScript partial3b = CScript() << OP_0 << OP_0 << sig3; + CScript partial3c = CScript() << OP_0 << sig3 << OP_0; + CScript complete12 = CScript() << OP_0 << sig1 << sig2; + CScript complete13 = CScript() << OP_0 << sig1 << sig3; + CScript complete23 = CScript() << OP_0 << sig2 << sig3; + + combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b); + BOOST_CHECK(combined == partial1a); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a); + BOOST_CHECK(combined == complete12); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial1a); + BOOST_CHECK(combined == complete12); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial1b, partial2b); + BOOST_CHECK(combined == complete12); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial1b); + BOOST_CHECK(combined == complete13); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial3a); + BOOST_CHECK(combined == complete23); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial2b); + BOOST_CHECK(combined == complete23); + combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial3a); + BOOST_CHECK(combined == partial3c); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp new file mode 100644 index 0000000..59673f9 --- /dev/null +++ b/src/test/sigopcount_tests.cpp @@ -0,0 +1,60 @@ +#include +#include +#include + +#include "script.h" +#include "key.h" + +using namespace std; + +// Helpers: +static std::vector +Serialize(const CScript& s) +{ + std::vector sSerialized(s); + return sSerialized; +} + +BOOST_AUTO_TEST_SUITE(sigopcount_tests) + +BOOST_AUTO_TEST_CASE(GetSigOpCount) +{ + // Test CScript::GetSigOpCount() + CScript s1; + BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0); + BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0); + + uint160 dummy; + s1 << OP_1 << dummy << dummy << OP_2 << OP_CHECKMULTISIG; + BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2); + s1 << OP_IF << OP_CHECKSIG << OP_ENDIF; + BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3); + BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21); + + CScript p2sh; + p2sh.SetDestination(s1.GetID()); + CScript scriptSig; + scriptSig << OP_0 << Serialize(s1); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3); + + std::vector keys; + for (int i = 0; i < 3; i++) + { + CKey k; + k.MakeNewKey(true); + keys.push_back(k); + } + CScript s2; + s2.SetMultisig(1, keys); + BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3); + BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20); + + p2sh.SetDestination(s2.GetID()); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0); + CScript scriptSig2; + scriptSig2 << OP_1 << dummy << dummy << Serialize(s2); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp new file mode 100644 index 0000000..96d63bf --- /dev/null +++ b/src/test/test_bitcoin.cpp @@ -0,0 +1,38 @@ +#define BOOST_TEST_MODULE Bitcoin Test Suite +#include + +#include "main.h" +#include "wallet.h" + +CWallet* pwalletMain; +CClientUIInterface uiInterface; + +extern bool fPrintToConsole; +extern void noui_connect(); + +struct TestingSetup { + TestingSetup() { + fPrintToConsole = true; // don't want to write to debug.log file + noui_connect(); + pwalletMain = new CWallet(); + RegisterWallet(pwalletMain); + } + ~TestingSetup() + { + delete pwalletMain; + pwalletMain = NULL; + } +}; + +BOOST_GLOBAL_FIXTURE(TestingSetup); + +void Shutdown(void* parg) +{ + exit(0); +} + +void StartShutdown() +{ + exit(0); +} + diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp new file mode 100644 index 0000000..be0d976 --- /dev/null +++ b/src/test/transaction_tests.cpp @@ -0,0 +1,120 @@ +#include + +#include "main.h" +#include "wallet.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(transaction_tests) + +BOOST_AUTO_TEST_CASE(basic_transaction_tests) +{ + // Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436) + unsigned char ch[] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00}; + vector vch(ch, ch + sizeof(ch) -1); + CDataStream stream(vch, SER_DISK, CLIENT_VERSION); + CTransaction tx; + stream >> tx; + BOOST_CHECK_MESSAGE(tx.CheckTransaction(), "Simple deserialized transaction should be valid."); + + // Check that duplicate txins fail + tx.vin.push_back(tx.vin[0]); + BOOST_CHECK_MESSAGE(!tx.CheckTransaction(), "Transaction with duplicate txins should be invalid."); +} + +// +// Helper: create two dummy transactions, each with +// two outputs. The first has 11 and 50 CENT outputs +// paid to a TX_PUBKEY, the second 21 and 22 CENT outputs +// paid to a TX_PUBKEYHASH. +// +static std::vector +SetupDummyInputs(CBasicKeyStore& keystoreRet, MapPrevTx& inputsRet) +{ + std::vector dummyTransactions; + dummyTransactions.resize(2); + + // Add some keys to the keystore: + CKey key[4]; + for (int i = 0; i < 4; i++) + { + key[i].MakeNewKey(i % 2); + keystoreRet.AddKey(key[i]); + } + + // Create some dummy input transactions + dummyTransactions[0].vout.resize(2); + dummyTransactions[0].vout[0].nValue = 11*CENT; + dummyTransactions[0].vout[0].scriptPubKey << key[0].GetPubKey() << OP_CHECKSIG; + dummyTransactions[0].vout[1].nValue = 50*CENT; + dummyTransactions[0].vout[1].scriptPubKey << key[1].GetPubKey() << OP_CHECKSIG; + inputsRet[dummyTransactions[0].GetHash()] = make_pair(CTxIndex(), dummyTransactions[0]); + + dummyTransactions[1].vout.resize(2); + dummyTransactions[1].vout[0].nValue = 21*CENT; + dummyTransactions[1].vout[0].scriptPubKey.SetDestination(key[2].GetPubKey().GetID()); + dummyTransactions[1].vout[1].nValue = 22*CENT; + dummyTransactions[1].vout[1].scriptPubKey.SetDestination(key[3].GetPubKey().GetID()); + inputsRet[dummyTransactions[1].GetHash()] = make_pair(CTxIndex(), dummyTransactions[1]); + + return dummyTransactions; +} + +BOOST_AUTO_TEST_CASE(test_Get) +{ + CBasicKeyStore keystore; + MapPrevTx dummyInputs; + std::vector dummyTransactions = SetupDummyInputs(keystore, dummyInputs); + + CTransaction t1; + t1.vin.resize(3); + t1.vin[0].prevout.hash = dummyTransactions[0].GetHash(); + t1.vin[0].prevout.n = 1; + t1.vin[0].scriptSig << std::vector(65, 0); + t1.vin[1].prevout.hash = dummyTransactions[1].GetHash(); + t1.vin[1].prevout.n = 0; + t1.vin[1].scriptSig << std::vector(65, 0) << std::vector(33, 4); + t1.vin[2].prevout.hash = dummyTransactions[1].GetHash(); + t1.vin[2].prevout.n = 1; + t1.vin[2].scriptSig << std::vector(65, 0) << std::vector(33, 4); + t1.vout.resize(2); + t1.vout[0].nValue = 90*CENT; + t1.vout[0].scriptPubKey << OP_1; + + BOOST_CHECK(t1.AreInputsStandard(dummyInputs)); + BOOST_CHECK_EQUAL(t1.GetValueIn(dummyInputs), (50+21+22)*CENT); + + // Adding extra junk to the scriptSig should make it non-standard: + t1.vin[0].scriptSig << OP_11; + BOOST_CHECK(!t1.AreInputsStandard(dummyInputs)); + + // ... as should not having enough: + t1.vin[0].scriptSig = CScript(); + BOOST_CHECK(!t1.AreInputsStandard(dummyInputs)); +} + +BOOST_AUTO_TEST_CASE(test_GetThrow) +{ + CBasicKeyStore keystore; + MapPrevTx dummyInputs; + std::vector dummyTransactions = SetupDummyInputs(keystore, dummyInputs); + + MapPrevTx missingInputs; + + CTransaction t1; + t1.vin.resize(3); + t1.vin[0].prevout.hash = dummyTransactions[0].GetHash(); + t1.vin[0].prevout.n = 0; + t1.vin[1].prevout.hash = dummyTransactions[1].GetHash();; + t1.vin[1].prevout.n = 0; + t1.vin[2].prevout.hash = dummyTransactions[1].GetHash();; + t1.vin[2].prevout.n = 1; + t1.vout.resize(2); + t1.vout[0].nValue = 90*CENT; + t1.vout[0].scriptPubKey << OP_1; + + BOOST_CHECK_THROW(t1.AreInputsStandard(missingInputs), runtime_error); + BOOST_CHECK_THROW(t1.GetValueIn(missingInputs), runtime_error); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/uint160_tests.cpp b/src/test/uint160_tests.cpp new file mode 100644 index 0000000..35cb35b --- /dev/null +++ b/src/test/uint160_tests.cpp @@ -0,0 +1,18 @@ +#include + +#include "uint256.h" + +BOOST_AUTO_TEST_SUITE(uint160_tests) + +BOOST_AUTO_TEST_CASE(uint160_equality) +{ + uint160 num1 = 10; + uint160 num2 = 11; + BOOST_CHECK(num1+1 == num2); + + uint64 num3 = 10; + BOOST_CHECK(num1 == num3); + BOOST_CHECK(num1+num2 == num3+num2); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp new file mode 100644 index 0000000..efdc8a6 --- /dev/null +++ b/src/test/uint256_tests.cpp @@ -0,0 +1,18 @@ +#include + +#include "uint256.h" + +BOOST_AUTO_TEST_SUITE(uint256_tests) + +BOOST_AUTO_TEST_CASE(uint256_equality) +{ + uint256 num1 = 10; + uint256 num2 = 11; + BOOST_CHECK(num1+1 == num2); + + uint64 num3 = 10; + BOOST_CHECK(num1 == num3); + BOOST_CHECK(num1+num2 == num3+num2); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp new file mode 100644 index 0000000..2bfda61 --- /dev/null +++ b/src/test/util_tests.cpp @@ -0,0 +1,262 @@ +#include +#include +#include + +#include "main.h" +#include "wallet.h" +#include "util.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(util_tests) + +BOOST_AUTO_TEST_CASE(util_criticalsection) +{ + CCriticalSection cs; + + do { + LOCK(cs); + break; + + BOOST_ERROR("break was swallowed!"); + } while(0); + + do { + TRY_LOCK(cs, lockTest); + if (lockTest) + break; + + BOOST_ERROR("break was swallowed!"); + } while(0); +} + +BOOST_AUTO_TEST_CASE(util_MedianFilter) +{ + CMedianFilter filter(5, 15); + + BOOST_CHECK_EQUAL(filter.median(), 15); + + filter.input(20); // [15 20] + BOOST_CHECK_EQUAL(filter.median(), 17); + + filter.input(30); // [15 20 30] + BOOST_CHECK_EQUAL(filter.median(), 20); + + filter.input(3); // [3 15 20 30] + BOOST_CHECK_EQUAL(filter.median(), 17); + + filter.input(7); // [3 7 15 20 30] + BOOST_CHECK_EQUAL(filter.median(), 15); + + filter.input(18); // [3 7 18 20 30] + BOOST_CHECK_EQUAL(filter.median(), 18); + + filter.input(0); // [0 3 7 18 30] + BOOST_CHECK_EQUAL(filter.median(), 7); +} + +static const unsigned char ParseHex_expected[65] = { + 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, + 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, + 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, + 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, + 0x5f +}; +BOOST_AUTO_TEST_CASE(util_ParseHex) +{ + std::vector result; + std::vector expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)); + // Basic test vector + result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); + BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); + + // Spaces between bytes must be supported + result = ParseHex("12 34 56 78"); + BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78); + + // Stop parsing at invalid value + result = ParseHex("1234 invalid 1234"); + BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34); +} + +BOOST_AUTO_TEST_CASE(util_HexStr) +{ + BOOST_CHECK_EQUAL( + HexStr(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)), + "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); + + BOOST_CHECK_EQUAL( + HexStr(ParseHex_expected, ParseHex_expected + 5, true), + "04 67 8a fd b0"); + + BOOST_CHECK_EQUAL( + HexStr(ParseHex_expected, ParseHex_expected, true), + ""); + + std::vector ParseHex_vec(ParseHex_expected, ParseHex_expected + 5); + + BOOST_CHECK_EQUAL( + HexStr(ParseHex_vec, true), + "04 67 8a fd b0"); +} + + +BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat) +{ + BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0), "01/01/70 00:00:00"); + BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0x7FFFFFFF), "01/19/38 03:14:07"); + // Formats used within Bitcoin + BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 1317425777), "09/30/11 23:36:17"); + BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M", 1317425777), "09/30/11 23:36"); +} + +BOOST_AUTO_TEST_CASE(util_ParseParameters) +{ + const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"}; + + ParseParameters(0, (char**)argv_test); + BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + + ParseParameters(1, (char**)argv_test); + BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + + ParseParameters(5, (char**)argv_test); + // expectation: -ignored is ignored (program name argument), + // -a, -b and -ccc end up in map, -d ignored because it is after + // a non-option argument (non-GNU option parsing) + BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3); + BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc") + && !mapArgs.count("f") && !mapArgs.count("-d")); + BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc") + && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d")); + + BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple"); + BOOST_CHECK(mapMultiArgs["-ccc"].size() == 2); +} + +BOOST_AUTO_TEST_CASE(util_GetArg) +{ + mapArgs.clear(); + mapArgs["strtest1"] = "string..."; + // strtest2 undefined on purpose + mapArgs["inttest1"] = "12345"; + mapArgs["inttest2"] = "81985529216486895"; + // inttest3 undefined on purpose + mapArgs["booltest1"] = ""; + // booltest2 undefined on purpose + mapArgs["booltest3"] = "0"; + mapArgs["booltest4"] = "1"; + + BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string..."); + BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default"); + BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345); + BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL); + BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1); + BOOST_CHECK_EQUAL(GetBoolArg("booltest1"), true); + BOOST_CHECK_EQUAL(GetBoolArg("booltest2"), false); + BOOST_CHECK_EQUAL(GetBoolArg("booltest3"), false); + BOOST_CHECK_EQUAL(GetBoolArg("booltest4"), true); +} + +BOOST_AUTO_TEST_CASE(util_WildcardMatch) +{ + BOOST_CHECK(WildcardMatch("127.0.0.1", "*")); + BOOST_CHECK(WildcardMatch("127.0.0.1", "127.*")); + BOOST_CHECK(WildcardMatch("abcdef", "a?cde?")); + BOOST_CHECK(!WildcardMatch("abcdef", "a?cde??")); + BOOST_CHECK(WildcardMatch("abcdef", "a*f")); + BOOST_CHECK(!WildcardMatch("abcdef", "a*x")); + BOOST_CHECK(WildcardMatch("", "*")); +} + +BOOST_AUTO_TEST_CASE(util_FormatMoney) +{ + BOOST_CHECK_EQUAL(FormatMoney(0, false), "0.00"); + BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789, false), "12345.6789"); + BOOST_CHECK_EQUAL(FormatMoney(COIN, true), "+1.00"); + BOOST_CHECK_EQUAL(FormatMoney(-COIN, false), "-1.00"); + BOOST_CHECK_EQUAL(FormatMoney(-COIN, true), "-1.00"); + + BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000, false), "100000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000, false), "10000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000, false), "1000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*100000, false), "100000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10000, false), "10000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*1000, false), "1000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*100, false), "100.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10, false), "10.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN, false), "1.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10, false), "0.10"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100, false), "0.01"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/1000, false), "0.001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10000, false), "0.0001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100000, false), "0.00001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000, false), "0.000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000, false), "0.0000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000, false), "0.00000001"); +} + +BOOST_AUTO_TEST_CASE(util_ParseMoney) +{ + int64 ret = 0; + BOOST_CHECK(ParseMoney("0.0", ret)); + BOOST_CHECK_EQUAL(ret, 0); + + BOOST_CHECK(ParseMoney("12345.6789", ret)); + BOOST_CHECK_EQUAL(ret, (COIN/10000)*123456789); + + BOOST_CHECK(ParseMoney("100000000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*100000000); + BOOST_CHECK(ParseMoney("10000000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*10000000); + BOOST_CHECK(ParseMoney("1000000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*1000000); + BOOST_CHECK(ParseMoney("100000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*100000); + BOOST_CHECK(ParseMoney("10000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*10000); + BOOST_CHECK(ParseMoney("1000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*1000); + BOOST_CHECK(ParseMoney("100.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*100); + BOOST_CHECK(ParseMoney("10.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*10); + BOOST_CHECK(ParseMoney("1.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN); + BOOST_CHECK(ParseMoney("0.1", ret)); + BOOST_CHECK_EQUAL(ret, COIN/10); + BOOST_CHECK(ParseMoney("0.01", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100); + BOOST_CHECK(ParseMoney("0.001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/1000); + BOOST_CHECK(ParseMoney("0.0001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/10000); + BOOST_CHECK(ParseMoney("0.00001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100000); + BOOST_CHECK(ParseMoney("0.000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/1000000); + BOOST_CHECK(ParseMoney("0.0000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/10000000); + BOOST_CHECK(ParseMoney("0.00000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100000000); + + // Attempted 63 bit overflow should fail + BOOST_CHECK(!ParseMoney("92233720368.54775808", ret)); +} + +BOOST_AUTO_TEST_CASE(util_IsHex) +{ + BOOST_CHECK(IsHex("00")); + BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF")); + BOOST_CHECK(IsHex("ff")); + BOOST_CHECK(IsHex("FF")); + + BOOST_CHECK(!IsHex("")); + BOOST_CHECK(!IsHex("0")); + BOOST_CHECK(!IsHex("a")); + BOOST_CHECK(!IsHex("eleven")); + BOOST_CHECK(!IsHex("00xx00")); + BOOST_CHECK(!IsHex("0x0000")); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp new file mode 100644 index 0000000..2f6da93 --- /dev/null +++ b/src/test/wallet_tests.cpp @@ -0,0 +1,295 @@ +#include + +#include "main.h" +#include "wallet.h" + +// how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles +#define RUN_TESTS 100 + +// some tests fail 1% of the time due to bad luck. +// we repeat those tests this many times and only complain if all iterations of the test fail +#define RANDOM_REPEATS 5 + +using namespace std; + +typedef set > CoinSet; + +BOOST_AUTO_TEST_SUITE(wallet_tests) + +static CWallet wallet; +static vector vCoins; + +static void add_coin(int64 nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) +{ + static int i; + CTransaction* tx = new CTransaction; + tx->nLockTime = i++; // so all transactions get different hashes + tx->vout.resize(nInput+1); + tx->vout[nInput].nValue = nValue; + CWalletTx* wtx = new CWalletTx(&wallet, *tx); + delete tx; + if (fIsFromMe) + { + // IsFromMe() returns (GetDebit() > 0), and GetDebit() is 0 if vin.empty(), + // so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe() + wtx->vin.resize(1); + wtx->fDebitCached = true; + wtx->nDebitCached = 1; + } + COutput output(wtx, nInput, nAge); + vCoins.push_back(output); +} + +static void empty_wallet(void) +{ + BOOST_FOREACH(COutput output, vCoins) + delete output.tx; + vCoins.clear(); +} + +static bool equal_sets(CoinSet a, CoinSet b) +{ + pair ret = mismatch(a.begin(), a.end(), b.begin()); + return ret.first == a.end() && ret.second == b.end(); +} + +BOOST_AUTO_TEST_CASE(coin_selection_tests) +{ + static CoinSet setCoinsRet, setCoinsRet2; + static int64 nValueRet; + + // test multiple times to allow for differences in the shuffle order + for (int i = 0; i < RUN_TESTS; i++) + { + empty_wallet(); + + // with an empty wallet we can't even pay one cent + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + + add_coin(1*CENT, 4); // add a new 1 cent coin + + // with a new 1 cent coin, we still can't find a mature 1 cent + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + + // but we can find a new 1 cent + BOOST_CHECK( wallet.SelectCoinsMinConf( 1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); + + add_coin(2*CENT); // add a mature 2 cent coin + + // we can't make 3 cents of mature coins + BOOST_CHECK(!wallet.SelectCoinsMinConf( 3 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + + // we can make 3 cents of new coins + BOOST_CHECK( wallet.SelectCoinsMinConf( 3 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); + + add_coin(5*CENT); // add a mature 5 cent coin, + add_coin(10*CENT, 3, true); // a new 10 cent coin sent from one of our own addresses + add_coin(20*CENT); // and a mature 20 cent coin + + // now we have new: 1+10=11 (of which 10 was self-sent), and mature: 2+5+20=27. total = 38 + + // we can't make 38 cents only if we disallow new coins: + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + // we can't even make 37 cents if we don't allow new coins even if they're from us + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 6, 6, vCoins, setCoinsRet, nValueRet)); + // but we can make 37 cents if we accept new coins from ourself + BOOST_CHECK( wallet.SelectCoinsMinConf(37 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 37 * CENT); + // and we can make 38 cents if we accept all new coins + BOOST_CHECK( wallet.SelectCoinsMinConf(38 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 38 * CENT); + + // try making 34 cents from 1,2,5,10,20 - we can't do it exactly + BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_GT(nValueRet, 34 * CENT); // but should get more than 34 cents + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) + + // when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5 + BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 7 * CENT); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); + + // when we try making 8 cents, the smaller coins (1,2,5) are exactly enough. + BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(nValueRet == 8 * CENT); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); + + // when we try making 9 cents, no subset of smaller coins is enough, and we get the next bigger coin (10) + BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 10 * CENT); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + // now clear out the wallet and start again to test choosing between subsets of smaller coins and the next biggest coin + empty_wallet(); + + add_coin( 6*CENT); + add_coin( 7*CENT); + add_coin( 8*CENT); + add_coin(20*CENT); + add_coin(30*CENT); // now we have 6+7+8+20+30 = 71 cents total + + // check that we have 71 and not 72 + BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + + // now try making 16 cents. the best smaller coins can do is 6+7+8 = 21; not as good at the next biggest coin, 20 + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + add_coin( 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total + + // now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, better than the next biggest coin, 20 + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); + + add_coin( 18*CENT); // now we have 5+6+7+8+18+20+30 + + // and now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, the same as the next biggest coin, 18 + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 1 coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); // because in the event of a tie, the biggest coin wins + + // now try making 11 cents. we should get 5+6 + BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 11 * CENT); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); + + // check that the smallest bigger coin is used + add_coin( 1*COIN); + add_coin( 2*COIN); + add_coin( 3*COIN); + add_coin( 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents + BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 bitcoin in 1 coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 bitcoins in 1 coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + // empty the wallet and start again, now with fractions of a cent, to test sub-cent change avoidance + empty_wallet(); + add_coin(0.1*CENT); + add_coin(0.2*CENT); + add_coin(0.3*CENT); + add_coin(0.4*CENT); + add_coin(0.5*CENT); + + // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 = 1.5 cents + // we'll get sub-cent change whatever happens, so can expect 1.0 exactly + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); + + // but if we add a bigger coin, making it possible to avoid sub-cent change, things change: + add_coin(1111*CENT); + + // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 cents + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + + // if we add more sub-cent coins: + add_coin(0.6*CENT); + add_coin(0.7*CENT); + + // and try again to make 1.0 cents, we can still make 1.0 cents + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + + // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) + // they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change + empty_wallet(); + for (int i = 0; i < 20; i++) + add_coin(50000 * COIN); + + BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount + BOOST_CHECK_EQUAL(setCoinsRet.size(), 10); // in ten coins + + // if there's not enough in the smaller coins to make at least 1 cent change (0.5+0.6+0.7 < 1.0+1.0), + // we need to try finding an exact subset anyway + + // sometimes it will fail, and so we use the next biggest coin: + empty_wallet(); + add_coin(0.5 * CENT); + add_coin(0.6 * CENT); + add_coin(0.7 * CENT); + add_coin(1111 * CENT); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // we get the bigger coin + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + + // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) + empty_wallet(); + add_coin(0.4 * CENT); + add_coin(0.6 * CENT); + add_coin(0.8 * CENT); + add_coin(1111 * CENT); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); // in two coins 0.4+0.6 + + // test avoiding sub-cent change + empty_wallet(); + add_coin(0.0005 * COIN); + add_coin(0.01 * COIN); + add_coin(1 * COIN); + + // trying to make 1.0001 from these three coins + BOOST_CHECK( wallet.SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1.0105 * COIN); // we should get all coins + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); + + // but if we try to make 0.999, we should take the bigger of the two small coins to avoid sub-cent change + BOOST_CHECK( wallet.SelectCoinsMinConf(0.999 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1.01 * COIN); // we should get 1 + 0.01 + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); + + // test randomness + { + empty_wallet(); + for (int i2 = 0; i2 < 100; i2++) + add_coin(COIN); + + // picking 50 from 100 coins doesn't depend on the shuffle, + // but does depend on randomness in the stochastic approximation code + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); + + int fails = 0; + for (int i = 0; i < RANDOM_REPEATS; i++) + { + // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time + // run the test RANDOM_REPEATS times and only complain if all of them fail + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + if (equal_sets(setCoinsRet, setCoinsRet2)) + fails++; + } + BOOST_CHECK_NE(fails, RANDOM_REPEATS); + + // add 75 cents in small change. not enough to make 90 cents, + // then try making 90 cents. there are multiple competing "smallest bigger" coins, + // one of which should be picked at random + add_coin( 5*CENT); add_coin(10*CENT); add_coin(15*CENT); add_coin(20*CENT); add_coin(25*CENT); + + fails = 0; + for (int i = 0; i < RANDOM_REPEATS; i++) + { + // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time + // run the test RANDOM_REPEATS times and only complain if all of them fail + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet2, nValueRet)); + if (equal_sets(setCoinsRet, setCoinsRet2)) + fails++; + } + BOOST_CHECK_NE(fails, RANDOM_REPEATS); + } + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/ui_interface.h b/src/ui_interface.h new file mode 100644 index 0000000..4775509 --- /dev/null +++ b/src/ui_interface.h @@ -0,0 +1,106 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2012 The Bitcoin developers +// Copyright (c) 2012 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_UI_INTERFACE_H +#define BITCOIN_UI_INTERFACE_H + +#include +#include "util.h" // for int64 +#include +#include + +class CBasicKeyStore; +class CWallet; +class uint256; + +/** General change type (added, updated, removed). */ +enum ChangeType +{ + CT_NEW, + CT_UPDATED, + CT_DELETED +}; + +/** Signals for UI communication. */ +class CClientUIInterface +{ +public: + /** Flags for CClientUIInterface::ThreadSafeMessageBox */ + enum MessageBoxFlags + { + YES = 0x00000002, + OK = 0x00000004, + NO = 0x00000008, + YES_NO = (YES|NO), + CANCEL = 0x00000010, + APPLY = 0x00000020, + CLOSE = 0x00000040, + OK_DEFAULT = 0x00000000, + YES_DEFAULT = 0x00000000, + NO_DEFAULT = 0x00000080, + CANCEL_DEFAULT = 0x80000000, + ICON_EXCLAMATION = 0x00000100, + ICON_HAND = 0x00000200, + ICON_WARNING = ICON_EXCLAMATION, + ICON_ERROR = ICON_HAND, + ICON_QUESTION = 0x00000400, + ICON_INFORMATION = 0x00000800, + ICON_STOP = ICON_HAND, + ICON_ASTERISK = ICON_INFORMATION, + ICON_MASK = (0x00000100|0x00000200|0x00000400|0x00000800), + FORWARD = 0x00001000, + BACKWARD = 0x00002000, + RESET = 0x00004000, + HELP = 0x00008000, + MORE = 0x00010000, + SETUP = 0x00020000, + // Force blocking, modal message box dialog (not just OS notification) + MODAL = 0x00040000 + }; + + /** Show message box. */ + boost::signals2::signal ThreadSafeMessageBox; + + /** Ask the user whether they want to pay a fee or not. */ + boost::signals2::signal > ThreadSafeAskFee; + + /** Handle a URL passed at the command line. */ + boost::signals2::signal ThreadSafeHandleURI; + + /** Progress message during initialization. */ + boost::signals2::signal InitMessage; + + /** Initiate client shutdown. */ + boost::signals2::signal QueueShutdown; + + /** Translate a message to the native language of the user. */ + boost::signals2::signal Translate; + + /** Block chain changed. */ + boost::signals2::signal NotifyBlocksChanged; + + /** Number of network connections changed. */ + boost::signals2::signal NotifyNumConnectionsChanged; + + /** + * New, updated or cancelled alert. + * @note called with lock cs_mapAlerts held. + */ + boost::signals2::signal NotifyAlertChanged; +}; + +extern CClientUIInterface uiInterface; + +/** + * Translation function: Call Translate signal on UI interface, which returns a boost::optional result. + * If no translation slot is registered, nothing is returned, and simply return the input. + */ +inline std::string _(const char* psz) +{ + boost::optional rv = uiInterface.Translate(psz); + return rv ? (*rv) : psz; +} + +#endif diff --git a/src/uint256.h b/src/uint256.h new file mode 100644 index 0000000..45bea65 --- /dev/null +++ b/src/uint256.h @@ -0,0 +1,765 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_UINT256_H +#define BITCOIN_UINT256_H + +#include +#include +#include +#include +#include + +typedef long long int64; +typedef unsigned long long uint64; + + +inline int Testuint256AdHoc(std::vector vArg); + + + +/** Base class without constructors for uint256 and uint160. + * This makes the compiler let u use it in a union. + */ +template +class base_uint +{ +protected: + enum { WIDTH=BITS/32 }; + unsigned int pn[WIDTH]; +public: + + bool operator!() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } + + const base_uint operator~() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + return ret; + } + + const base_uint operator-() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + ret++; + return ret; + } + + + base_uint& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + base_uint& operator^=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] ^= b.pn[i]; + return *this; + } + + base_uint& operator&=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] &= b.pn[i]; + return *this; + } + + base_uint& operator|=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] |= b.pn[i]; + return *this; + } + + base_uint& operator^=(uint64 b) + { + pn[0] ^= (unsigned int)b; + pn[1] ^= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator|=(uint64 b) + { + pn[0] |= (unsigned int)b; + pn[1] |= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator<<=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i+k+1 < WIDTH && shift != 0) + pn[i+k+1] |= (a.pn[i] >> (32-shift)); + if (i+k < WIDTH) + pn[i+k] |= (a.pn[i] << shift); + } + return *this; + } + + base_uint& operator>>=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i-k-1 >= 0 && shift != 0) + pn[i-k-1] |= (a.pn[i] << (32-shift)); + if (i-k >= 0) + pn[i-k] |= (a.pn[i] >> shift); + } + return *this; + } + + base_uint& operator+=(const base_uint& b) + { + uint64 carry = 0; + for (int i = 0; i < WIDTH; i++) + { + uint64 n = carry + pn[i] + b.pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; + } + + base_uint& operator-=(const base_uint& b) + { + *this += -b; + return *this; + } + + base_uint& operator+=(uint64 b64) + { + base_uint b; + b = b64; + *this += b; + return *this; + } + + base_uint& operator-=(uint64 b64) + { + base_uint b; + b = b64; + *this += -b; + return *this; + } + + + base_uint& operator++() + { + // prefix operator + int i = 0; + while (++pn[i] == 0 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator++(int) + { + // postfix operator + const base_uint ret = *this; + ++(*this); + return ret; + } + + base_uint& operator--() + { + // prefix operator + int i = 0; + while (--pn[i] == -1 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator--(int) + { + // postfix operator + const base_uint ret = *this; + --(*this); + return ret; + } + + + friend inline bool operator<(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator<=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator>(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator>=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator==(const base_uint& a, const base_uint& b) + { + for (int i = 0; i < base_uint::WIDTH; i++) + if (a.pn[i] != b.pn[i]) + return false; + return true; + } + + friend inline bool operator==(const base_uint& a, uint64 b) + { + if (a.pn[0] != (unsigned int)b) + return false; + if (a.pn[1] != (unsigned int)(b >> 32)) + return false; + for (int i = 2; i < base_uint::WIDTH; i++) + if (a.pn[i] != 0) + return false; + return true; + } + + friend inline bool operator!=(const base_uint& a, const base_uint& b) + { + return (!(a == b)); + } + + friend inline bool operator!=(const base_uint& a, uint64 b) + { + return (!(a == b)); + } + + + + std::string GetHex() const + { + char psz[sizeof(pn)*2 + 1]; + for (unsigned int i = 0; i < sizeof(pn); i++) + sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); + return std::string(psz, psz + sizeof(pn)*2); + } + + void SetHex(const char* psz) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + + // skip leading spaces + while (isspace(*psz)) + psz++; + + // skip 0x + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + + // hex string to uint + static unsigned char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + const char* pbegin = psz; + while (phexdigit[(unsigned char)*psz] || *psz == '0') + psz++; + psz--; + unsigned char* p1 = (unsigned char*)pn; + unsigned char* pend = p1 + WIDTH * 4; + while (psz >= pbegin && p1 < pend) + { + *p1 = phexdigit[(unsigned char)*psz--]; + if (psz >= pbegin) + { + *p1 |= (phexdigit[(unsigned char)*psz--] << 4); + p1++; + } + } + } + + void SetHex(const std::string& str) + { + SetHex(str.c_str()); + } + + std::string ToString() const + { + return (GetHex()); + } + + unsigned char* begin() + { + return (unsigned char*)&pn[0]; + } + + unsigned char* end() + { + return (unsigned char*)&pn[WIDTH]; + } + + unsigned int size() + { + return sizeof(pn); + } + + uint64 Get64(int n=0) const + { + return pn[2*n] | (uint64)pn[2*n+1] << 32; + } + +// unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const + unsigned int GetSerializeSize(int nType, int nVersion) const + { + return sizeof(pn); + } + + template +// void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const + void Serialize(Stream& s, int nType, int nVersion) const + { + s.write((char*)pn, sizeof(pn)); + } + + template +// void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) + void Unserialize(Stream& s, int nType, int nVersion) + { + s.read((char*)pn, sizeof(pn)); + } + + + friend class uint160; + friend class uint256; + friend inline int Testuint256AdHoc(std::vector vArg); +}; + +typedef base_uint<160> base_uint160; +typedef base_uint<256> base_uint256; + + + +// +// uint160 and uint256 could be implemented as templates, but to keep +// compile errors and debugging cleaner, they're copy and pasted. +// + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint160 +// + +/** 160-bit unsigned integer */ +class uint160 : public base_uint160 +{ +public: + typedef base_uint160 basetype; + + uint160() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint160(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint160& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint160(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint160& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint160(const std::string& str) + { + SetHex(str); + } + + explicit uint160(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; } +inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; } +inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; } +inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; } + +inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; } +inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; } +inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; } +inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; } +inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; } + +inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint256 +// + +/** 256-bit unsigned integer */ +class uint256 : public base_uint256 +{ +public: + typedef base_uint256 basetype; + + uint256() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + uint256(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint256& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint256(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint256& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint256(const std::string& str) + { + SetHex(str); + } + + explicit uint256(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint256& a, uint64 b) { return (base_uint256)a == b; } +inline bool operator!=(const uint256& a, uint64 b) { return (base_uint256)a != b; } +inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; } +inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; } + +inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; } +inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; } +inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; } +inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; } +inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; } + +inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + + + + + + + + + + +#ifdef TEST_UINT256 + +inline int Testuint256AdHoc(std::vector vArg) +{ + uint256 g(0); + + + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + + + + uint256 a(7); + printf("a=7\n"); + printf("%s\n", a.ToString().c_str()); + + uint256 b; + printf("b undefined\n"); + printf("%s\n", b.ToString().c_str()); + int c = 3; + + a = c; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + uint256 k(c); + + a = 5; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + b = 1; + b <<= 52; + + a |= b; + + a ^= 0x500; + + printf("a %s\n", a.ToString().c_str()); + + a = a | b | (uint256)0x1000; + + + printf("a %s\n", a.ToString().c_str()); + printf("b %s\n", b.ToString().c_str()); + + a = 0xfffffffe; + a.pn[4] = 9; + + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + uint256 d = a--; + printf("%s\n", d.ToString().c_str()); + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + + d = a; + + printf("%s\n", d.ToString().c_str()); + for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n"); + + uint256 neg = d; + neg = ~neg; + printf("%s\n", neg.ToString().c_str()); + + + uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + printf("\n"); + printf("%s\n", e.ToString().c_str()); + + + printf("\n"); + uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + uint256 x2; + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1 << i; + printf("%s\n", x2.ToString().c_str()); + } + + printf("\n"); + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1; + x2 >>= i; + printf("%s\n", x2.ToString().c_str()); + } + + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) >> i); + printf("%s\n", k.ToString().c_str()); + } + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) << i); + printf("%s\n", k.ToString().c_str()); + } + + return (0); +} + +#endif + +#endif diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..afb4f30 --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,1304 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "util.h" +#include "sync.h" +#include "strlcpy.h" +#include "version.h" +#include "ui_interface.h" +#include + +// Work around clang compilation problem in Boost 1.46: +// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup +// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options +// http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION +namespace boost { + namespace program_options { + std::string to_internal(const std::string&); + } +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4804) +#pragma warning(disable:4805) +#pragma warning(disable:4717) +#endif +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include /* for _commit */ +#include "shlobj.h" +#elif defined(__linux__) +# include +#endif + +using namespace std; + +map mapArgs; +map > mapMultiArgs; +bool fDebug = false; +bool fDebugNet = false; +bool fPrintToConsole = false; +bool fPrintToDebugger = false; +bool fRequestShutdown = false; +bool fShutdown = false; +bool fDaemon = false; +bool fServer = false; +bool fCommandLine = false; +string strMiscWarning; +bool fTestNet = false; +bool fNoListen = false; +bool fLogTimestamps = false; +CMedianFilter vTimeOffsets(200,0); +bool fReopenDebugLog = false; + +// Init openssl library multithreading support +static CCriticalSection** ppmutexOpenSSL; +void locking_callback(int mode, int i, const char* file, int line) +{ + if (mode & CRYPTO_LOCK) { + ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]); + } else { + LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]); + } +} + +// Init +class CInit +{ +public: + CInit() + { + // Init openssl library multithreading support + ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*)); + for (int i = 0; i < CRYPTO_num_locks(); i++) + ppmutexOpenSSL[i] = new CCriticalSection(); + CRYPTO_set_locking_callback(locking_callback); + +#ifdef WIN32 + // Seed random number generator with screen scrape and other hardware sources + RAND_screen(); +#endif + + // Seed random number generator with performance counter + RandAddSeed(); + } + ~CInit() + { + // Shutdown openssl library multithreading support + CRYPTO_set_locking_callback(NULL); + for (int i = 0; i < CRYPTO_num_locks(); i++) + delete ppmutexOpenSSL[i]; + OPENSSL_free(ppmutexOpenSSL); + } +} +instance_of_cinit; + + + + + + + + +void RandAddSeed() +{ + // Seed with CPU performance counter + int64 nCounter = GetPerformanceCounter(); + RAND_add(&nCounter, sizeof(nCounter), 1.5); + memset(&nCounter, 0, sizeof(nCounter)); +} + +void RandAddSeedPerfmon() +{ + RandAddSeed(); + + // This can take up to 2 seconds, so only do it every 10 minutes + static int64 nLastPerfmon; + if (GetTime() < nLastPerfmon + 10 * 60) + return; + nLastPerfmon = GetTime(); + +#ifdef WIN32 + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom + // Seed with the entire set of perfmon data + unsigned char pdata[250000]; + memset(pdata, 0, sizeof(pdata)); + unsigned long nSize = sizeof(pdata); + long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + RegCloseKey(HKEY_PERFORMANCE_DATA); + if (ret == ERROR_SUCCESS) + { + RAND_add(pdata, nSize, nSize/100.0); + memset(pdata, 0, nSize); + printf("RandAddSeed() %d bytes\n", nSize); + } +#endif +} + +uint64 GetRand(uint64 nMax) +{ + if (nMax == 0) + return 0; + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64 nRange = (std::numeric_limits::max() / nMax) * nMax; + uint64 nRand = 0; + do + RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); + while (nRand >= nRange); + return (nRand % nMax); +} + +int GetRandInt(int nMax) +{ + return GetRand(nMax); +} + +uint256 GetRandHash() +{ + uint256 hash; + RAND_bytes((unsigned char*)&hash, sizeof(hash)); + return hash; +} + + + + + + + + +inline int OutputDebugStringF(const char* pszFormat, ...) +{ + int ret = 0; + if (fPrintToConsole) + { + // print to console + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + } + else + { + // print to debug.log + static FILE* fileout = NULL; + + if (!fileout) + { + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + fileout = fopen(pathDebug.string().c_str(), "a"); + if (fileout) setbuf(fileout, NULL); // unbuffered + } + if (fileout) + { + static bool fStartedNewLine = true; + static boost::mutex mutexDebugLog; + boost::mutex::scoped_lock scoped_lock(mutexDebugLog); + + // reopen the log file, if requested + if (fReopenDebugLog) { + fReopenDebugLog = false; + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL) + setbuf(fileout, NULL); // unbuffered + } + + // Debug print useful for profiling + if (fLogTimestamps && fStartedNewLine) + fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + if (pszFormat[strlen(pszFormat) - 1] == '\n') + fStartedNewLine = true; + else + fStartedNewLine = false; + + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vfprintf(fileout, pszFormat, arg_ptr); + va_end(arg_ptr); + } + } + +#ifdef WIN32 + if (fPrintToDebugger) + { + static CCriticalSection cs_OutputDebugStringF; + + // accumulate and output a line at a time + { + LOCK(cs_OutputDebugStringF); + static std::string buffer; + + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + buffer += vstrprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + + int line_start = 0, line_end; + while((line_end = buffer.find('\n', line_start)) != -1) + { + OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str()); + line_start = line_end + 1; + } + buffer.erase(0, line_start); + } + } +#endif + return ret; +} + +string vstrprintf(const std::string &format, va_list ap) +{ + char buffer[50000]; + char* p = buffer; + int limit = sizeof(buffer); + int ret; + loop + { + va_list arg_ptr; + va_copy(arg_ptr, ap); + ret = _vsnprintf(p, limit, format.c_str(), arg_ptr); + va_end(arg_ptr); + if (ret >= 0 && ret < limit) + break; + if (p != buffer) + delete[] p; + limit *= 2; + p = new char[limit]; + if (p == NULL) + throw std::bad_alloc(); + } + string str(p, p+ret); + if (p != buffer) + delete[] p; + return str; +} + +string real_strprintf(const std::string &format, int dummy, ...) +{ + va_list arg_ptr; + va_start(arg_ptr, dummy); + string str = vstrprintf(format, arg_ptr); + va_end(arg_ptr); + return str; +} + +bool error(const char *format, ...) +{ + va_list arg_ptr; + va_start(arg_ptr, format); + std::string str = vstrprintf(format, arg_ptr); + va_end(arg_ptr); + printf("ERROR: %s\n", str.c_str()); + return false; +} + + +void ParseString(const string& str, char c, vector& v) +{ + if (str.empty()) + return; + string::size_type i1 = 0; + string::size_type i2; + loop + { + i2 = str.find(c, i1); + if (i2 == str.npos) + { + v.push_back(str.substr(i1)); + return; + } + v.push_back(str.substr(i1, i2-i1)); + i1 = i2+1; + } +} + + +string FormatMoney(int64 n, bool fPlus) +{ + // Note: not using straight sprintf here because we do NOT want + // localized number formatting. + int64 n_abs = (n > 0 ? n : -n); + int64 quotient = n_abs/COIN; + int64 remainder = n_abs%COIN; + string str = strprintf("%"PRI64d".%08"PRI64d, quotient, remainder); + + // Right-trim excess 0's before the decimal point: + int nTrim = 0; + for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i) + ++nTrim; + if (nTrim) + str.erase(str.size()-nTrim, nTrim); + + if (n < 0) + str.insert((unsigned int)0, 1, '-'); + else if (fPlus && n > 0) + str.insert((unsigned int)0, 1, '+'); + return str; +} + + +bool ParseMoney(const string& str, int64& nRet) +{ + return ParseMoney(str.c_str(), nRet); +} + +bool ParseMoney(const char* pszIn, int64& nRet) +{ + string strWhole; + int64 nUnits = 0; + const char* p = pszIn; + while (isspace(*p)) + p++; + for (; *p; p++) + { + if (*p == '.') + { + p++; + int64 nMult = CENT*10; + while (isdigit(*p) && (nMult > 0)) + { + nUnits += nMult * (*p++ - '0'); + nMult /= 10; + } + break; + } + if (isspace(*p)) + break; + if (!isdigit(*p)) + return false; + strWhole.insert(strWhole.end(), *p); + } + for (; *p; p++) + if (!isspace(*p)) + return false; + if (strWhole.size() > 10) // guard against 63 bit overflow + return false; + if (nUnits < 0 || nUnits > COIN) + return false; + int64 nWhole = atoi64(strWhole); + int64 nValue = nWhole*COIN + nUnits; + + nRet = nValue; + return true; +} + + +static signed char phexdigit[256] = +{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; + +bool IsHex(const string& str) +{ + BOOST_FOREACH(unsigned char c, str) + { + if (phexdigit[c] < 0) + return false; + } + return (str.size() > 0) && (str.size()%2 == 0); +} + +vector ParseHex(const char* psz) +{ + // convert hex dump to vector + vector vch; + loop + { + while (isspace(*psz)) + psz++; + signed char c = phexdigit[(unsigned char)*psz++]; + if (c == (signed char)-1) + break; + unsigned char n = (c << 4); + c = phexdigit[(unsigned char)*psz++]; + if (c == (signed char)-1) + break; + n |= c; + vch.push_back(n); + } + return vch; +} + +vector ParseHex(const string& str) +{ + return ParseHex(str.c_str()); +} + +static void InterpretNegativeSetting(string name, map& mapSettingsRet) +{ + // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set + if (name.find("-no") == 0) + { + std::string positive("-"); + positive.append(name.begin()+3, name.end()); + if (mapSettingsRet.count(positive) == 0) + { + bool value = !GetBoolArg(name); + mapSettingsRet[positive] = (value ? "1" : "0"); + } + } +} + +void ParseParameters(int argc, const char* const argv[]) +{ + mapArgs.clear(); + mapMultiArgs.clear(); + for (int i = 1; i < argc; i++) + { + char psz[10000]; + strlcpy(psz, argv[i], sizeof(psz)); + char* pszValue = (char*)""; + if (strchr(psz, '=')) + { + pszValue = strchr(psz, '='); + *pszValue++ = '\0'; + } + #ifdef WIN32 + _strlwr(psz); + if (psz[0] == '/') + psz[0] = '-'; + #endif + if (psz[0] != '-') + break; + + mapArgs[psz] = pszValue; + mapMultiArgs[psz].push_back(pszValue); + } + + // New 0.6 features: + BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs) + { + string name = entry.first; + + // interpret --foo as -foo (as long as both are not set) + if (name.find("--") == 0) + { + std::string singleDash(name.begin()+1, name.end()); + if (mapArgs.count(singleDash) == 0) + mapArgs[singleDash] = entry.second; + name = singleDash; + } + + // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set + InterpretNegativeSetting(name, mapArgs); + } +} + +std::string GetArg(const std::string& strArg, const std::string& strDefault) +{ + if (mapArgs.count(strArg)) + return mapArgs[strArg]; + return strDefault; +} + +int64 GetArg(const std::string& strArg, int64 nDefault) +{ + if (mapArgs.count(strArg)) + return atoi64(mapArgs[strArg]); + return nDefault; +} + +bool GetBoolArg(const std::string& strArg, bool fDefault) +{ + if (mapArgs.count(strArg)) + { + if (mapArgs[strArg].empty()) + return true; + return (atoi(mapArgs[strArg]) != 0); + } + return fDefault; +} + +bool SoftSetArg(const std::string& strArg, const std::string& strValue) +{ + if (mapArgs.count(strArg)) + return false; + mapArgs[strArg] = strValue; + return true; +} + +bool SoftSetBoolArg(const std::string& strArg, bool fValue) +{ + if (fValue) + return SoftSetArg(strArg, std::string("1")); + else + return SoftSetArg(strArg, std::string("0")); +} + + +string EncodeBase64(const unsigned char* pch, size_t len) +{ + static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + string strRet=""; + strRet.reserve((len+2)/3*4); + + int mode=0, left=0; + const unsigned char *pchEnd = pch+len; + + while (pch> 2]; + left = (enc & 3) << 4; + mode = 1; + break; + + case 1: // we have two bits + strRet += pbase64[left | (enc >> 4)]; + left = (enc & 15) << 2; + mode = 2; + break; + + case 2: // we have four bits + strRet += pbase64[left | (enc >> 6)]; + strRet += pbase64[enc & 63]; + mode = 0; + break; + } + } + + if (mode) + { + strRet += pbase64[left]; + strRet += '='; + if (mode == 1) + strRet += '='; + } + + return strRet; +} + +string EncodeBase64(const string& str) +{ + return EncodeBase64((const unsigned char*)str.c_str(), str.size()); +} + +vector DecodeBase64(const char* p, bool* pfInvalid) +{ + static const int decode64_table[256] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, + -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + if (pfInvalid) + *pfInvalid = false; + + vector vchRet; + vchRet.reserve(strlen(p)*3/4); + + int mode = 0; + int left = 0; + + while (1) + { + int dec = decode64_table[(unsigned char)*p]; + if (dec == -1) break; + p++; + switch (mode) + { + case 0: // we have no bits and get 6 + left = dec; + mode = 1; + break; + + case 1: // we have 6 bits and keep 4 + vchRet.push_back((left<<2) | (dec>>4)); + left = dec & 15; + mode = 2; + break; + + case 2: // we have 4 bits and get 6, we keep 2 + vchRet.push_back((left<<4) | (dec>>2)); + left = dec & 3; + mode = 3; + break; + + case 3: // we have 2 bits and get 6 + vchRet.push_back((left<<6) | dec); + mode = 0; + break; + } + } + + if (pfInvalid) + switch (mode) + { + case 0: // 4n base64 characters processed: ok + break; + + case 1: // 4n+1 base64 character processed: impossible + *pfInvalid = true; + break; + + case 2: // 4n+2 base64 characters processed: require '==' + if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1) + *pfInvalid = true; + break; + + case 3: // 4n+3 base64 characters processed: require '=' + if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1) + *pfInvalid = true; + break; + } + + return vchRet; +} + +string DecodeBase64(const string& str) +{ + vector vchRet = DecodeBase64(str.c_str()); + return string((const char*)&vchRet[0], vchRet.size()); +} + +string EncodeBase32(const unsigned char* pch, size_t len) +{ + static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567"; + + string strRet=""; + strRet.reserve((len+4)/5*8); + + int mode=0, left=0; + const unsigned char *pchEnd = pch+len; + + while (pch> 3]; + left = (enc & 7) << 2; + mode = 1; + break; + + case 1: // we have three bits + strRet += pbase32[left | (enc >> 6)]; + strRet += pbase32[(enc >> 1) & 31]; + left = (enc & 1) << 4; + mode = 2; + break; + + case 2: // we have one bit + strRet += pbase32[left | (enc >> 4)]; + left = (enc & 15) << 1; + mode = 3; + break; + + case 3: // we have four bits + strRet += pbase32[left | (enc >> 7)]; + strRet += pbase32[(enc >> 2) & 31]; + left = (enc & 3) << 3; + mode = 4; + break; + + case 4: // we have two bits + strRet += pbase32[left | (enc >> 5)]; + strRet += pbase32[enc & 31]; + mode = 0; + } + } + + static const int nPadding[5] = {0, 6, 4, 3, 1}; + if (mode) + { + strRet += pbase32[left]; + for (int n=0; n DecodeBase32(const char* p, bool* pfInvalid) +{ + static const int decode32_table[256] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + if (pfInvalid) + *pfInvalid = false; + + vector vchRet; + vchRet.reserve((strlen(p))*5/8); + + int mode = 0; + int left = 0; + + while (1) + { + int dec = decode32_table[(unsigned char)*p]; + if (dec == -1) break; + p++; + switch (mode) + { + case 0: // we have no bits and get 5 + left = dec; + mode = 1; + break; + + case 1: // we have 5 bits and keep 2 + vchRet.push_back((left<<3) | (dec>>2)); + left = dec & 3; + mode = 2; + break; + + case 2: // we have 2 bits and keep 7 + left = left << 5 | dec; + mode = 3; + break; + + case 3: // we have 7 bits and keep 4 + vchRet.push_back((left<<1) | (dec>>4)); + left = dec & 15; + mode = 4; + break; + + case 4: // we have 4 bits, and keep 1 + vchRet.push_back((left<<4) | (dec>>1)); + left = dec & 1; + mode = 5; + break; + + case 5: // we have 1 bit, and keep 6 + left = left << 5 | dec; + mode = 6; + break; + + case 6: // we have 6 bits, and keep 3 + vchRet.push_back((left<<2) | (dec>>3)); + left = dec & 7; + mode = 7; + break; + + case 7: // we have 3 bits, and keep 0 + vchRet.push_back((left<<5) | dec); + mode = 0; + break; + } + } + + if (pfInvalid) + switch (mode) + { + case 0: // 8n base32 characters processed: ok + break; + + case 1: // 8n+1 base32 characters processed: impossible + case 3: // +3 + case 6: // +6 + *pfInvalid = true; + break; + + case 2: // 8n+2 base32 characters processed: require '======' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1) + *pfInvalid = true; + break; + + case 4: // 8n+4 base32 characters processed: require '====' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1) + *pfInvalid = true; + break; + + case 5: // 8n+5 base32 characters processed: require '===' + if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1) + *pfInvalid = true; + break; + + case 7: // 8n+7 base32 characters processed: require '=' + if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1) + *pfInvalid = true; + break; + } + + return vchRet; +} + +string DecodeBase32(const string& str) +{ + vector vchRet = DecodeBase32(str.c_str()); + return string((const char*)&vchRet[0], vchRet.size()); +} + + +bool WildcardMatch(const char* psz, const char* mask) +{ + loop + { + switch (*mask) + { + case '\0': + return (*psz == '\0'); + case '*': + return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask)); + case '?': + if (*psz == '\0') + return false; + break; + default: + if (*psz != *mask) + return false; + break; + } + psz++; + mask++; + } +} + +bool WildcardMatch(const string& str, const string& mask) +{ + return WildcardMatch(str.c_str(), mask.c_str()); +} + + + + + + + + +static std::string FormatException(std::exception* pex, const char* pszThread) +{ +#ifdef WIN32 + char pszModule[MAX_PATH] = ""; + GetModuleFileNameA(NULL, pszModule, sizeof(pszModule)); +#else + const char* pszModule = "casinocoin"; +#endif + if (pex) + return strprintf( + "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); + else + return strprintf( + "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); +} + +void LogException(std::exception* pex, const char* pszThread) +{ + std::string message = FormatException(pex, pszThread); + printf("\n%s", message.c_str()); +} + +void PrintException(std::exception* pex, const char* pszThread) +{ + std::string message = FormatException(pex, pszThread); + printf("\n\n************************\n%s\n", message.c_str()); + fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); + strMiscWarning = message; + throw; +} + +void PrintExceptionContinue(std::exception* pex, const char* pszThread) +{ + std::string message = FormatException(pex, pszThread); + printf("\n\n************************\n%s\n", message.c_str()); + fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); + strMiscWarning = message; +} + +boost::filesystem::path GetDefaultDataDir() +{ + namespace fs = boost::filesystem; + // Windows < Vista: C:\Documents and Settings\Username\Application Data\CasinoCoin + // Windows >= Vista: C:\Users\Username\AppData\Roaming\CasinoCoin + // Mac: ~/Library/Application Support/CasinoCoin + // Unix: ~/.casinocoin +#ifdef WIN32 + // Windows + return GetSpecialFolderPath(CSIDL_APPDATA) / "CasinoCoin"; +#else + fs::path pathRet; + char* pszHome = getenv("HOME"); + if (pszHome == NULL || strlen(pszHome) == 0) + pathRet = fs::path("/"); + else + pathRet = fs::path(pszHome); +#ifdef MAC_OSX + // Mac + pathRet /= "Library/Application Support"; + fs::create_directory(pathRet); + return pathRet / "CasinoCoin"; +#else + // Unix + return pathRet / ".casinocoin"; +#endif +#endif +} + +const boost::filesystem::path &GetDataDir(bool fNetSpecific) +{ + namespace fs = boost::filesystem; + + static fs::path pathCached[2]; + static CCriticalSection csPathCached; + static bool cachedPath[2] = {false, false}; + + fs::path &path = pathCached[fNetSpecific]; + + // This can be called during exceptions by printf, so we cache the + // value so we don't have to do memory allocations after that. + if (cachedPath[fNetSpecific]) + return path; + + LOCK(csPathCached); + + if (mapArgs.count("-datadir")) { + path = fs::system_complete(mapArgs["-datadir"]); + if (!fs::is_directory(path)) { + path = ""; + return path; + } + } else { + path = GetDefaultDataDir(); + } + if (fNetSpecific && GetBoolArg("-testnet", false)) + path /= "testnet3"; + + fs::create_directory(path); + + cachedPath[fNetSpecific]=true; + return path; +} + +boost::filesystem::path GetConfigFile() +{ + boost::filesystem::path pathConfigFile(GetArg("-conf", "casinocoin.conf")); + if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile; + return pathConfigFile; +} + +void ReadConfigFile(map& mapSettingsRet, + map >& mapMultiSettingsRet) +{ + boost::filesystem::ifstream streamConfig(GetConfigFile()); + if (!streamConfig.good()) + return; // No casinocoin.conf file is OK + + set setOptions; + setOptions.insert("*"); + + for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it) + { + // Don't overwrite existing settings so command line settings override casinocoin.conf + string strKey = string("-") + it->string_key; + if (mapSettingsRet.count(strKey) == 0) + { + mapSettingsRet[strKey] = it->value[0]; + // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set) + InterpretNegativeSetting(strKey, mapSettingsRet); + } + mapMultiSettingsRet[strKey].push_back(it->value[0]); + } +} + +boost::filesystem::path GetPidFile() +{ + boost::filesystem::path pathPidFile(GetArg("-pid", "casinocoind.pid")); + if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile; + return pathPidFile; +} + +void CreatePidFile(const boost::filesystem::path &path, pid_t pid) +{ + FILE* file = fopen(path.string().c_str(), "w"); + if (file) + { + fprintf(file, "%d\n", pid); + fclose(file); + } +} + +bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest) +{ +#ifdef WIN32 + return MoveFileExA(src.string().c_str(), dest.string().c_str(), + MOVEFILE_REPLACE_EXISTING); +#else + int rc = std::rename(src.string().c_str(), dest.string().c_str()); + return (rc == 0); +#endif /* WIN32 */ +} + +void FileCommit(FILE *fileout) +{ + fflush(fileout); // harmless if redundantly called +#ifdef WIN32 + _commit(_fileno(fileout)); +#else + fsync(fileno(fileout)); +#endif +} + +int GetFilesize(FILE* file) +{ + int nSavePos = ftell(file); + int nFilesize = -1; + if (fseek(file, 0, SEEK_END) == 0) + nFilesize = ftell(file); + fseek(file, nSavePos, SEEK_SET); + return nFilesize; +} + +void ShrinkDebugFile() +{ + // Scroll debug.log if it's getting too big + boost::filesystem::path pathLog = GetDataDir() / "debug.log"; + FILE* file = fopen(pathLog.string().c_str(), "r"); + if (file && GetFilesize(file) > 10 * 1000000) + { + // Restart the file with some of the end + char pch[200000]; + fseek(file, -sizeof(pch), SEEK_END); + int nBytes = fread(pch, 1, sizeof(pch), file); + fclose(file); + + file = fopen(pathLog.string().c_str(), "w"); + if (file) + { + fwrite(pch, 1, nBytes, file); + fclose(file); + } + } +} + + + + + + + + +// +// "Never go to sea with two chronometers; take one or three." +// Our three time sources are: +// - System clock +// - Median of other nodes clocks +// - The user (asking the user to fix the system clock if the first two disagree) +// +static int64 nMockTime = 0; // For unit testing + +int64 GetTime() +{ + if (nMockTime) return nMockTime; + + return time(NULL); +} + +void SetMockTime(int64 nMockTimeIn) +{ + nMockTime = nMockTimeIn; +} + +static int64 nTimeOffset = 0; + +int64 GetAdjustedTime() +{ + return GetTime() + nTimeOffset; +} + +void AddTimeData(const CNetAddr& ip, int64 nTime) +{ + int64 nOffsetSample = nTime - GetTime(); + + // Ignore duplicates + static set setKnown; + if (!setKnown.insert(ip).second) + return; + + // Add data + vTimeOffsets.input(nOffsetSample); + printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); + if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) + { + int64 nMedian = vTimeOffsets.median(); + std::vector vSorted = vTimeOffsets.sorted(); + // Only let other nodes change our time by so much + if (abs64(nMedian) < 35 * 60) // CasinoCoin: changed maximum adjust to 35 mins to avoid letting peers change our time too much in case of an attack. + { + nTimeOffset = nMedian; + } + else + { + nTimeOffset = 0; + + static bool fDone; + if (!fDone) + { + // If nobody has a time different than ours but within 5 minutes of ours, give a warning + bool fMatch = false; + BOOST_FOREACH(int64 nOffset, vSorted) + if (nOffset != 0 && abs64(nOffset) < 5 * 60) + fMatch = true; + + if (!fMatch) + { + fDone = true; + string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong CasinoCoin will not work properly."); + strMiscWarning = strMessage; + printf("*** %s\n", strMessage.c_str()); + uiInterface.ThreadSafeMessageBox(strMessage+" ", string("CasinoCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION); + } + } + } + if (fDebug) { + BOOST_FOREACH(int64 n, vSorted) + printf("%+"PRI64d" ", n); + printf("| "); + } + printf("nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60); + } +} + + + + + + + + +string FormatVersion(int nVersion) +{ + if (nVersion%100 == 0) + return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100); + else + return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100); +} + +string FormatFullVersion() +{ + return CLIENT_BUILD; +} + +// Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014) +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments) +{ + std::ostringstream ss; + ss << "/"; + ss << name << ":" << FormatVersion(nClientVersion); + if (!comments.empty()) + ss << "(" << boost::algorithm::join(comments, "; ") << ")"; + ss << "/"; + return ss.str(); +} + +#ifdef WIN32 +boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate) +{ + namespace fs = boost::filesystem; + + char pszPath[MAX_PATH] = ""; + + if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate)) + { + return fs::path(pszPath); + } + + printf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n"); + return fs::path(""); +} +#endif + +void runCommand(std::string strCommand) +{ + int nErr = ::system(strCommand.c_str()); + if (nErr) + printf("runCommand error: system(%s) returned %d\n", strCommand.c_str(), nErr); +} + +void RenameThread(const char* name) +{ +#if defined(PR_SET_NAME) + // Only the first 15 characters are used (16 - NUL terminator) + ::prctl(PR_SET_NAME, name, 0, 0, 0); +#elif 0 && (defined(__FreeBSD__) || defined(__OpenBSD__)) + // TODO: This is currently disabled because it needs to be verified to work + // on FreeBSD or OpenBSD first. When verified the '0 &&' part can be + // removed. + pthread_set_name_np(pthread_self(), name); + +#elif defined(MAC_OSX) && defined(__MAC_OS_X_VERSION_MAX_ALLOWED) + +// pthread_setname_np is XCode 10.6-and-later +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 + pthread_setname_np(name); +#endif + +#else + // Prevent warnings for unused parameters... + (void)name; +#endif +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..2f145ea --- /dev/null +++ b/src/util.h @@ -0,0 +1,635 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_UTIL_H +#define BITCOIN_UTIL_H + +#include "uint256.h" + +#ifndef WIN32 +#include +#include +#include +#else +typedef int pid_t; /* define for windows compatiblity */ +#endif +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "netbase.h" // for AddTimeData + +typedef long long int64; +typedef unsigned long long uint64; + +static const int64 COIN = 100000000; +static const int64 CENT = 1000000; + +#define loop for (;;) +#define BEGIN(a) ((char*)&(a)) +#define END(a) ((char*)&((&(a))[1])) +#define UBEGIN(a) ((unsigned char*)&(a)) +#define UEND(a) ((unsigned char*)&((&(a))[1])) +#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) +#define printf OutputDebugStringF + +#ifndef PRI64d +#if defined(_MSC_VER) || defined(__MSVCRT__) +#define PRI64d "I64d" +#define PRI64u "I64u" +#define PRI64x "I64x" +#else +#define PRI64d "lld" +#define PRI64u "llu" +#define PRI64x "llx" +#endif +#endif + +// This is needed because the foreach macro can't get over the comma in pair +#define PAIRTYPE(t1, t2) std::pair + +// Align by increasing pointer, must have extra space at end of buffer +template +T* alignup(T* p) +{ + union + { + T* ptr; + size_t n; + } u; + u.ptr = p; + u.n = (u.n + (nBytes-1)) & ~(nBytes-1); + return u.ptr; +} + +#ifdef WIN32 +#define MSG_NOSIGNAL 0 +#define MSG_DONTWAIT 0 + +#ifndef S_IRUSR +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#endif +#define unlink _unlink +#else +#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d) +#define strlwr(psz) to_lower(psz) +#define _strlwr(psz) to_lower(psz) +#define MAX_PATH 1024 +inline void Sleep(int64 n) +{ + /*Boost has a year 2038 problem— if the request sleep time is past epoch+2^31 seconds the sleep returns instantly. + So we clamp our sleeps here to 10 years and hope that boost is fixed by 2028.*/ + boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n>315576000000LL?315576000000LL:n)); +} +#endif + + + + + + + + + +extern std::map mapArgs; +extern std::map > mapMultiArgs; +extern bool fDebug; +extern bool fDebugNet; +extern bool fPrintToConsole; +extern bool fPrintToDebugger; +extern bool fRequestShutdown; +extern bool fShutdown; +extern bool fDaemon; +extern bool fServer; +extern bool fCommandLine; +extern std::string strMiscWarning; +extern bool fTestNet; +extern bool fNoListen; +extern bool fLogTimestamps; +extern bool fReopenDebugLog; + +void RandAddSeed(); +void RandAddSeedPerfmon(); +int OutputDebugStringF(const char* pszFormat, ...); +int my_snprintf(char* buffer, size_t limit, const char* format, ...); + +/* It is not allowed to use va_start with a pass-by-reference argument. + (C++ standard, 18.7, paragraph 3). Use a dummy argument to work around this, and use a + macro to keep similar semantics. +*/ +std::string real_strprintf(const std::string &format, int dummy, ...); +#define strprintf(format, ...) real_strprintf(format, 0, __VA_ARGS__) +std::string vstrprintf(const std::string &format, va_list ap); + +bool error(const char *format, ...); +void LogException(std::exception* pex, const char* pszThread); +void PrintException(std::exception* pex, const char* pszThread); +void PrintExceptionContinue(std::exception* pex, const char* pszThread); +void ParseString(const std::string& str, char c, std::vector& v); +std::string FormatMoney(int64 n, bool fPlus=false); +bool ParseMoney(const std::string& str, int64& nRet); +bool ParseMoney(const char* pszIn, int64& nRet); +std::vector ParseHex(const char* psz); +std::vector ParseHex(const std::string& str); +bool IsHex(const std::string& str); +std::vector DecodeBase64(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase64(const std::string& str); +std::string EncodeBase64(const unsigned char* pch, size_t len); +std::string EncodeBase64(const std::string& str); +std::vector DecodeBase32(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase32(const std::string& str); +std::string EncodeBase32(const unsigned char* pch, size_t len); +std::string EncodeBase32(const std::string& str); +void ParseParameters(int argc, const char*const argv[]); +bool WildcardMatch(const char* psz, const char* mask); +bool WildcardMatch(const std::string& str, const std::string& mask); +void FileCommit(FILE *fileout); +int GetFilesize(FILE* file); +bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest); +boost::filesystem::path GetDefaultDataDir(); +const boost::filesystem::path &GetDataDir(bool fNetSpecific = true); +boost::filesystem::path GetConfigFile(); +boost::filesystem::path GetPidFile(); +void CreatePidFile(const boost::filesystem::path &path, pid_t pid); +void ReadConfigFile(std::map& mapSettingsRet, std::map >& mapMultiSettingsRet); +#ifdef WIN32 +boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); +#endif +void ShrinkDebugFile(); +int GetRandInt(int nMax); +uint64 GetRand(uint64 nMax); +uint256 GetRandHash(); +int64 GetTime(); +void SetMockTime(int64 nMockTimeIn); +int64 GetAdjustedTime(); +std::string FormatFullVersion(); +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); +void AddTimeData(const CNetAddr& ip, int64 nTime); +void runCommand(std::string strCommand); + + + + + + + + + +inline std::string i64tostr(int64 n) +{ + return strprintf("%"PRI64d, n); +} + +inline std::string itostr(int n) +{ + return strprintf("%d", n); +} + +inline int64 atoi64(const char* psz) +{ +#ifdef _MSC_VER + return _atoi64(psz); +#else + return strtoll(psz, NULL, 10); +#endif +} + +inline int64 atoi64(const std::string& str) +{ +#ifdef _MSC_VER + return _atoi64(str.c_str()); +#else + return strtoll(str.c_str(), NULL, 10); +#endif +} + +inline int atoi(const std::string& str) +{ + return atoi(str.c_str()); +} + +inline int roundint(double d) +{ + return (int)(d > 0 ? d + 0.5 : d - 0.5); +} + +inline int64 roundint64(double d) +{ + return (int64)(d > 0 ? d + 0.5 : d - 0.5); +} + +inline int64 abs64(int64 n) +{ + return (n >= 0 ? n : -n); +} + +template +std::string HexStr(const T itbegin, const T itend, bool fSpaces=false) +{ + std::vector rv; + static char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + rv.reserve((itend-itbegin)*3); + for(T it = itbegin; it < itend; ++it) + { + unsigned char val = (unsigned char)(*it); + if(fSpaces && it != itbegin) + rv.push_back(' '); + rv.push_back(hexmap[val>>4]); + rv.push_back(hexmap[val&15]); + } + + return std::string(rv.begin(), rv.end()); +} + +inline std::string HexStr(const std::vector& vch, bool fSpaces=false) +{ + return HexStr(vch.begin(), vch.end(), fSpaces); +} + +template +void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true) +{ + printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); +} + +inline void PrintHex(const std::vector& vch, const char* pszFormat="%s", bool fSpaces=true) +{ + printf(pszFormat, HexStr(vch, fSpaces).c_str()); +} + +inline int64 GetPerformanceCounter() +{ + int64 nCounter = 0; +#ifdef WIN32 + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); +#else + timeval t; + gettimeofday(&t, NULL); + nCounter = (int64) t.tv_sec * 1000000 + t.tv_usec; +#endif + return nCounter; +} + +inline int64 GetTimeMillis() +{ + return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - + boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); +} + +inline std::string DateTimeStrFormat(const char* pszFormat, int64 nTime) +{ + time_t n = nTime; + struct tm* ptmTime = gmtime(&n); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime); + return pszTime; +} + +template +void skipspaces(T& it) +{ + while (isspace(*it)) + ++it; +} + +inline bool IsSwitchChar(char c) +{ +#ifdef WIN32 + return c == '-' || c == '/'; +#else + return c == '-'; +#endif +} + +/** + * Return string argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. "1") + * @return command-line argument or default value + */ +std::string GetArg(const std::string& strArg, const std::string& strDefault); + +/** + * Return integer argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. 1) + * @return command-line argument (0 if invalid number) or default value + */ +int64 GetArg(const std::string& strArg, int64 nDefault); + +/** + * Return boolean argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (true or false) + * @return command-line argument or default value + */ +bool GetBoolArg(const std::string& strArg, bool fDefault=false); + +/** + * Set an argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param strValue Value (e.g. "1") + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetArg(const std::string& strArg, const std::string& strValue); + +/** + * Set a boolean argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param fValue Value (e.g. false) + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetBoolArg(const std::string& strArg, bool fValue); + + + + + + + + + +// Randomize the stack to help protect against buffer overrun exploits +#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \ + { \ + static char nLoops; \ + if (nLoops <= 0) \ + nLoops = GetRand(20) + 1; \ + if (nLoops-- > 1) \ + { \ + ThreadFn; \ + return; \ + } \ + } + + +template +inline uint256 Hash(const T1 pbegin, const T1 pend) +{ + static unsigned char pblank[1]; + uint256 hash1; + SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +class CHashWriter +{ +private: + SHA256_CTX ctx; + +public: + int nType; + int nVersion; + + void Init() { + SHA256_Init(&ctx); + } + + CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) { + Init(); + } + + CHashWriter& write(const char *pch, size_t size) { + SHA256_Update(&ctx, pch, size); + return (*this); + } + + // invalidates the object + uint256 GetHash() { + uint256 hash1; + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; + } + + template + CHashWriter& operator<<(const T& obj) { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } +}; + + +template +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end) +{ + static unsigned char pblank[1]; + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end, + const T3 p3begin, const T3 p3end) +{ + static unsigned char pblank[1]; + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) +{ + CHashWriter ss(nType, nVersion); + ss << obj; + return ss.GetHash(); +} + +inline uint160 Hash160(const std::vector& vch) +{ + uint256 hash1; + SHA256(&vch[0], vch.size(), (unsigned char*)&hash1); + uint160 hash2; + RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + + +/** Median filter over a stream of values. + * Returns the median of the last N numbers + */ +template class CMedianFilter +{ +private: + std::vector vValues; + std::vector vSorted; + unsigned int nSize; +public: + CMedianFilter(unsigned int size, T initial_value): + nSize(size) + { + vValues.reserve(size); + vValues.push_back(initial_value); + vSorted = vValues; + } + + void input(T value) + { + if(vValues.size() == nSize) + { + vValues.erase(vValues.begin()); + } + vValues.push_back(value); + + vSorted.resize(vValues.size()); + std::copy(vValues.begin(), vValues.end(), vSorted.begin()); + std::sort(vSorted.begin(), vSorted.end()); + } + + T median() const + { + int size = vSorted.size(); + assert(size>0); + if(size & 1) // Odd number of elements + { + return vSorted[size/2]; + } + else // Even number of elements + { + return (vSorted[size/2-1] + vSorted[size/2]) / 2; + } + } + + int size() const + { + return vValues.size(); + } + + std::vector sorted () const + { + return vSorted; + } +}; + + + + + + + + + + +// Note: It turns out we might have been able to use boost::thread +// by using TerminateThread(boost::thread.native_handle(), 0); +#ifdef WIN32 +typedef HANDLE pthread_t; + +inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) +{ + DWORD nUnused = 0; + HANDLE hthread = + CreateThread( + NULL, // default security + 0, // inherit stack size from parent + (LPTHREAD_START_ROUTINE)pfn, // function pointer + parg, // argument + 0, // creation option, start immediately + &nUnused); // thread identifier + if (hthread == NULL) + { + printf("Error: CreateThread() returned %d\n", GetLastError()); + return (pthread_t)0; + } + if (!fWantHandle) + { + CloseHandle(hthread); + return (pthread_t)-1; + } + return hthread; +} + +inline void SetThreadPriority(int nPriority) +{ + SetThreadPriority(GetCurrentThread(), nPriority); +} +#else +inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) +{ + pthread_t hthread = 0; + int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg); + if (ret != 0) + { + printf("Error: pthread_create() returned %d\n", ret); + return (pthread_t)0; + } + if (!fWantHandle) + { + pthread_detach(hthread); + return (pthread_t)-1; + } + return hthread; +} + +#define THREAD_PRIORITY_LOWEST PRIO_MAX +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 + +inline void SetThreadPriority(int nPriority) +{ + // It's unclear if it's even possible to change thread priorities on Linux, + // but we really and truly need it for the generation threads. +#ifdef PRIO_THREAD + setpriority(PRIO_THREAD, 0, nPriority); +#else + setpriority(PRIO_PROCESS, 0, nPriority); +#endif +} + +inline void ExitThread(size_t nExitCode) +{ + pthread_exit((void*)nExitCode); +} +#endif + +void RenameThread(const char* name); + +inline uint32_t ByteReverse(uint32_t value) +{ + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return (value<<16) | (value>>16); +} + +#endif + diff --git a/src/version.cpp b/src/version.cpp new file mode 100644 index 0000000..5bba575 --- /dev/null +++ b/src/version.cpp @@ -0,0 +1,69 @@ +// Copyright (c) 2012 The Bitcoin developers +// Copyright (c) 2012 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include + +#include "version.h" + +// Name of client reported in the 'version' message. Report the same name +// for both bitcoind and bitcoin-qt, to make it harder for attackers to +// target servers or GUI users specifically. +const std::string CLIENT_NAME("transcoder"); + +// Client version number +#define CLIENT_VERSION_SUFFIX "-beta" + + +// The following part of the code determines the CLIENT_BUILD variable. +// Several mechanisms are used for this: +// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is +// generated by the build environment, possibly containing the output +// of git-describe in a macro called BUILD_DESC +// * secondly, if this is an exported version of the code, GIT_ARCHIVE will +// be defined (automatically using the export-subst git attribute), and +// GIT_COMMIT will contain the commit id. +// * then, three options exist for determining CLIENT_BUILD: +// * if BUILD_DESC is defined, use that literally (output of git-describe) +// * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit] +// * otherwise, use v[maj].[min].[rev].[build]-unk +// finally CLIENT_VERSION_SUFFIX is added + +// First, include build.h if requested +#ifdef HAVE_BUILD_INFO +# include "build.h" +#endif + +// git will put "#define GIT_ARCHIVE 1" on the next line inside archives. +#define GIT_ARCHIVE 1 +#ifdef GIT_ARCHIVE +# define GIT_COMMIT_ID "" +# define GIT_COMMIT_DATE "" +#endif + +#define STRINGIFY(s) #s + +#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \ + "v" STRINGIFY(maj) "." STRINGIFY(min) "." STRINGIFY(rev) "." STRINGIFY(build) "-g" commit + +#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \ + "v" STRINGIFY(maj) "." STRINGIFY(min) "." STRINGIFY(rev) "." STRINGIFY(build) "-unk" + +#ifndef BUILD_DESC +# ifdef GIT_COMMIT_ID +# define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID) +# else +# define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD) +# endif +#endif + +#ifndef BUILD_DATE +# ifdef GIT_COMMIT_DATE +# define BUILD_DATE GIT_COMMIT_DATE +# else +# define BUILD_DATE __DATE__ ", " __TIME__ +# endif +#endif + +const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX); +const std::string CLIENT_DATE(BUILD_DATE); diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..cc0f1a6 --- /dev/null +++ b/src/version.h @@ -0,0 +1,50 @@ +// Copyright (c) 2012 The Bitcoin developers +// Copyright (c) 2012 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_VERSION_H +#define BITCOIN_VERSION_H + +#include + +// +// client versioning +// + +// These need to be macro's, as version.cpp's voodoo requires it +#define CLIENT_VERSION_MAJOR 1 +#define CLIENT_VERSION_MINOR 0 +#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_BUILD 3 + +static const int CLIENT_VERSION = + 1000000 * CLIENT_VERSION_MAJOR + + 10000 * CLIENT_VERSION_MINOR + + 100 * CLIENT_VERSION_REVISION + + 1 * CLIENT_VERSION_BUILD; + +extern const std::string CLIENT_NAME; +extern const std::string CLIENT_BUILD; +extern const std::string CLIENT_DATE; + +// +// network protocol versioning +// + +static const int PROTOCOL_VERSION = 60002; + +// earlier versions not supported as of Feb 2012, and are disconnected +static const int MIN_PROTO_VERSION = 209; + +// nTime field added to CAddress, starting with this version; +// if possible, avoid requesting addresses nodes older than this +static const int CADDR_TIME_VERSION = 31402; + +// only request blocks from nodes outside this range of versions +static const int NOBLKS_VERSION_START = 32000; +static const int NOBLKS_VERSION_END = 32400; + +// BIP 0031, pong message, is enabled for all versions AFTER this one +static const int BIP0031_VERSION = 60000; + +#endif diff --git a/src/wallet.cpp b/src/wallet.cpp new file mode 100644 index 0000000..9857d79 --- /dev/null +++ b/src/wallet.cpp @@ -0,0 +1,1617 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "wallet.h" +#include "walletdb.h" +#include "crypter.h" +#include "ui_interface.h" +#include "base58.h" + +using namespace std; + + +////////////////////////////////////////////////////////////////////////////// +// +// mapWallet +// + +struct CompareValueOnly +{ + bool operator()(const pair >& t1, + const pair >& t2) const + { + return t1.first < t2.first; + } +}; + +CPubKey CWallet::GenerateNewKey() +{ + bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets + + RandAddSeedPerfmon(); + CKey key; + key.MakeNewKey(fCompressed); + + // Compressed public keys were introduced in version 0.6.0 + if (fCompressed) + SetMinVersion(FEATURE_COMPRPUBKEY); + + if (!AddKey(key)) + throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed"); + return key.GetPubKey(); +} + +bool CWallet::AddKey(const CKey& key) +{ + if (!CCryptoKeyStore::AddKey(key)) + return false; + if (!fFileBacked) + return true; + if (!IsCrypted()) + return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey()); + return true; +} + +bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector &vchCryptedSecret) +{ + if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) + return false; + if (!fFileBacked) + return true; + { + LOCK(cs_wallet); + if (pwalletdbEncryption) + return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret); + else + return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret); + } + return false; +} + +bool CWallet::AddCScript(const CScript& redeemScript) +{ + if (!CCryptoKeyStore::AddCScript(redeemScript)) + return false; + if (!fFileBacked) + return true; + return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript); +} + +bool CWallet::Unlock(const SecureString& strWalletPassphrase) +{ + if (!IsLocked()) + return false; + + CCrypter crypter; + CKeyingMaterial vMasterKey; + + { + LOCK(cs_wallet); + BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (CCryptoKeyStore::Unlock(vMasterKey)) + return true; + } + } + return false; +} + +bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase) +{ + bool fWasLocked = IsLocked(); + + { + LOCK(cs_wallet); + Lock(); + + CCrypter crypter; + CKeyingMaterial vMasterKey; + BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (CCryptoKeyStore::Unlock(vMasterKey)) + { + int64 nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (pMasterKey.second.nDeriveIterations < 25000) + pMasterKey.second.nDeriveIterations = 25000; + + printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey)) + return false; + CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second); + if (fWasLocked) + Lock(); + return true; + } + } + } + + return false; +} + +void CWallet::SetBestChain(const CBlockLocator& loc) +{ + CWalletDB walletdb(strWalletFile); + walletdb.WriteBestBlock(loc); +} + +// This class implements an addrIncoming entry that causes pre-0.4 +// clients to crash on startup if reading a private-key-encrypted wallet. +class CCorruptAddress +{ +public: + IMPLEMENT_SERIALIZE + ( + if (nType & SER_DISK) + READWRITE(nVersion); + ) +}; + +bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit) +{ + if (nWalletVersion >= nVersion) + return true; + + // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way + if (fExplicit && nVersion > nWalletMaxVersion) + nVersion = FEATURE_LATEST; + + nWalletVersion = nVersion; + + if (nVersion > nWalletMaxVersion) + nWalletMaxVersion = nVersion; + + if (fFileBacked) + { + CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile); + if (nWalletVersion >= 40000) + { + // Versions prior to 0.4.0 did not support the "minversion" record. + // Use a CCorruptAddress to make them crash instead. + CCorruptAddress corruptAddress; + pwalletdb->WriteSetting("addrIncoming", corruptAddress); + } + if (nWalletVersion > 40000) + pwalletdb->WriteMinVersion(nWalletVersion); + if (!pwalletdbIn) + delete pwalletdb; + } + + return true; +} + +bool CWallet::SetMaxVersion(int nVersion) +{ + // cannot downgrade below current version + if (nWalletVersion > nVersion) + return false; + + nWalletMaxVersion = nVersion; + + return true; +} + +bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) +{ + if (IsCrypted()) + return false; + + CKeyingMaterial vMasterKey; + RandAddSeedPerfmon(); + + vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); + RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); + + CMasterKey kMasterKey; + + RandAddSeedPerfmon(); + kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); + RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); + + CCrypter crypter; + int64 nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime)); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (kMasterKey.nDeriveIterations < 25000) + kMasterKey.nDeriveIterations = 25000; + + printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) + return false; + + { + LOCK(cs_wallet); + mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; + if (fFileBacked) + { + pwalletdbEncryption = new CWalletDB(strWalletFile); + if (!pwalletdbEncryption->TxnBegin()) + return false; + pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); + } + + if (!EncryptKeys(vMasterKey)) + { + if (fFileBacked) + pwalletdbEncryption->TxnAbort(); + exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet. + } + + // Encryption was introduced in version 0.4.0 + SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true); + + if (fFileBacked) + { + if (!pwalletdbEncryption->TxnCommit()) + exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet. + + delete pwalletdbEncryption; + pwalletdbEncryption = NULL; + } + + Lock(); + Unlock(strWalletPassphrase); + NewKeyPool(); + Lock(); + + // Need to completely rewrite the wallet file; if we don't, bdb might keep + // bits of the unencrypted private key in slack space in the database file. + CDB::Rewrite(strWalletFile); + + } + NotifyStatusChanged(this); + + return true; +} + +void CWallet::WalletUpdateSpent(const CTransaction &tx) +{ + // Anytime a signature is successfully verified, it's proof the outpoint is spent. + // Update the wallet spent flag if it doesn't know due to wallet.dat being + // restored from backup or the user making copies of wallet.dat. + { + LOCK(cs_wallet); + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + map::iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + CWalletTx& wtx = (*mi).second; + if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n])) + { + printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.MarkSpent(txin.prevout.n); + wtx.WriteToDisk(); + NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED); + } + } + } + } +} + +void CWallet::MarkDirty() +{ + { + LOCK(cs_wallet); + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + item.second.MarkDirty(); + } +} + +bool CWallet::AddToWallet(const CWalletTx& wtxIn) +{ + uint256 hash = wtxIn.GetHash(); + { + LOCK(cs_wallet); + // Inserts only if not already there, returns tx inserted or tx found + pair::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); + CWalletTx& wtx = (*ret.first).second; + wtx.BindWallet(this); + bool fInsertedNew = ret.second; + if (fInsertedNew) + wtx.nTimeReceived = GetAdjustedTime(); + + bool fUpdated = false; + if (!fInsertedNew) + { + // Merge + if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) + { + wtx.hashBlock = wtxIn.hashBlock; + fUpdated = true; + } + if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex)) + { + wtx.vMerkleBranch = wtxIn.vMerkleBranch; + wtx.nIndex = wtxIn.nIndex; + fUpdated = true; + } + if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe) + { + wtx.fFromMe = wtxIn.fFromMe; + fUpdated = true; + } + fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent); + } + + //// debug print + printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); + + // Write to disk + if (fInsertedNew || fUpdated) + if (!wtx.WriteToDisk()) + return false; +#ifndef QT_GUI + // If default receiving address gets used, replace it with a new one + CScript scriptDefaultKey; + scriptDefaultKey.SetDestination(vchDefaultKey.GetID()); + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if (txout.scriptPubKey == scriptDefaultKey) + { + CPubKey newDefaultKey; + if (GetKeyFromPool(newDefaultKey, false)) + { + SetDefaultKey(newDefaultKey); + SetAddressBookName(vchDefaultKey.GetID(), ""); + } + } + } +#endif + // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins + WalletUpdateSpent(wtx); + + // Notify UI of new or updated transaction + NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED); + } + return true; +} + +// Add a transaction to the wallet, or update it. +// pblock is optional, but should be provided if the transaction is known to be in a block. +// If fUpdate is true, existing transactions will be updated. +bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock) +{ + uint256 hash = tx.GetHash(); + { + LOCK(cs_wallet); + bool fExisted = mapWallet.count(hash); + if (fExisted && !fUpdate) return false; + if (fExisted || IsMine(tx) || IsFromMe(tx)) + { + CWalletTx wtx(this,tx); + // Get merkle branch if transaction was found in a block + if (pblock) + wtx.SetMerkleBranch(pblock); + return AddToWallet(wtx); + } + else + WalletUpdateSpent(tx); + } + return false; +} + +bool CWallet::EraseFromWallet(uint256 hash) +{ + if (!fFileBacked) + return false; + { + LOCK(cs_wallet); + if (mapWallet.erase(hash)) + CWalletDB(strWalletFile).EraseTx(hash); + } + return true; +} + + +bool CWallet::IsMine(const CTxIn &txin) const +{ + { + LOCK(cs_wallet); + map::const_iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (txin.prevout.n < prev.vout.size()) + if (IsMine(prev.vout[txin.prevout.n])) + return true; + } + } + return false; +} + +int64 CWallet::GetDebit(const CTxIn &txin) const +{ + { + LOCK(cs_wallet); + map::const_iterator mi = mapWallet.find(txin.prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (txin.prevout.n < prev.vout.size()) + if (IsMine(prev.vout[txin.prevout.n])) + return prev.vout[txin.prevout.n].nValue; + } + } + return 0; +} + +bool CWallet::IsChange(const CTxOut& txout) const +{ + CTxDestination address; + + // TODO: fix handling of 'change' outputs. The assumption is that any + // payment to a TX_PUBKEYHASH that is mine but isn't in the address book + // is change. That assumption is likely to break when we implement multisignature + // wallets that return change back into a multi-signature-protected address; + // a better way of identifying which outputs are 'the send' and which are + // 'the change' will need to be implemented (maybe extend CWalletTx to remember + // which output, if any, was change). + if (ExtractDestination(txout.scriptPubKey, address) && ::IsMine(*this, address)) + { + LOCK(cs_wallet); + if (!mapAddressBook.count(address)) + return true; + } + return false; +} + +int64 CWalletTx::GetTxTime() const +{ + return nTimeReceived; +} + +int CWalletTx::GetRequestCount() const +{ + // Returns -1 if it wasn't being tracked + int nRequests = -1; + { + LOCK(pwallet->cs_wallet); + if (IsCoinBase()) + { + // Generated block + if (hashBlock != 0) + { + map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); + if (mi != pwallet->mapRequestCount.end()) + nRequests = (*mi).second; + } + } + else + { + // Did anyone request this transaction? + map::const_iterator mi = pwallet->mapRequestCount.find(GetHash()); + if (mi != pwallet->mapRequestCount.end()) + { + nRequests = (*mi).second; + + // How about the block it's in? + if (nRequests == 0 && hashBlock != 0) + { + map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); + if (mi != pwallet->mapRequestCount.end()) + nRequests = (*mi).second; + else + nRequests = 1; // If it's in someone else's block it must have got out + } + } + } + } + return nRequests; +} + +void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list >& listReceived, + list >& listSent, int64& nFee, string& strSentAccount) const +{ + nGeneratedImmature = nGeneratedMature = nFee = 0; + listReceived.clear(); + listSent.clear(); + strSentAccount = strFromAccount; + + if (IsCoinBase()) + { + if (GetBlocksToMaturity() > 0) + nGeneratedImmature = pwallet->GetCredit(*this); + else + nGeneratedMature = GetCredit(); + return; + } + + // Compute fee: + int64 nDebit = GetDebit(); + if (nDebit > 0) // debit>0 means we signed/sent this transaction + { + int64 nValueOut = GetValueOut(); + nFee = nDebit - nValueOut; + } + + // Sent/received. + BOOST_FOREACH(const CTxOut& txout, vout) + { + CTxDestination address; + vector vchPubKey; + if (!ExtractDestination(txout.scriptPubKey, address)) + { + printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", + this->GetHash().ToString().c_str()); + } + + // Don't report 'change' txouts + if (nDebit > 0 && pwallet->IsChange(txout)) + continue; + + if (nDebit > 0) + listSent.push_back(make_pair(address, txout.nValue)); + + if (pwallet->IsMine(txout)) + listReceived.push_back(make_pair(address, txout.nValue)); + } + +} + +void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, + int64& nSent, int64& nFee) const +{ + nGenerated = nReceived = nSent = nFee = 0; + + int64 allGeneratedImmature, allGeneratedMature, allFee; + allGeneratedImmature = allGeneratedMature = allFee = 0; + string strSentAccount; + list > listReceived; + list > listSent; + GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); + + if (strAccount == "") + nGenerated = allGeneratedMature; + if (strAccount == strSentAccount) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& s, listSent) + nSent += s.second; + nFee = allFee; + } + { + LOCK(pwallet->cs_wallet); + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived) + { + if (pwallet->mapAddressBook.count(r.first)) + { + map::const_iterator mi = pwallet->mapAddressBook.find(r.first); + if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount) + nReceived += r.second; + } + else if (strAccount.empty()) + { + nReceived += r.second; + } + } + } +} + +void CWalletTx::AddSupportingTransactions(CTxDB& txdb) +{ + vtxPrev.clear(); + + const int COPY_DEPTH = 3; + if (SetMerkleBranch() < COPY_DEPTH) + { + vector vWorkQueue; + BOOST_FOREACH(const CTxIn& txin, vin) + vWorkQueue.push_back(txin.prevout.hash); + + // This critsect is OK because txdb is already open + { + LOCK(pwallet->cs_wallet); + map mapWalletPrev; + set setAlreadyDone; + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hash = vWorkQueue[i]; + if (setAlreadyDone.count(hash)) + continue; + setAlreadyDone.insert(hash); + + CMerkleTx tx; + map::const_iterator mi = pwallet->mapWallet.find(hash); + if (mi != pwallet->mapWallet.end()) + { + tx = (*mi).second; + BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev) + mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev; + } + else if (mapWalletPrev.count(hash)) + { + tx = *mapWalletPrev[hash]; + } + else if (!fClient && txdb.ReadDiskTx(hash, tx)) + { + ; + } + else + { + printf("ERROR: AddSupportingTransactions() : unsupported transaction\n"); + continue; + } + + int nDepth = tx.SetMerkleBranch(); + vtxPrev.push_back(tx); + + if (nDepth < COPY_DEPTH) + { + BOOST_FOREACH(const CTxIn& txin, tx.vin) + vWorkQueue.push_back(txin.prevout.hash); + } + } + } + } + + reverse(vtxPrev.begin(), vtxPrev.end()); +} + +bool CWalletTx::WriteToDisk() +{ + return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); +} + +// Scan the block chain (starting in pindexStart) for transactions +// from or to us. If fUpdate is true, found transactions that already +// exist in the wallet will be updated. +int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) +{ + int ret = 0; + + CBlockIndex* pindex = pindexStart; + { + LOCK(cs_wallet); + while (pindex) + { + CBlock block; + block.ReadFromDisk(pindex, true); + BOOST_FOREACH(CTransaction& tx, block.vtx) + { + if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) + ret++; + } + pindex = pindex->pnext; + } + } + return ret; +} + +int CWallet::ScanForWalletTransaction(const uint256& hashTx) +{ + CTransaction tx; + tx.ReadFromDisk(COutPoint(hashTx, 0)); + if (AddToWalletIfInvolvingMe(tx, NULL, true, true)) + return 1; + return 0; +} + +void CWallet::ReacceptWalletTransactions() +{ + CTxDB txdb("r"); + bool fRepeat = true; + while (fRepeat) + { + LOCK(cs_wallet); + fRepeat = false; + vector vMissingTx; + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + if (wtx.IsCoinBase() && wtx.IsSpent(0)) + continue; + + CTxIndex txindex; + bool fUpdated = false; + if (txdb.ReadTxIndex(wtx.GetHash(), txindex)) + { + // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat + if (txindex.vSpent.size() != wtx.vout.size()) + { + printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size()); + continue; + } + for (unsigned int i = 0; i < txindex.vSpent.size(); i++) + { + if (wtx.IsSpent(i)) + continue; + if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i])) + { + wtx.MarkSpent(i); + fUpdated = true; + vMissingTx.push_back(txindex.vSpent[i]); + } + } + if (fUpdated) + { + printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.MarkDirty(); + wtx.WriteToDisk(); + } + } + else + { + // Reaccept any txes of ours that aren't already in a block + if (!wtx.IsCoinBase()) + wtx.AcceptWalletTransaction(txdb, false); + } + } + if (!vMissingTx.empty()) + { + // TODO: optimize this to scan just part of the block chain? + if (ScanForWalletTransactions(pindexGenesisBlock)) + fRepeat = true; // Found missing transactions: re-do Reaccept. + } + } +} + +void CWalletTx::RelayWalletTransaction(CTxDB& txdb) +{ + BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) + { + if (!tx.IsCoinBase()) + { + uint256 hash = tx.GetHash(); + if (!txdb.ContainsTx(hash)) + RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx); + } + } + if (!IsCoinBase()) + { + uint256 hash = GetHash(); + if (!txdb.ContainsTx(hash)) + { + printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str()); + RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); + } + } +} + +void CWalletTx::RelayWalletTransaction() +{ + CTxDB txdb("r"); + RelayWalletTransaction(txdb); +} + +void CWallet::ResendWalletTransactions() +{ + // Do this infrequently and randomly to avoid giving away + // that these are our transactions. + static int64 nNextTime; + if (GetTime() < nNextTime) + return; + bool fFirst = (nNextTime == 0); + nNextTime = GetTime() + GetRand(30 * 60); + if (fFirst) + return; + + // Only do it if there's been a new block since last time + static int64 nLastTime; + if (nTimeBestReceived < nLastTime) + return; + nLastTime = GetTime(); + + // Rebroadcast any of our txes that aren't in a block yet + printf("ResendWalletTransactions()\n"); + CTxDB txdb("r"); + { + LOCK(cs_wallet); + // Sort them in chronological order + multimap mapSorted; + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + // Don't rebroadcast until it's had plenty of time that + // it should have gotten in already by now. + if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60) + mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + } + BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) + { + CWalletTx& wtx = *item.second; + wtx.RelayWalletTransaction(txdb); + } + } +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Actions +// + + +int64 CWallet::GetBalance() const +{ + int64 nTotal = 0; + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsFinal() && pcoin->IsConfirmed()) + nTotal += pcoin->GetAvailableCredit(); + } + } + + return nTotal; +} + +int64 CWallet::GetUnconfirmedBalance() const +{ + int64 nTotal = 0; + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (!pcoin->IsFinal() || !pcoin->IsConfirmed()) + nTotal += pcoin->GetAvailableCredit(); + } + } + return nTotal; +} + +int64 CWallet::GetImmatureBalance() const +{ + int64 nTotal = 0; + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& pcoin = (*it).second; + if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.GetDepthInMainChain() >= 2) + nTotal += GetCredit(pcoin); + } + } + return nTotal; +} + +// populate vCoins with vector of spendable COutputs +void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed) const +{ + vCoins.clear(); + + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + if (!pcoin->IsFinal()) + continue; + + if (fOnlyConfirmed && !pcoin->IsConfirmed()) + continue; + + if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) + continue; + + // If output is less than minimum value, then don't include transaction. + // This is to help deal with dust spam clogging up create transactions. + for (unsigned int i = 0; i < pcoin->vout.size(); i++) + if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue >= nMinimumInputValue) + vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); + } + } +} + +static void ApproximateBestSubset(vector > >vValue, int64 nTotalLower, int64 nTargetValue, + vector& vfBest, int64& nBest, int iterations = 1000) +{ + vector vfIncluded; + + vfBest.assign(vValue.size(), true); + nBest = nTotalLower; + + for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++) + { + vfIncluded.assign(vValue.size(), false); + int64 nTotal = 0; + bool fReachedTarget = false; + for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) + { + for (unsigned int i = 0; i < vValue.size(); i++) + { + if (nPass == 0 ? rand() % 2 : !vfIncluded[i]) + { + nTotal += vValue[i].first; + vfIncluded[i] = true; + if (nTotal >= nTargetValue) + { + fReachedTarget = true; + if (nTotal < nBest) + { + nBest = nTotal; + vfBest = vfIncluded; + } + nTotal -= vValue[i].first; + vfIncluded[i] = false; + } + } + } + } + } +} + +bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, vector vCoins, + set >& setCoinsRet, int64& nValueRet) const +{ + setCoinsRet.clear(); + nValueRet = 0; + + // List of values less than target + pair > coinLowestLarger; + coinLowestLarger.first = std::numeric_limits::max(); + coinLowestLarger.second.first = NULL; + vector > > vValue; + int64 nTotalLower = 0; + + random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); + + BOOST_FOREACH(COutput output, vCoins) + { + const CWalletTx *pcoin = output.tx; + + if (output.nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs)) + continue; + + int i = output.i; + int64 n = pcoin->vout[i].nValue; + + pair > coin = make_pair(n,make_pair(pcoin, i)); + + if (n == nTargetValue) + { + setCoinsRet.insert(coin.second); + nValueRet += coin.first; + return true; + } + else if (n < nTargetValue + CENT) + { + vValue.push_back(coin); + nTotalLower += n; + } + else if (n < coinLowestLarger.first) + { + coinLowestLarger = coin; + } + } + + if (nTotalLower == nTargetValue) + { + for (unsigned int i = 0; i < vValue.size(); ++i) + { + setCoinsRet.insert(vValue[i].second); + nValueRet += vValue[i].first; + } + return true; + } + + if (nTotalLower < nTargetValue) + { + if (coinLowestLarger.second.first == NULL) + return false; + setCoinsRet.insert(coinLowestLarger.second); + nValueRet += coinLowestLarger.first; + return true; + } + + // Solve subset sum by stochastic approximation + sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); + vector vfBest; + int64 nBest; + + ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000); + if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT) + ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000); + + // If we have a bigger coin and (either the stochastic approximation didn't find a good solution, + // or the next bigger coin is closer), return the bigger coin + if (coinLowestLarger.second.first && + ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest)) + { + setCoinsRet.insert(coinLowestLarger.second); + nValueRet += coinLowestLarger.first; + } + else { + for (unsigned int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + { + setCoinsRet.insert(vValue[i].second); + nValueRet += vValue[i].first; + } + + //// debug print + printf("SelectCoins() best subset: "); + for (unsigned int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + printf("%s ", FormatMoney(vValue[i].first).c_str()); + printf("total %s\n", FormatMoney(nBest).c_str()); + } + + return true; +} + +bool CWallet::SelectCoins(int64 nTargetValue, set >& setCoinsRet, int64& nValueRet) const +{ + vector vCoins; + AvailableCoins(vCoins); + + return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) || + SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) || + SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet)); +} + + + + +bool CWallet::CreateTransaction(const vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet) +{ + int64 nValue = 0; + BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend) + { + if (nValue < 0) + return false; + nValue += s.second; + } + if (vecSend.empty() || nValue < 0) + return false; + + wtxNew.BindWallet(this); + + { + LOCK2(cs_main, cs_wallet); + // txdb must be opened before the mapWallet lock + CTxDB txdb("r"); + { + nFeeRet = nTransactionFee; + loop + { + wtxNew.vin.clear(); + wtxNew.vout.clear(); + wtxNew.fFromMe = true; + + int64 nTotalValue = nValue + nFeeRet; + double dPriority = 0; + // vouts to the payees + BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend) + wtxNew.vout.push_back(CTxOut(s.second, s.first)); + + // Choose coins to use + set > setCoins; + int64 nValueIn = 0; + if (!SelectCoins(nTotalValue, setCoins, nValueIn)) + return false; + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + int64 nCredit = pcoin.first->vout[pcoin.second].nValue; + dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain(); + } + + int64 nChange = nValueIn - nValue - nFeeRet; + // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE + // or until nChange becomes zero + // NOTE: this depends on the exact behaviour of GetMinFee + if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT) + { + int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet); + nChange -= nMoveToFee; + nFeeRet += nMoveToFee; + } + + if (nChange > 0) + { + // Note: We use a new key here to keep it from being obvious which side is the change. + // The drawback is that by not reusing a previous key, the change may be lost if a + // backup is restored, if the backup doesn't have the new private key for the change. + // If we reused the old key, it would be possible to add code to look for and + // rediscover unknown transactions that were written with keys of ours to recover + // post-backup change. + + // Reserve a new key pair from key pool + CPubKey vchPubKey = reservekey.GetReservedKey(); + // assert(mapKeys.count(vchPubKey)); + + // Fill a vout to ourself + // TODO: pass in scriptChange instead of reservekey so + // change transaction isn't always pay-to-bitcoin-address + CScript scriptChange; + scriptChange.SetDestination(vchPubKey.GetID()); + + // Insert change txn at random position: + vector::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()); + wtxNew.vout.insert(position, CTxOut(nChange, scriptChange)); + } + else + reservekey.ReturnKey(); + + // Fill vin + BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) + wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second)); + + // Sign + int nIn = 0; + BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) + if (!SignSignature(*this, *coin.first, wtxNew, nIn++)) + return false; + + // Limit size + unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION); + if (nBytes >= MAX_BLOCK_SIZE_GEN/5) + return false; + dPriority /= nBytes; + + // Check that enough fee is included + int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000); + bool fAllowFree = CTransaction::AllowFree(dPriority); + int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND); + if (nFeeRet < max(nPayFee, nMinFee)) + { + nFeeRet = max(nPayFee, nMinFee); + continue; + } + + // Fill vtxPrev by copying from previous transactions vtxPrev + wtxNew.AddSupportingTransactions(txdb); + wtxNew.fTimeReceivedIsTxTime = true; + + break; + } + } + } + return true; +} + +bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet) +{ + vector< pair > vecSend; + vecSend.push_back(make_pair(scriptPubKey, nValue)); + return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet); +} + +// Call after CreateTransaction unless you want to abort +bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) +{ + { + LOCK2(cs_main, cs_wallet); + printf("CommitTransaction:\n%s", wtxNew.ToString().c_str()); + { + // This is only to keep the database open to defeat the auto-flush for the + // duration of this scope. This is the only place where this optimization + // maybe makes sense; please don't do it anywhere else. + CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL; + + // Take key pair from key pool so it won't be used again + reservekey.KeepKey(); + + // Add tx to wallet, because if it has change it's also ours, + // otherwise just for transaction history. + AddToWallet(wtxNew); + + // Mark old coins as spent + set setCoins; + BOOST_FOREACH(const CTxIn& txin, wtxNew.vin) + { + CWalletTx &coin = mapWallet[txin.prevout.hash]; + coin.BindWallet(this); + coin.MarkSpent(txin.prevout.n); + coin.WriteToDisk(); + NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED); + } + + if (fFileBacked) + delete pwalletdb; + } + + // Track how many getdata requests our transaction gets + mapRequestCount[wtxNew.GetHash()] = 0; + + // Broadcast + if (!wtxNew.AcceptToMemoryPool()) + { + // This must not fail. The transaction has already been signed and recorded. + printf("CommitTransaction() : Error: Transaction not valid"); + return false; + } + wtxNew.RelayWalletTransaction(); + } + return true; +} + + + + +string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee) +{ + CReserveKey reservekey(this); + int64 nFeeRequired; + + if (IsLocked()) + { + string strError = _("Error: Wallet locked, unable to create transaction "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) + { + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str()); + else + strError = _("Error: Transaction creation failed "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } + + if (fAskFee && !uiInterface.ThreadSafeAskFee(nFeeRequired, _("Sending..."))) + return "ABORTED"; + + if (!CommitTransaction(wtxNew, reservekey)) + return _("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."); + + return ""; +} + + + +string CWallet::SendMoneyToDestination(const CTxDestination& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee) +{ + // Check amount + if (nValue <= 0) + return _("Invalid amount"); + if (nValue + nTransactionFee > GetBalance()) + return _("Insufficient funds"); + + // Parse Bitcoin address + CScript scriptPubKey; + scriptPubKey.SetDestination(address); + + return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee); +} + + + + +int CWallet::LoadWallet(bool& fFirstRunRet) +{ + if (!fFileBacked) + return false; + fFirstRunRet = false; + int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this); + if (nLoadWalletRet == DB_NEED_REWRITE) + { + if (CDB::Rewrite(strWalletFile, "\x04pool")) + { + setKeyPool.clear(); + // Note: can't top-up keypool here, because wallet is locked. + // User will be prompted to unlock wallet the next operation + // the requires a new key. + } + nLoadWalletRet = DB_NEED_REWRITE; + } + + if (nLoadWalletRet != DB_LOAD_OK) + return nLoadWalletRet; + fFirstRunRet = !vchDefaultKey.IsValid(); + + CreateThread(ThreadFlushWalletDB, &strWalletFile); + return DB_LOAD_OK; +} + + +bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName) +{ + std::map::iterator mi = mapAddressBook.find(address); + mapAddressBook[address] = strName; + NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED); + if (!fFileBacked) + return false; + return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName); +} + +bool CWallet::DelAddressBookName(const CTxDestination& address) +{ + mapAddressBook.erase(address); + NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED); + if (!fFileBacked) + return false; + return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString()); +} + + +void CWallet::PrintWallet(const CBlock& block) +{ + { + LOCK(cs_wallet); + if (mapWallet.count(block.vtx[0].GetHash())) + { + CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()]; + printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); + } + } + printf("\n"); +} + +bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx) +{ + { + LOCK(cs_wallet); + map::iterator mi = mapWallet.find(hashTx); + if (mi != mapWallet.end()) + { + wtx = (*mi).second; + return true; + } + } + return false; +} + +bool CWallet::SetDefaultKey(const CPubKey &vchPubKey) +{ + if (fFileBacked) + { + if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey)) + return false; + } + vchDefaultKey = vchPubKey; + return true; +} + +bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut) +{ + if (!pwallet->fFileBacked) + return false; + strWalletFileOut = pwallet->strWalletFile; + return true; +} + +// +// Mark old keypool keys as used, +// and generate all new keys +// +bool CWallet::NewKeyPool() +{ + { + LOCK(cs_wallet); + CWalletDB walletdb(strWalletFile); + BOOST_FOREACH(int64 nIndex, setKeyPool) + walletdb.ErasePool(nIndex); + setKeyPool.clear(); + + if (IsLocked()) + return false; + + int64 nKeys = max(GetArg("-keypool", 100), (int64)0); + for (int i = 0; i < nKeys; i++) + { + int64 nIndex = i+1; + walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey())); + setKeyPool.insert(nIndex); + } + printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys); + } + return true; +} + +bool CWallet::TopUpKeyPool() +{ + { + LOCK(cs_wallet); + + if (IsLocked()) + return false; + + CWalletDB walletdb(strWalletFile); + + // Top up key pool + unsigned int nTargetSize = max(GetArg("-keypool", 100), 0LL); + while (setKeyPool.size() < (nTargetSize + 1)) + { + int64 nEnd = 1; + if (!setKeyPool.empty()) + nEnd = *(--setKeyPool.end()) + 1; + if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) + throw runtime_error("TopUpKeyPool() : writing generated key failed"); + setKeyPool.insert(nEnd); + printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size()); + } + } + return true; +} + +void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) +{ + nIndex = -1; + keypool.vchPubKey = CPubKey(); + { + LOCK(cs_wallet); + + if (!IsLocked()) + TopUpKeyPool(); + + // Get the oldest key + if(setKeyPool.empty()) + return; + + CWalletDB walletdb(strWalletFile); + + nIndex = *(setKeyPool.begin()); + setKeyPool.erase(setKeyPool.begin()); + if (!walletdb.ReadPool(nIndex, keypool)) + throw runtime_error("ReserveKeyFromKeyPool() : read failed"); + if (!HaveKey(keypool.vchPubKey.GetID())) + throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); + assert(keypool.vchPubKey.IsValid()); + printf("keypool reserve %"PRI64d"\n", nIndex); + } +} + +int64 CWallet::AddReserveKey(const CKeyPool& keypool) +{ + { + LOCK2(cs_main, cs_wallet); + CWalletDB walletdb(strWalletFile); + + int64 nIndex = 1 + *(--setKeyPool.end()); + if (!walletdb.WritePool(nIndex, keypool)) + throw runtime_error("AddReserveKey() : writing added key failed"); + setKeyPool.insert(nIndex); + return nIndex; + } + return -1; +} + +void CWallet::KeepKey(int64 nIndex) +{ + // Remove from key pool + if (fFileBacked) + { + CWalletDB walletdb(strWalletFile); + walletdb.ErasePool(nIndex); + } + printf("keypool keep %"PRI64d"\n", nIndex); +} + +void CWallet::ReturnKey(int64 nIndex) +{ + // Return to key pool + { + LOCK(cs_wallet); + setKeyPool.insert(nIndex); + } + printf("keypool return %"PRI64d"\n", nIndex); +} + +bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse) +{ + int64 nIndex = 0; + CKeyPool keypool; + { + LOCK(cs_wallet); + ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) + { + if (fAllowReuse && vchDefaultKey.IsValid()) + { + result = vchDefaultKey; + return true; + } + if (IsLocked()) return false; + result = GenerateNewKey(); + return true; + } + KeepKey(nIndex); + result = keypool.vchPubKey; + } + return true; +} + +int64 CWallet::GetOldestKeyPoolTime() +{ + int64 nIndex = 0; + CKeyPool keypool; + ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) + return GetTime(); + ReturnKey(nIndex); + return keypool.nTime; +} + +CPubKey CReserveKey::GetReservedKey() +{ + if (nIndex == -1) + { + CKeyPool keypool; + pwallet->ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex != -1) + vchPubKey = keypool.vchPubKey; + else + { + printf("CReserveKey::GetReservedKey(): Warning: using default key instead of a new key, top up your keypool."); + vchPubKey = pwallet->vchDefaultKey; + } + } + assert(vchPubKey.IsValid()); + return vchPubKey; +} + +void CReserveKey::KeepKey() +{ + if (nIndex != -1) + pwallet->KeepKey(nIndex); + nIndex = -1; + vchPubKey = CPubKey(); +} + +void CReserveKey::ReturnKey() +{ + if (nIndex != -1) + pwallet->ReturnKey(nIndex); + nIndex = -1; + vchPubKey = CPubKey(); +} + +void CWallet::GetAllReserveKeys(set& setAddress) +{ + setAddress.clear(); + + CWalletDB walletdb(strWalletFile); + + LOCK2(cs_main, cs_wallet); + BOOST_FOREACH(const int64& id, setKeyPool) + { + CKeyPool keypool; + if (!walletdb.ReadPool(id, keypool)) + throw runtime_error("GetAllReserveKeyHashes() : read failed"); + assert(keypool.vchPubKey.IsValid()); + CKeyID keyID = keypool.vchPubKey.GetID(); + if (!HaveKey(keyID)) + throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool"); + setAddress.insert(keyID); + } +} + +void CWallet::UpdatedTransaction(const uint256 &hashTx) +{ + { + LOCK(cs_wallet); + // Only notify UI if this transaction is in this wallet + map::const_iterator mi = mapWallet.find(hashTx); + if (mi != mapWallet.end()) + NotifyTransactionChanged(this, hashTx, CT_UPDATED); + } +} diff --git a/src/wallet.h b/src/wallet.h new file mode 100644 index 0000000..864ea5c --- /dev/null +++ b/src/wallet.h @@ -0,0 +1,741 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_WALLET_H +#define BITCOIN_WALLET_H + +#include "main.h" +#include "key.h" +#include "keystore.h" +#include "script.h" +#include "ui_interface.h" + +class CWalletTx; +class CReserveKey; +class CWalletDB; +class COutput; + +/** (client) version numbers for particular wallet features */ +enum WalletFeature +{ + FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output) + + FEATURE_WALLETCRYPT = 40000, // wallet encryption + FEATURE_COMPRPUBKEY = 60000, // compressed public keys + + FEATURE_LATEST = 60000 +}; + + +/** A key pool entry */ +class CKeyPool +{ +public: + int64 nTime; + CPubKey vchPubKey; + + CKeyPool() + { + nTime = GetTime(); + } + + CKeyPool(const CPubKey& vchPubKeyIn) + { + nTime = GetTime(); + vchPubKey = vchPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(nTime); + READWRITE(vchPubKey); + ) +}; + +/** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, + * and provides the ability to create new transactions. + */ +class CWallet : public CCryptoKeyStore +{ +private: + bool SelectCoins(int64 nTargetValue, std::set >& setCoinsRet, int64& nValueRet) const; + + CWalletDB *pwalletdbEncryption; + + // the current wallet version: clients below this version are not able to load the wallet + int nWalletVersion; + + // the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded + int nWalletMaxVersion; + +public: + mutable CCriticalSection cs_wallet; + + bool fFileBacked; + std::string strWalletFile; + + std::set setKeyPool; + + + typedef std::map MasterKeyMap; + MasterKeyMap mapMasterKeys; + unsigned int nMasterKeyMaxID; + + CWallet() + { + nWalletVersion = FEATURE_BASE; + nWalletMaxVersion = FEATURE_BASE; + fFileBacked = false; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; + } + CWallet(std::string strWalletFileIn) + { + nWalletVersion = FEATURE_BASE; + nWalletMaxVersion = FEATURE_BASE; + strWalletFile = strWalletFileIn; + fFileBacked = true; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; + } + + std::map mapWallet; + std::map mapRequestCount; + + std::map mapAddressBook; + + CPubKey vchDefaultKey; + + // check whether we are allowed to upgrade (or already support) to the named feature + bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; } + + void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true) const; + bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, int64& nValueRet) const; + + // keystore implementation + // Generate a new key + CPubKey GenerateNewKey(); + // Adds a key to the store, and saves it to disk. + bool AddKey(const CKey& key); + // Adds a key to the store, without saving it to disk (used by LoadWallet) + bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); } + + bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } + + // Adds an encrypted key to the store, and saves it to disk. + bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret); + // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) + bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } + bool AddCScript(const CScript& redeemScript); + bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); } + + bool Unlock(const SecureString& strWalletPassphrase); + bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); + bool EncryptWallet(const SecureString& strWalletPassphrase); + + void MarkDirty(); + bool AddToWallet(const CWalletTx& wtxIn); + bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false); + bool EraseFromWallet(uint256 hash); + void WalletUpdateSpent(const CTransaction& prevout); + int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); + int ScanForWalletTransaction(const uint256& hashTx); + void ReacceptWalletTransactions(); + void ResendWalletTransactions(); + int64 GetBalance() const; + int64 GetUnconfirmedBalance() const; + int64 GetImmatureBalance() const; + bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); + bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); + bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); + std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + + bool NewKeyPool(); + bool TopUpKeyPool(); + int64 AddReserveKey(const CKeyPool& keypool); + void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); + void KeepKey(int64 nIndex); + void ReturnKey(int64 nIndex); + bool GetKeyFromPool(CPubKey &key, bool fAllowReuse=true); + int64 GetOldestKeyPoolTime(); + void GetAllReserveKeys(std::set& setAddress); + + bool IsMine(const CTxIn& txin) const; + int64 GetDebit(const CTxIn& txin) const; + bool IsMine(const CTxOut& txout) const + { + return ::IsMine(*this, txout.scriptPubKey); + } + int64 GetCredit(const CTxOut& txout) const + { + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetCredit() : value out of range"); + return (IsMine(txout) ? txout.nValue : 0); + } + bool IsChange(const CTxOut& txout) const; + int64 GetChange(const CTxOut& txout) const + { + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetChange() : value out of range"); + return (IsChange(txout) ? txout.nValue : 0); + } + bool IsMine(const CTransaction& tx) const + { + BOOST_FOREACH(const CTxOut& txout, tx.vout) + // If output is less than minimum value, then don't include transaction. + // This is to help deal with dust spam bloating the wallet. + if (IsMine(txout) && txout.nValue >= nMinimumInputValue) + return true; + return false; + } + bool IsFromMe(const CTransaction& tx) const + { + return (GetDebit(tx) > 0); + } + int64 GetDebit(const CTransaction& tx) const + { + int64 nDebit = 0; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + nDebit += GetDebit(txin); + if (!MoneyRange(nDebit)) + throw std::runtime_error("CWallet::GetDebit() : value out of range"); + } + return nDebit; + } + int64 GetCredit(const CTransaction& tx) const + { + int64 nCredit = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nCredit += GetCredit(txout); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWallet::GetCredit() : value out of range"); + } + return nCredit; + } + int64 GetChange(const CTransaction& tx) const + { + int64 nChange = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nChange += GetChange(txout); + if (!MoneyRange(nChange)) + throw std::runtime_error("CWallet::GetChange() : value out of range"); + } + return nChange; + } + void SetBestChain(const CBlockLocator& loc); + + int LoadWallet(bool& fFirstRunRet); + + bool SetAddressBookName(const CTxDestination& address, const std::string& strName); + + bool DelAddressBookName(const CTxDestination& address); + + void UpdatedTransaction(const uint256 &hashTx); + + void PrintWallet(const CBlock& block); + + void Inventory(const uint256 &hash) + { + { + LOCK(cs_wallet); + std::map::iterator mi = mapRequestCount.find(hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } + } + + int GetKeyPoolSize() + { + return setKeyPool.size(); + } + + bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); + + bool SetDefaultKey(const CPubKey &vchPubKey); + + // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower + bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false); + + // change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format) + bool SetMaxVersion(int nVersion); + + // get the current wallet format (the oldest client version guaranteed to understand this wallet) + int GetVersion() { return nWalletVersion; } + + /** Address book entry changed. + * @note called with lock cs_wallet held. + */ + boost::signals2::signal NotifyAddressBookChanged; + + /** Wallet transaction added, removed or updated. + * @note called with lock cs_wallet held. + */ + boost::signals2::signal NotifyTransactionChanged; +}; + +/** A key allocated from the key pool. */ +class CReserveKey +{ +protected: + CWallet* pwallet; + int64 nIndex; + CPubKey vchPubKey; +public: + CReserveKey(CWallet* pwalletIn) + { + nIndex = -1; + pwallet = pwalletIn; + } + + ~CReserveKey() + { + if (!fShutdown) + ReturnKey(); + } + + void ReturnKey(); + CPubKey GetReservedKey(); + void KeepKey(); +}; + + +/** A transaction with a bunch of additional info that only the owner cares about. + * It includes any unrecorded transactions needed to link it back to the block chain. + */ +class CWalletTx : public CMerkleTx +{ +private: + const CWallet* pwallet; + +public: + std::vector vtxPrev; + std::map mapValue; + std::vector > vOrderForm; + unsigned int fTimeReceivedIsTxTime; + unsigned int nTimeReceived; // time received by this node + char fFromMe; + std::string strFromAccount; + std::vector vfSpent; // which outputs are already spent + + // memory only + mutable bool fDebitCached; + mutable bool fCreditCached; + mutable bool fAvailableCreditCached; + mutable bool fChangeCached; + mutable int64 nDebitCached; + mutable int64 nCreditCached; + mutable int64 nAvailableCreditCached; + mutable int64 nChangeCached; + + CWalletTx() + { + Init(NULL); + } + + CWalletTx(const CWallet* pwalletIn) + { + Init(pwalletIn); + } + + CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn) + { + Init(pwalletIn); + } + + CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn) + { + Init(pwalletIn); + } + + void Init(const CWallet* pwalletIn) + { + pwallet = pwalletIn; + vtxPrev.clear(); + mapValue.clear(); + vOrderForm.clear(); + fTimeReceivedIsTxTime = false; + nTimeReceived = 0; + fFromMe = false; + strFromAccount.clear(); + vfSpent.clear(); + fDebitCached = false; + fCreditCached = false; + fAvailableCreditCached = false; + fChangeCached = false; + nDebitCached = 0; + nCreditCached = 0; + nAvailableCreditCached = 0; + nChangeCached = 0; + } + + IMPLEMENT_SERIALIZE + ( + CWalletTx* pthis = const_cast(this); + if (fRead) + pthis->Init(NULL); + char fSpent = false; + + if (!fRead) + { + pthis->mapValue["fromaccount"] = pthis->strFromAccount; + + std::string str; + BOOST_FOREACH(char f, vfSpent) + { + str += (f ? '1' : '0'); + if (f) + fSpent = true; + } + pthis->mapValue["spent"] = str; + } + + nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action); + READWRITE(vtxPrev); + READWRITE(mapValue); + READWRITE(vOrderForm); + READWRITE(fTimeReceivedIsTxTime); + READWRITE(nTimeReceived); + READWRITE(fFromMe); + READWRITE(fSpent); + + if (fRead) + { + pthis->strFromAccount = pthis->mapValue["fromaccount"]; + + if (mapValue.count("spent")) + BOOST_FOREACH(char c, pthis->mapValue["spent"]) + pthis->vfSpent.push_back(c != '0'); + else + pthis->vfSpent.assign(vout.size(), fSpent); + } + + pthis->mapValue.erase("fromaccount"); + pthis->mapValue.erase("version"); + pthis->mapValue.erase("spent"); + ) + + // marks certain txout's as spent + // returns true if any update took place + bool UpdateSpent(const std::vector& vfNewSpent) + { + bool fReturn = false; + for (unsigned int i = 0; i < vfNewSpent.size(); i++) + { + if (i == vfSpent.size()) + break; + + if (vfNewSpent[i] && !vfSpent[i]) + { + vfSpent[i] = true; + fReturn = true; + fAvailableCreditCached = false; + } + } + return fReturn; + } + + // make sure balances are recalculated + void MarkDirty() + { + fCreditCached = false; + fAvailableCreditCached = false; + fDebitCached = false; + fChangeCached = false; + } + + void BindWallet(CWallet *pwalletIn) + { + pwallet = pwalletIn; + MarkDirty(); + } + + void MarkSpent(unsigned int nOut) + { + if (nOut >= vout.size()) + throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range"); + vfSpent.resize(vout.size()); + if (!vfSpent[nOut]) + { + vfSpent[nOut] = true; + fAvailableCreditCached = false; + } + } + + bool IsSpent(unsigned int nOut) const + { + if (nOut >= vout.size()) + throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range"); + if (nOut >= vfSpent.size()) + return false; + return (!!vfSpent[nOut]); + } + + int64 GetDebit() const + { + if (vin.empty()) + return 0; + if (fDebitCached) + return nDebitCached; + nDebitCached = pwallet->GetDebit(*this); + fDebitCached = true; + return nDebitCached; + } + + int64 GetCredit(bool fUseCache=true) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + + // GetBalance can assume transactions in mapWallet won't change + if (fUseCache && fCreditCached) + return nCreditCached; + nCreditCached = pwallet->GetCredit(*this); + fCreditCached = true; + return nCreditCached; + } + + int64 GetAvailableCredit(bool fUseCache=true) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + + if (fUseCache && fAvailableCreditCached) + return nAvailableCreditCached; + + int64 nCredit = 0; + for (unsigned int i = 0; i < vout.size(); i++) + { + if (!IsSpent(i)) + { + const CTxOut &txout = vout[i]; + nCredit += pwallet->GetCredit(txout); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + } + } + + nAvailableCreditCached = nCredit; + fAvailableCreditCached = true; + return nCredit; + } + + + int64 GetChange() const + { + if (fChangeCached) + return nChangeCached; + nChangeCached = pwallet->GetChange(*this); + fChangeCached = true; + return nChangeCached; + } + + void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list >& listReceived, + std::list >& listSent, int64& nFee, std::string& strSentAccount) const; + + void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, + int64& nSent, int64& nFee) const; + + bool IsFromMe() const + { + return (GetDebit() > 0); + } + + bool IsConfirmed() const + { + // Quick answer in most cases + if (!IsFinal()) + return false; + if (GetDepthInMainChain() >= 1) + return true; + if (!IsFromMe()) // using wtx's cached debit + return false; + + // If no confirmations but it's from us, we can still + // consider it confirmed if all dependencies are confirmed + std::map mapPrev; + std::vector vWorkQueue; + vWorkQueue.reserve(vtxPrev.size()+1); + vWorkQueue.push_back(this); + for (unsigned int i = 0; i < vWorkQueue.size(); i++) + { + const CMerkleTx* ptx = vWorkQueue[i]; + + if (!ptx->IsFinal()) + return false; + if (ptx->GetDepthInMainChain() >= 1) + continue; + if (!pwallet->IsFromMe(*ptx)) + return false; + + if (mapPrev.empty()) + { + BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) + mapPrev[tx.GetHash()] = &tx; + } + + BOOST_FOREACH(const CTxIn& txin, ptx->vin) + { + if (!mapPrev.count(txin.prevout.hash)) + return false; + vWorkQueue.push_back(mapPrev[txin.prevout.hash]); + } + } + return true; + } + + bool WriteToDisk(); + + int64 GetTxTime() const; + int GetRequestCount() const; + + void AddSupportingTransactions(CTxDB& txdb); + + bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptWalletTransaction(); + + void RelayWalletTransaction(CTxDB& txdb); + void RelayWalletTransaction(); +}; + + + + +class COutput +{ +public: + const CWalletTx *tx; + int i; + int nDepth; + + COutput(const CWalletTx *txIn, int iIn, int nDepthIn) + { + tx = txIn; i = iIn; nDepth = nDepthIn; + } + + std::string ToString() const + { + return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString().substr(0,10).c_str(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +/** Private key that includes an expiration date in case it never gets used. */ +class CWalletKey +{ +public: + CPrivKey vchPrivKey; + int64 nTimeCreated; + int64 nTimeExpires; + std::string strComment; + //// todo: add something to note what created it (user, getnewaddress, change) + //// maybe should have a map property map + + CWalletKey(int64 nExpires=0) + { + nTimeCreated = (nExpires ? GetTime() : 0); + nTimeExpires = nExpires; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPrivKey); + READWRITE(nTimeCreated); + READWRITE(nTimeExpires); + READWRITE(strComment); + ) +}; + + + + + + +/** Account information. + * Stored in wallet with key "acc"+string account name. + */ +class CAccount +{ +public: + CPubKey vchPubKey; + + CAccount() + { + SetNull(); + } + + void SetNull() + { + vchPubKey = CPubKey(); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPubKey); + ) +}; + + + +/** Internal transfers. + * Database key is acentry. + */ +class CAccountingEntry +{ +public: + std::string strAccount; + int64 nCreditDebit; + int64 nTime; + std::string strOtherAccount; + std::string strComment; + + CAccountingEntry() + { + SetNull(); + } + + void SetNull() + { + nCreditDebit = 0; + nTime = 0; + strAccount.clear(); + strOtherAccount.clear(); + strComment.clear(); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + // Note: strAccount is serialized as part of the key, not here. + READWRITE(nCreditDebit); + READWRITE(nTime); + READWRITE(strOtherAccount); + READWRITE(strComment); + ) +}; + +bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); + +#endif diff --git a/src/walletdb.cpp b/src/walletdb.cpp new file mode 100644 index 0000000..d2cb906 --- /dev/null +++ b/src/walletdb.cpp @@ -0,0 +1,426 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "walletdb.h" +#include "wallet.h" +#include + +using namespace std; +using namespace boost; + + +static uint64 nAccountingEntryNumber = 0; + +// +// CWalletDB +// + +bool CWalletDB::WriteName(const string& strAddress, const string& strName) +{ + nWalletDBUpdated++; + return Write(make_pair(string("name"), strAddress), strName); +} + +bool CWalletDB::EraseName(const string& strAddress) +{ + // This should only be used for sending addresses, never for receiving addresses, + // receiving addresses must always have an address book entry if they're not change return. + nWalletDBUpdated++; + return Erase(make_pair(string("name"), strAddress)); +} + +bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account) +{ + account.SetNull(); + return Read(make_pair(string("acc"), strAccount), account); +} + +bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account) +{ + return Write(make_pair(string("acc"), strAccount), account); +} + +bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) +{ + return Write(boost::make_tuple(string("acentry"), acentry.strAccount, ++nAccountingEntryNumber), acentry); +} + +int64 CWalletDB::GetAccountCreditDebit(const string& strAccount) +{ + list entries; + ListAccountCreditDebit(strAccount, entries); + + int64 nCreditDebit = 0; + BOOST_FOREACH (const CAccountingEntry& entry, entries) + nCreditDebit += entry.nCreditDebit; + + return nCreditDebit; +} + +void CWalletDB::ListAccountCreditDebit(const string& strAccount, list& entries) +{ + bool fAllAccounts = (strAccount == "*"); + + Dbc* pcursor = GetCursor(); + if (!pcursor) + throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor"); + unsigned int fFlags = DB_SET_RANGE; + loop + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + if (fFlags == DB_SET_RANGE) + ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64(0)); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + pcursor->close(); + throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB"); + } + + // Unserialize + string strType; + ssKey >> strType; + if (strType != "acentry") + break; + CAccountingEntry acentry; + ssKey >> acentry.strAccount; + if (!fAllAccounts && acentry.strAccount != strAccount) + break; + + ssValue >> acentry; + entries.push_back(acentry); + } + + pcursor->close(); +} + + +int CWalletDB::LoadWallet(CWallet* pwallet) +{ + pwallet->vchDefaultKey = CPubKey(); + int nFileVersion = 0; + vector vWalletUpgrade; + bool fIsEncrypted = false; + + //// todo: shouldn't we catch exceptions and try to recover and continue? + { + LOCK(pwallet->cs_wallet); + int nMinVersion = 0; + if (Read((string)"minversion", nMinVersion)) + { + if (nMinVersion > CLIENT_VERSION) + return DB_TOO_NEW; + pwallet->LoadMinVersion(nMinVersion); + } + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + { + printf("Error getting wallet database cursor\n"); + return DB_CORRUPT; + } + + loop + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + printf("Error reading next record from wallet database\n"); + return DB_CORRUPT; + } + + // Unserialize + // Taking advantage of the fact that pair serialization + // is just the two items serialized one after the other + string strType; + ssKey >> strType; + if (strType == "name") + { + string strAddress; + ssKey >> strAddress; + ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()]; + } + else if (strType == "tx") + { + uint256 hash; + ssKey >> hash; + CWalletTx& wtx = pwallet->mapWallet[hash]; + ssValue >> wtx; + wtx.BindWallet(pwallet); + + if (wtx.GetHash() != hash) + printf("Error in wallet.dat, hash mismatch\n"); + + // Undo serialize changes in 31600 + if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703) + { + if (!ssValue.empty()) + { + char fTmp; + char fUnused; + ssValue >> fTmp >> fUnused >> wtx.strFromAccount; + printf("LoadWallet() upgrading tx ver=%d %d '%s' %s\n", wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount.c_str(), hash.ToString().c_str()); + wtx.fTimeReceivedIsTxTime = fTmp; + } + else + { + printf("LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString().c_str()); + wtx.fTimeReceivedIsTxTime = 0; + } + vWalletUpgrade.push_back(hash); + } + + //// debug print + //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); + //printf(" %12"PRI64d" %s %s %s\n", + // wtx.vout[0].nValue, + // DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()).c_str(), + // wtx.hashBlock.ToString().substr(0,20).c_str(), + // wtx.mapValue["message"].c_str()); + } + else if (strType == "acentry") + { + string strAccount; + ssKey >> strAccount; + uint64 nNumber; + ssKey >> nNumber; + if (nNumber > nAccountingEntryNumber) + nAccountingEntryNumber = nNumber; + } + else if (strType == "key" || strType == "wkey") + { + vector vchPubKey; + ssKey >> vchPubKey; + CKey key; + if (strType == "key") + { + CPrivKey pkey; + ssValue >> pkey; + key.SetPubKey(vchPubKey); + key.SetPrivKey(pkey); + if (key.GetPubKey() != vchPubKey) + { + printf("Error reading wallet database: CPrivKey pubkey inconsistency\n"); + return DB_CORRUPT; + } + if (!key.IsValid()) + { + printf("Error reading wallet database: invalid CPrivKey\n"); + return DB_CORRUPT; + } + } + else + { + CWalletKey wkey; + ssValue >> wkey; + key.SetPubKey(vchPubKey); + key.SetPrivKey(wkey.vchPrivKey); + if (key.GetPubKey() != vchPubKey) + { + printf("Error reading wallet database: CWalletKey pubkey inconsistency\n"); + return DB_CORRUPT; + } + if (!key.IsValid()) + { + printf("Error reading wallet database: invalid CWalletKey\n"); + return DB_CORRUPT; + } + } + if (!pwallet->LoadKey(key)) + { + printf("Error reading wallet database: LoadKey failed\n"); + return DB_CORRUPT; + } + } + else if (strType == "mkey") + { + unsigned int nID; + ssKey >> nID; + CMasterKey kMasterKey; + ssValue >> kMasterKey; + if(pwallet->mapMasterKeys.count(nID) != 0) + { + printf("Error reading wallet database: duplicate CMasterKey id %u\n", nID); + return DB_CORRUPT; + } + pwallet->mapMasterKeys[nID] = kMasterKey; + if (pwallet->nMasterKeyMaxID < nID) + pwallet->nMasterKeyMaxID = nID; + } + else if (strType == "ckey") + { + vector vchPubKey; + ssKey >> vchPubKey; + vector vchPrivKey; + ssValue >> vchPrivKey; + if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey)) + { + printf("Error reading wallet database: LoadCryptedKey failed\n"); + return DB_CORRUPT; + } + fIsEncrypted = true; + } + else if (strType == "defaultkey") + { + ssValue >> pwallet->vchDefaultKey; + } + else if (strType == "pool") + { + int64 nIndex; + ssKey >> nIndex; + pwallet->setKeyPool.insert(nIndex); + } + else if (strType == "version") + { + ssValue >> nFileVersion; + if (nFileVersion == 10300) + nFileVersion = 300; + } + else if (strType == "cscript") + { + uint160 hash; + ssKey >> hash; + CScript script; + ssValue >> script; + if (!pwallet->LoadCScript(script)) + { + printf("Error reading wallet database: LoadCScript failed\n"); + return DB_CORRUPT; + } + } + } + pcursor->close(); + } + + BOOST_FOREACH(uint256 hash, vWalletUpgrade) + WriteTx(hash, pwallet->mapWallet[hash]); + + printf("nFileVersion = %d\n", nFileVersion); + + + // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc: + if (fIsEncrypted && (nFileVersion == 40000 || nFileVersion == 50000)) + return DB_NEED_REWRITE; + + if (nFileVersion < CLIENT_VERSION) // Update + WriteVersion(CLIENT_VERSION); + + return DB_LOAD_OK; +} + +void ThreadFlushWalletDB(void* parg) +{ + // Make this thread recognisable as the wallet flushing thread + RenameThread("bitcoin-wallet"); + + const string& strFile = ((const string*)parg)[0]; + static bool fOneThread; + if (fOneThread) + return; + fOneThread = true; + if (!GetBoolArg("-flushwallet", true)) + return; + + unsigned int nLastSeen = nWalletDBUpdated; + unsigned int nLastFlushed = nWalletDBUpdated; + int64 nLastWalletUpdate = GetTime(); + while (!fShutdown) + { + Sleep(500); + + if (nLastSeen != nWalletDBUpdated) + { + nLastSeen = nWalletDBUpdated; + nLastWalletUpdate = GetTime(); + } + + if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) + { + TRY_LOCK(bitdb.cs_db,lockDb); + if (lockDb) + { + // Don't do this if any databases are in use + int nRefCount = 0; + map::iterator mi = bitdb.mapFileUseCount.begin(); + while (mi != bitdb.mapFileUseCount.end()) + { + nRefCount += (*mi).second; + mi++; + } + + if (nRefCount == 0 && !fShutdown) + { + map::iterator mi = bitdb.mapFileUseCount.find(strFile); + if (mi != bitdb.mapFileUseCount.end()) + { + printf("Flushing wallet.dat\n"); + nLastFlushed = nWalletDBUpdated; + int64 nStart = GetTimeMillis(); + + // Flush wallet.dat so it's self contained + bitdb.CloseDb(strFile); + bitdb.CheckpointLSN(strFile); + + bitdb.mapFileUseCount.erase(mi++); + printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); + } + } + } + } + } +} + +bool BackupWallet(const CWallet& wallet, const string& strDest) +{ + if (!wallet.fFileBacked) + return false; + while (!fShutdown) + { + { + LOCK(bitdb.cs_db); + if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0) + { + // Flush log data to the dat file + bitdb.CloseDb(wallet.strWalletFile); + bitdb.CheckpointLSN(wallet.strWalletFile); + bitdb.mapFileUseCount.erase(wallet.strWalletFile); + + // Copy wallet.dat + filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; + filesystem::path pathDest(strDest); + if (filesystem::is_directory(pathDest)) + pathDest /= wallet.strWalletFile; + + try { +#if BOOST_VERSION >= 104000 + filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists); +#else + filesystem::copy_file(pathSrc, pathDest); +#endif + printf("copied wallet.dat to %s\n", pathDest.string().c_str()); + return true; + } catch(const filesystem::filesystem_error &e) { + printf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what()); + return false; + } + } + } + Sleep(100); + } + return false; +} diff --git a/src/walletdb.h b/src/walletdb.h new file mode 100644 index 0000000..296326b --- /dev/null +++ b/src/walletdb.h @@ -0,0 +1,182 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2011-2012 Litecoin Developers +// Copyright (c) 2013 CasinoCoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_WALLETDB_H +#define BITCOIN_WALLETDB_H + +#include "db.h" +#include "base58.h" + +class CKeyPool; +class CAccount; +class CAccountingEntry; + +/** Error statuses for the wallet database */ +enum DBErrors +{ + DB_LOAD_OK, + DB_CORRUPT, + DB_TOO_NEW, + DB_LOAD_FAIL, + DB_NEED_REWRITE +}; + +/** Access to the wallet database (wallet.dat) */ +class CWalletDB : public CDB +{ +public: + CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode) + { + } +private: + CWalletDB(const CWalletDB&); + void operator=(const CWalletDB&); +public: + bool ReadName(const std::string& strAddress, std::string& strName) + { + strName = ""; + return Read(std::make_pair(std::string("name"), strAddress), strName); + } + + bool WriteName(const std::string& strAddress, const std::string& strName); + + bool EraseName(const std::string& strAddress); + + bool ReadTx(uint256 hash, CWalletTx& wtx) + { + return Read(std::make_pair(std::string("tx"), hash), wtx); + } + + bool WriteTx(uint256 hash, const CWalletTx& wtx) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("tx"), hash), wtx); + } + + bool EraseTx(uint256 hash) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("tx"), hash)); + } + + bool ReadKey(const CPubKey& vchPubKey, CPrivKey& vchPrivKey) + { + vchPrivKey.clear(); + return Read(std::make_pair(std::string("key"), vchPubKey.Raw()), vchPrivKey); + } + + bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("key"), vchPubKey.Raw()), vchPrivKey, false); + } + + bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector& vchCryptedSecret, bool fEraseUnencryptedKey = true) + { + nWalletDBUpdated++; + if (!Write(std::make_pair(std::string("ckey"), vchPubKey.Raw()), vchCryptedSecret, false)) + return false; + if (fEraseUnencryptedKey) + { + Erase(std::make_pair(std::string("key"), vchPubKey.Raw())); + Erase(std::make_pair(std::string("wkey"), vchPubKey.Raw())); + } + return true; + } + + bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); + } + + // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013 + bool ReadCScript(const uint160 &hash, CScript& redeemScript) + { + redeemScript.clear(); + return Read(std::make_pair(std::string("cscript"), hash), redeemScript); + } + + bool WriteCScript(const uint160& hash, const CScript& redeemScript) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false); + } + + bool WriteBestBlock(const CBlockLocator& locator) + { + nWalletDBUpdated++; + return Write(std::string("bestblock"), locator); + } + + bool ReadBestBlock(CBlockLocator& locator) + { + return Read(std::string("bestblock"), locator); + } + + bool ReadDefaultKey(std::vector& vchPubKey) + { + vchPubKey.clear(); + return Read(std::string("defaultkey"), vchPubKey); + } + + bool WriteDefaultKey(const CPubKey& vchPubKey) + { + nWalletDBUpdated++; + return Write(std::string("defaultkey"), vchPubKey.Raw()); + } + + bool ReadPool(int64 nPool, CKeyPool& keypool) + { + return Read(std::make_pair(std::string("pool"), nPool), keypool); + } + + bool WritePool(int64 nPool, const CKeyPool& keypool) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("pool"), nPool), keypool); + } + + bool ErasePool(int64 nPool) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("pool"), nPool)); + } + + // Settings are no longer stored in wallet.dat; these are + // used only for backwards compatibility: + template + bool ReadSetting(const std::string& strKey, T& value) + { + return Read(std::make_pair(std::string("setting"), strKey), value); + } + template + bool WriteSetting(const std::string& strKey, const T& value) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("setting"), strKey), value); + } + bool EraseSetting(const std::string& strKey) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("setting"), strKey)); + } + + bool WriteMinVersion(int nVersion) + { + return Write(std::string("minversion"), nVersion); + } + + bool ReadAccount(const std::string& strAccount, CAccount& account); + bool WriteAccount(const std::string& strAccount, const CAccount& account); + bool WriteAccountingEntry(const CAccountingEntry& acentry); + int64 GetAccountCreditDebit(const std::string& strAccount); + void ListAccountCreditDebit(const std::string& strAccount, std::list& acentries); + + int LoadWallet(CWallet* pwallet); +}; + +#endif // BITCOIN_WALLETDB_H